From 79b9da22a1f4b26279940d285c1bc28ce4e99252 Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 4 Oct 2018 22:06:28 +0000 Subject: [PATCH] Security-58286.200.222.tar.gz --- .gitignore | 2 + Analytics/Clients/LocalKeychainAnalytics.h | 42 + Analytics/Clients/LocalKeychainAnalytics.m | 151 + Analytics/Clients/SOSAnalytics.m | 11 +- .../SFAnalytics+Signin.h | 23 +- Analytics/SFAnalytics.h | 2 + Analytics/SFAnalytics.m | 35 +- Analytics/SFAnalyticsActivityTracker.m | 25 +- Analytics/SFAnalyticsDefines.h | 2 + Analytics/SFAnalyticsSQLiteStore.m | 9 + Analytics/SQLite/SFSQLite.h | 2 - Analytics/SQLite/SFSQLite.m | 76 +- ...com.apple.private.alloy.keychainsync.plist | Bin 458 -> 0 bytes KVSKeychainSyncingProxy/CKDKVSProxy.m | 9 +- ...ple.security.cloudkeychainproxy3.osx.plist | 2 - KeychainCircle/KCAESGCMDuplexSession.m | 3 + KeychainCircle/KCSRPContext.m | 3 + KeychainCircle/PairingChannel.h | 1 + KeychainCircle/Tests/KCDerTest.m | 20 +- KeychainCircle/Tests/KCPairingTest.m | 9 +- .../KeychainSyncAccountNotification.m | 83 +- .../IDSPersistentState.m | 128 - KeychainSyncingOverIDSProxy/IDSProxy.h | 121 - KeychainSyncingOverIDSProxy/IDSProxy.m | 563 -- ...ychainSyncingOverIDSProxy+ReceiveMessage.m | 446 -- .../KeychainSyncingOverIDSProxy+SendMessage.m | 526 -- .../KeychainSyncingOverIDSProxy+Throttle.m | 414 -- .../KeychainSyncingOverIDSProxy-Info.plist | 34 - .../KeychainSyncingOverIDSProxy.8 | 9 - ...com.apple.private.alloy.keychainsync.plist | Bin 458 -> 0 bytes ...rity.keychainsyncingoveridsproxy.ios.plist | 53 - ...rity.keychainsyncingoveridsproxy.osx.plist | 43 - .../en.lproj/InfoPlist.strings | 2 - ...hainsyncingoveridsproxy.entitlements.plist | 32 - .../keychainsyncingoveridsproxy.m | 335 -- .../ClientInfoByNotification.m | 295 ++ .../DeviceSimulator-Entitlements.plist | 64 + .../DeviceSimulator/DeviceSimulator.h | 17 + .../DeviceSimulator/DeviceSimulator.m | 285 + .../DeviceSimulator/DeviceSimulatorMain.m | 489 ++ .../DeviceSimulator/DeviceSimulatorProtocol.h | 44 + .../DeviceSimulator/Info.plist | 33 + .../MultiDeviceSimulatorTests/Info.plist | 22 + .../MultiDeviceNetworking.h | 24 + .../MultiDeviceNetworking.m | 295 ++ .../MultiDeviceNetworkingProtocol.h | 26 + .../MultiDeviceSimulatorTests.m | 547 ++ OSX/Breadcrumb/SecBreadcrumb.c | 143 +- .../KNAppDelegate.m | 1 + OSX/Keychain/KDAppDelegate.m | 6 +- OSX/Keychain/KDSecCircle.m | 2 + OSX/authd/authdb.c | 130 +- OSX/authd/authdb.h | 8 +- OSX/authd/authitems.c | 135 +- OSX/authd/authitems.h | 3 - OSX/authd/authorization.plist | 61 +- OSX/authd/authtoken.c | 25 +- OSX/authd/authtoken.h | 3 - OSX/authd/com.apple.authd.sb | 3 + OSX/authd/engine.c | 286 +- OSX/authd/rule.c | 36 +- OSX/authd/rule.h | 11 +- OSX/authd/server.c | 2 +- OSX/authd/session.c | 5 + OSX/config/security_framework_macos.xcconfig | 4 +- ....dfr.prompts-BBBAA77A32-C4EBFEA440.strings | 11 +- .../en.lproj/authorization.prompts.strings | 10 +- OSX/lib/framework.sb | 4 + .../lib/opensshCoding.cpp | 8 +- OSX/libsecurity_apple_csp/lib/opensshWrap.cpp | 8 +- .../lib/tpPolicies.cpp | 183 +- OSX/libsecurity_asn1/lib/SecAsn1Types.h | 4 +- OSX/libsecurity_asn1/lib/X509Templates.h | 5 + OSX/libsecurity_asn1/lib/ocspTemplates.h | 5 + .../lib/AuthorizationPlugin.h | 6 +- .../lib/CSPsession.cpp | 13 +- .../lib/cssmcred.cpp | 20 +- OSX/libsecurity_cdsa_utilities/lib/cssmcred.h | 4 +- .../lib/objectacl.cpp | 6 +- .../lib/objectacl.h | 2 +- .../lib/osxverifier.cpp | 4 +- .../lib/osxverifier.h | 4 +- .../lib/cuCdsaUtils.cpp | 2 +- OSX/libsecurity_cms/lib/CMSDecoder.cpp | 43 +- OSX/libsecurity_cms/lib/CMSDecoder.h | 3 + OSX/libsecurity_cms/lib/CMSEncoder.cpp | 41 +- OSX/libsecurity_cms/lib/CMSEncoder.h | 11 +- OSX/libsecurity_cms/lib/CMSPrivate.h | 22 + .../libsecurity_cms.xcodeproj/project.pbxproj | 28 +- .../regressions/cms-hashagility-test.h | 1020 ---- .../regressions/cms-hashagility-test.m | 422 -- .../regressions/cms_regressions.h | 1 - OSX/libsecurity_codesigning/lib/CSCommon.h | 25 +- OSX/libsecurity_codesigning/lib/Code.cpp | 18 +- .../lib/CodeSigner.cpp | 1 + OSX/libsecurity_codesigning/lib/CodeSigner.h | 1 + .../lib/RequirementKeywords.h | 1 + .../lib/RequirementLexer.cpp | 31 +- .../lib/RequirementParser.cpp | 42 +- .../lib/RequirementParser.hpp | 4 +- .../lib/RequirementParserTokenTypes.hpp | 73 +- .../lib/RequirementParserTokenTypes.txt | 73 +- .../lib/SecAssessment.cpp | 57 +- .../lib/SecAssessment.h | 12 + OSX/libsecurity_codesigning/lib/SecCode.cpp | 1 + OSX/libsecurity_codesigning/lib/SecCodePriv.h | 1 + .../lib/SecCodeSigner.cpp | 1 + .../lib/SecCodeSigner.h | 1 + .../lib/SecRequirement.cpp | 17 +- .../lib/SecRequirementPriv.h | 2 + .../lib/SecStaticCode.cpp | 42 +- .../lib/SecStaticCodePriv.h | 7 + .../lib/StaticCode.cpp | 97 +- OSX/libsecurity_codesigning/lib/StaticCode.h | 8 +- .../lib/bundlediskrep.cpp | 157 +- .../lib/bundlediskrep.h | 13 + .../lib/codedirectory.cpp | 2 + .../lib/codedirectory.h | 1 + OSX/libsecurity_codesigning/lib/csprocess.cpp | 5 +- OSX/libsecurity_codesigning/lib/csprocess.h | 2 +- .../lib/diskimagerep.cpp | 10 + .../lib/diskimagerep.h | 3 +- OSX/libsecurity_codesigning/lib/diskrep.cpp | 4 +- OSX/libsecurity_codesigning/lib/diskrep.h | 14 +- OSX/libsecurity_codesigning/lib/machorep.h | 2 +- .../lib/notarization.cpp | 309 ++ .../lib/notarization.h | 51 + .../lib/piddiskrep.cpp | 13 +- OSX/libsecurity_codesigning/lib/piddiskrep.h | 2 + OSX/libsecurity_codesigning/lib/policydb.cpp | 27 + .../lib/policyengine.cpp | 65 +- OSX/libsecurity_codesigning/lib/reqdumper.cpp | 3 + OSX/libsecurity_codesigning/lib/reqinterp.cpp | 11 +- OSX/libsecurity_codesigning/lib/reqmaker.h | 2 +- OSX/libsecurity_codesigning/lib/requirement.h | 13 +- OSX/libsecurity_codesigning/lib/signer.cpp | 16 +- .../lib/signerutils.cpp | 38 +- OSX/libsecurity_codesigning/lib/signerutils.h | 8 + .../lib/singlediskrep.cpp | 6 + .../lib/singlediskrep.h | 4 +- OSX/libsecurity_codesigning/lib/xar++.cpp | 64 + OSX/libsecurity_codesigning/lib/xar++.h | 7 +- OSX/libsecurity_codesigning/lib/xpcengine.cpp | 48 +- OSX/libsecurity_codesigning/lib/xpcengine.h | 3 + .../requirements.grammar | 2 + OSX/libsecurity_cssm/lib/cssmaci.h | 2 +- OSX/libsecurity_cssm/lib/cssmapplePriv.h | 30 +- OSX/libsecurity_cssm/lib/cssmcli.h | 2 +- OSX/libsecurity_cssm/lib/cssmcspi.h | 2 +- OSX/libsecurity_cssm/lib/cssmdli.h | 2 +- OSX/libsecurity_cssm/lib/cssmkrapi.h | 12 +- OSX/libsecurity_cssm/lib/cssmkrspi.h | 2 +- OSX/libsecurity_cssm/lib/cssmspi.h | 6 +- OSX/libsecurity_cssm/lib/cssmtpi.h | 2 +- OSX/libsecurity_cssm/lib/cssmtype.h | 170 +- OSX/libsecurity_cssm/lib/emmspi.h | 4 +- OSX/libsecurity_cssm/lib/emmtype.h | 2 +- OSX/libsecurity_cssm/lib/generator.pl | 2 +- OSX/libsecurity_cssm/lib/x509defs.h | 46 +- OSX/libsecurity_keychain/lib/CCallbackMgr.cp | 19 +- OSX/libsecurity_keychain/lib/KeyItem.cpp | 1 + OSX/libsecurity_keychain/lib/KeyItem.h | 1 + OSX/libsecurity_keychain/lib/PolicyCursor.cpp | 49 +- OSX/libsecurity_keychain/lib/SecAccess.h | 4 +- OSX/libsecurity_keychain/lib/SecAccessPriv.h | 4 +- OSX/libsecurity_keychain/lib/SecBase.cpp | 1 + .../lib/SecCertificate.cpp | 20 +- .../lib/SecCertificateBundle.h | 4 +- OSX/libsecurity_keychain/lib/SecIdentity.cpp | 44 +- .../lib/SecImportExport.c | 21 +- .../lib/SecImportExportUtils.cpp | 1 + OSX/libsecurity_keychain/lib/SecItem.cpp | 97 +- .../lib/SecItemConstants.c | 337 +- OSX/libsecurity_keychain/lib/SecKey.cpp | 58 +- OSX/libsecurity_keychain/lib/SecKeychain.cpp | 8 +- OSX/libsecurity_keychain/lib/SecKeychain.h | 52 +- .../lib/SecKeychainItem.cpp | 2 +- .../lib/SecKeychainItem.h | 28 +- .../lib/SecKeychainItemExtendedAttributes.h | 8 +- .../lib/SecKeychainItemPriv.h | 30 +- .../lib/SecKeychainPriv.h | 23 +- OSX/libsecurity_keychain/lib/SecPassword.h | 6 +- OSX/libsecurity_keychain/lib/SecPolicy.cpp | 147 +- OSX/libsecurity_keychain/lib/SecRandom.c | 4 +- OSX/libsecurity_keychain/lib/SecTrust.cpp | 17 +- .../lib/SecTrustOSXEntryPoints.cpp | 2 +- .../lib/SecTrustSettings.cpp | 12 +- .../lib/SecTrustedApplication.h | 6 +- .../lib/SecTrustedApplicationPriv.h | 20 +- .../lib/StorageManager.cpp | 21 +- OSX/libsecurity_keychain/lib/TokenLogin.cpp | 176 +- OSX/libsecurity_keychain/lib/Trust.cpp | 4 +- .../lib/TrustAdditions.cpp | 1 - .../regressions/kc-15-key-update-valueref.c | 12 +- .../regressions/kc-18-find-combined.c | 28 +- .../regressions/kc-20-item-find-stress.c | 2 +- .../regressions/kc-28-p12-import.m | 132 + .../regressions/kc-40-seckey.m | 2 +- .../regressions/kc-41-sececkey.m | 50 +- .../regressions/kc-43-seckey-interop.m | 7 + .../regressions/kc-helpers.h | 223 +- .../regressions/kc-identity-helpers.h | 131 - .../regressions/kc-keychain-file-helpers.c | 2527 +++++++++ .../regressions/kc-keychain-file-helpers.h | 2312 +-------- .../xpc-tsa/timestampclient.h | 2 +- OSX/libsecurity_mds/lib/mds.h | 4 +- OSX/libsecurity_smime/lib/SecCMS.c | 20 +- OSX/libsecurity_smime/lib/SecCMS.h | 1 + OSX/libsecurity_smime/lib/SecCmsBase.h | 7 +- OSX/libsecurity_smime/lib/SecCmsContentInfo.h | 14 +- OSX/libsecurity_smime/lib/SecCmsDecoder.h | 4 +- .../lib/SecCmsDigestContext.h | 4 +- .../lib/SecCmsDigestedData.h | 2 +- OSX/libsecurity_smime/lib/SecCmsEncoder.h | 4 +- OSX/libsecurity_smime/lib/SecCmsMessage.h | 2 +- .../lib/SecCmsRecipientInfo.h | 2 +- OSX/libsecurity_smime/lib/SecCmsSignedData.h | 6 +- OSX/libsecurity_smime/lib/SecCmsSignerInfo.h | 26 +- OSX/libsecurity_smime/lib/cert.c | 21 +- OSX/libsecurity_smime/lib/cert.h | 2 + OSX/libsecurity_smime/lib/cmsattr.c | 1 + OSX/libsecurity_smime/lib/cmspriv.h | 2 +- OSX/libsecurity_smime/lib/cmspubkey.c | 22 +- OSX/libsecurity_smime/lib/cmssigdata.c | 19 +- OSX/libsecurity_smime/lib/cmssiginfo.c | 84 +- OSX/libsecurity_smime/lib/cmstpriv.h | 1 + OSX/libsecurity_smime/lib/secoid.c | 8 + OSX/libsecurity_smime/lib/smimeutil.c | 51 +- OSX/libsecurity_smime/lib/tsaSupport.c | 228 +- OSX/libsecurity_smime/lib/tsaSupport.h | 2 +- OSX/libsecurity_smime/lib/tsaSupportPriv.h | 3 +- .../project.pbxproj | 22 +- OSX/libsecurity_ssl/lib/SecureTransport.h | 12 + OSX/libsecurity_ssl/lib/SecureTransportPriv.h | 58 +- OSX/libsecurity_ssl/lib/sslBuildFlags.h | 1 - OSX/libsecurity_ssl/lib/sslCipherSpecs.c | 222 +- OSX/libsecurity_ssl/lib/sslContext.c | 14 +- OSX/libsecurity_ssl/lib/sslCrypto.c | 8 - .../SecureTransportTests/Info.plist | 22 + .../STLegacyTests+ciphers.m | 685 +++ .../STLegacyTests+clientauth.m | 407 ++ .../STLegacyTests+clientauth41.m | 375 ++ .../STLegacyTests+crashes.m | 310 ++ .../SecureTransportTests/STLegacyTests+dhe.m | 400 ++ .../STLegacyTests+falsestart.m | 330 ++ .../STLegacyTests+noconn.m | 38 + .../STLegacyTests+renegotiate.m | 465 ++ .../STLegacyTests+sessioncache.m | 415 ++ .../STLegacyTests+sessionstate.m | 492 ++ .../SecureTransportTests/STLegacyTests+sni.m | 267 + .../STLegacyTests+split.m | 339 ++ .../STLegacyTests+sslciphers.m | 450 ++ .../STLegacyTests+tls12.m | 333 ++ .../STLegacyTests-Entitlements.plist | 22 + .../SecureTransportTests/STLegacyTests.h | 20 + .../SecureTransportTests/STLegacyTests.m | 11 + .../SecureTransportTests.m | 15 + .../SecureTransport_iosTests.plist | 21 + .../SecureTransport_macosTests.plist | 21 + .../ssl-46-SSLGetSupportedCiphers.c | 12 - OSX/libsecurity_ssl/regressions/ssl-utils.c | 11 - .../test-certs/ClientECC.Cert.CA-ECC.der | Bin 357 -> 503 bytes .../test-certs/ClientECC.Cert.CA-ECC.pem | 60 +- .../test-certs/ClientECC.Cert.CA-RSA.der | Bin 551 -> 673 bytes .../test-certs/ClientECC.Cert.CA-RSA.pem | 77 +- .../test-certs/ClientECC_Cert_CA-ECC.h | 74 +- .../test-certs/ClientECC_Cert_CA-RSA.h | 105 +- .../test-certs/ClientRSA.Cert.CA-ECC.der | Bin 426 -> 706 bytes .../test-certs/ClientRSA.Cert.CA-ECC.pem | 77 +- .../test-certs/ClientRSA.Cert.CA-RSA.der | Bin 622 -> 876 bytes .../test-certs/ClientRSA.Cert.CA-RSA.pem | 94 +- .../regressions/test-certs/ClientRSA.Key.der | Bin 607 -> 1191 bytes .../regressions/test-certs/ClientRSA.Key.pem | 38 +- .../regressions/test-certs/ClientRSA.Req.pem | 23 +- .../test-certs/ClientRSA_Cert_CA-ECC.h | 97 +- .../test-certs/ClientRSA_Cert_CA-RSA.h | 127 +- .../regressions/test-certs/ClientRSA_Key.h | 153 +- .../test-certs/ServerECC.Cert.CA-ECC.der | Bin 355 -> 502 bytes .../test-certs/ServerECC.Cert.CA-ECC.pem | 60 +- .../test-certs/ServerECC.Cert.CA-RSA.der | Bin 550 -> 697 bytes .../test-certs/ServerECC.Cert.CA-RSA.pem | 79 +- .../test-certs/ServerECC_Cert_CA-ECC.h | 74 +- .../test-certs/ServerECC_Cert_CA-RSA.h | 107 +- .../test-certs/ServerRSA.Cert.CA-ECC.der | Bin 427 -> 706 bytes .../test-certs/ServerRSA.Cert.CA-ECC.pem | 77 +- .../test-certs/ServerRSA.Cert.CA-RSA.der | Bin 621 -> 900 bytes .../test-certs/ServerRSA.Cert.CA-RSA.pem | 96 +- .../regressions/test-certs/ServerRSA.Key.der | Bin 607 -> 1192 bytes .../regressions/test-certs/ServerRSA.Key.pem | 38 +- .../regressions/test-certs/ServerRSA.Req.pem | 23 +- .../test-certs/ServerRSA_Cert_CA-ECC.h | 97 +- .../test-certs/ServerRSA_Cert_CA-RSA.h | 129 +- .../regressions/test-certs/ServerRSA_Key.h | 153 +- ...trustedClientRSA.Cert.Untrusted-CA-RSA.der | Bin 633 -> 886 bytes ...trustedClientRSA.Cert.Untrusted-CA-RSA.pem | 95 +- .../test-certs/UntrustedClientRSA.Key.der | Bin 610 -> 1190 bytes .../test-certs/UntrustedClientRSA.Key.pem | 38 +- .../test-certs/UntrustedClientRSA.Req.pem | 23 +- ...UntrustedClientRSA_Cert_Untrusted-CA-RSA.h | 129 +- .../test-certs/UntrustedClientRSA_Key.h | 153 +- .../lib/CEncryptDecrypt.c | 40 +- .../lib/SecCustomTransform.cpp | 14 +- OSX/libsecurity_transform/lib/Transform.cpp | 63 +- .../lib/TransformFactory.cpp | 10 +- OSX/libsecurity_transform/lib/misc.h | 4 +- .../lib/debugging_internal.h | 7 +- OSX/libsecurity_utilities/lib/errors.cpp | 11 +- OSX/libsecurity_utilities/lib/mach++.cpp | 9 +- OSX/libsecurity_utilities/lib/mach++.h | 1 + OSX/libsecurity_utilities/lib/mach_notify.h | 21 +- OSX/libsecurity_utilities/lib/machserver.cpp | 18 +- OSX/libsecurity_utilities/lib/machserver.h | 20 +- OSX/libsecurity_utilities/lib/refcount.h | 3 - OSX/macos_tapi_hacks.h | 10 + .../CKBridge/SOSCloudKeychainClient.c | 255 +- .../CKBridge/SOSCloudKeychainClient.h | 13 +- .../CKBridge/SOSCloudKeychainConstants.c | 12 - .../CKBridge/SOSCloudKeychainConstants.h | 14 +- .../SOSCircle/SecureObjectSync/SOSAccount.h | 27 +- .../SOSCircle/SecureObjectSync/SOSAccount.m | 587 ++- .../SecureObjectSync/SOSAccountBackup.m | 38 +- .../SecureObjectSync/SOSAccountCircles.m | 1 - .../SecureObjectSync/SOSAccountCredentials.m | 6 +- .../SecureObjectSync/SOSAccountFullPeerInfo.m | 42 + .../SecureObjectSync/SOSAccountGhost.m | 1 + .../SecureObjectSync/SOSAccountPeers.m | 14 +- .../SecureObjectSync/SOSAccountPersistence.m | 17 - .../SecureObjectSync/SOSAccountPriv.h | 17 +- .../SecureObjectSync/SOSAccountRecovery.m | 14 +- .../SecureObjectSync/SOSAccountSync.m | 216 +- .../SecureObjectSync/SOSAccountTransaction.m | 98 +- .../SOSAccountTrustClassic+Circle.h | 8 +- .../SOSAccountTrustClassic+Circle.m | 467 +- .../SOSAccountTrustClassic+Expansion.h | 2 + .../SOSAccountTrustClassic+Expansion.m | 53 +- .../SOSAccountTrustClassic+Identity.m | 10 - .../SecureObjectSync/SOSAccountTrustClassic.h | 7 +- .../SecureObjectSync/SOSAccountTrustClassic.m | 154 +- .../SecureObjectSync/SOSAccountTrustOctagon.h | 11 - .../SecureObjectSync/SOSAccountTrustOctagon.m | 6 - .../SecureObjectSync/SOSAccountUpdate.m | 2 +- .../SecureObjectSync/SOSAccountViewSync.m | 4 +- .../SecureObjectSync/SOSAuthKitHelpers.h | 25 + .../SecureObjectSync/SOSAuthKitHelpers.m | 165 + .../SecureObjectSync/SOSBackupSliceKeyBag.m | 5 +- .../SOSCircle/SecureObjectSync/SOSCircle.c | 34 +- .../SOSCircle/SecureObjectSync/SOSCircle.h | 3 + .../SecureObjectSync/SOSCloudCircle.h | 75 +- .../SecureObjectSync/SOSCloudCircle.m | 410 +- .../SecureObjectSync/SOSCloudCircleInternal.h | 34 - .../SecureObjectSync/SOSControlServer.m | 5 - .../SecureObjectSync/SOSDigestVector.c | 7 +- .../SOSCircle/SecureObjectSync/SOSEngine.c | 13 +- .../SecureObjectSync/SOSEnsureBackup.m | 3 - .../SecureObjectSync/SOSExports.exp-in | 105 +- .../SecureObjectSync/SOSFullPeerInfo.h | 10 +- .../SecureObjectSync/SOSFullPeerInfo.m | 67 +- .../SOSCircle/SecureObjectSync/SOSInternal.h | 42 +- .../SOSCircle/SecureObjectSync/SOSInternal.m | 141 +- .../SOSCircle/SecureObjectSync/SOSKVSKeys.h | 1 - .../SOSCircle/SecureObjectSync/SOSKVSKeys.m | 6 - .../SOSCircle/SecureObjectSync/SOSPeerInfo.h | 29 +- .../SOSCircle/SecureObjectSync/SOSPeerInfo.m | 212 +- .../SecureObjectSync/SOSPeerInfoDER.m | 3 +- .../SecureObjectSync/SOSPeerInfoInternal.h | 4 + .../SecureObjectSync/SOSPeerInfoPriv.h | 3 + .../SOSPeerInfoSecurityProperties.h | 35 - .../SOSPeerInfoSecurityProperties.m | 140 - .../SecureObjectSync/SOSPeerInfoV2.h | 2 +- .../SecureObjectSync/SOSPeerInfoV2.m | 16 +- .../SOSCircle/SecureObjectSync/SOSPiggyback.m | 5 + .../SecureObjectSync/SOSSysdiagnose.m | 14 +- .../SOSCircle/SecureObjectSync/SOSTransport.m | 1 - .../SecureObjectSync/SOSTransportMessage.m | 1 - .../SecureObjectSync/SOSTransportMessageIDS.h | 48 - .../SecureObjectSync/SOSTransportMessageIDS.m | 392 -- .../SecureObjectSync/SOSTransportMessageKVS.m | 31 - OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h | 33 - OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h | 2 + OSX/sec/SOSCircle/SecureObjectSync/SOSViews.m | 67 + .../SOSCircle/SecureObjectSync/ViewList.list | 1 + .../SOSCircle/Tool/accountCirclesViewsPrint.m | 45 +- OSX/sec/SOSCircle/Tool/keychain_log.m | 11 +- OSX/sec/SOSCircle/Tool/keychain_sync.h | 15 +- OSX/sec/SOSCircle/Tool/keychain_sync.m | 334 +- .../Regressions/Security_regressions.h | 1 - .../Regressions/crypto/pbkdf2-00-hmac-sha1.c | 34 +- .../Regressions/crypto/spbkdf-00-hmac-sha1.c | 36 +- .../crypto/spbkdf-01-hmac-sha256.c | 37 +- .../Regressions/secitem/si-10-find-internet.c | 2 +- .../secitem/si-18-certificate-parse.m | 6 +- .../Regressions/secitem/si-20-sectrust.c | 150 +- .../Regressions/secitem/si-20-sectrust.h | 516 +- .../Regressions/secitem/si-22-sectrust-iap.c | 116 +- .../Regressions/secitem/si-22-sectrust-iap.h | 145 + .../Regressions/secitem/si-23-sectrust-ocsp.c | 1543 +----- .../Regressions/secitem/si-23-sectrust-ocsp.h | 1423 +++++ .../secitem/si-27-sectrust-exceptions.c | 6 +- .../secitem/si-28-sectrustsettings.m | 28 +- .../secitem/si-29-sectrust-sha1-deprecation.m | 2 +- .../Regressions/secitem/si-34-cms-timestamp.h | 916 ++++ .../Regressions/secitem/si-34-cms-timestamp.m | 223 + .../secitem/si-35-cms-expiration-time.h | 534 ++ .../secitem/si-35-cms-expiration-time.m | 328 ++ .../Regressions/secitem/si-50-secrandom.c | 6 +- .../Regressions/secitem/si-61-pkcs12.c | 2 +- .../Regressions/secitem/si-66-smime.c | 3 +- .../secitem/si-70-sectrust-unified.c | 340 +- .../Regressions/secitem/si-82-token-ag.c | 2 +- .../secitem/si-87-sectrust-name-constraints.h | 76 + .../secitem/si-87-sectrust-name-constraints.m | 31 +- .../secitem/si-89-cms-hash-agility.m | 251 +- ...h-agility.h => si-cms-hash-agility-data.c} | 268 +- .../secitem/si-cms-hash-agility-data.h | 36 + .../secitem/si-cms-signing-identity-p12.c | 234 + .../secitem/si-cms-signing-identity-p12.h | 12 + OSX/sec/Security/SecBackupKeybagEntry.m | 4 +- OSX/sec/Security/SecBase.c | 111 + OSX/sec/Security/SecCMS.c | 20 +- OSX/sec/Security/SecCMS.h | 1 + OSX/sec/Security/{SecCTKKey.c => SecCTKKey.m} | 71 +- OSX/sec/Security/SecCertificate.c | 67 +- OSX/sec/Security/SecCertificateInternal.h | 6 + OSX/sec/Security/SecCertificateRequest.c | 26 +- OSX/sec/Security/SecECKey.h | 22 - OSX/sec/Security/{SecECKey.c => SecECKey.m} | 43 +- OSX/sec/Security/SecEMCS.m | 12 +- OSX/sec/Security/SecExports.exp-in | 119 +- OSX/sec/Security/SecFramework.c | 76 +- OSX/sec/Security/SecFramework.h | 2 + OSX/sec/Security/SecFrameworkStrings.h | 16 +- OSX/sec/Security/SecItem.c | 123 +- OSX/sec/Security/SecItemConstants.c | 3 +- OSX/sec/Security/SecItemInternal.h | 4 +- OSX/sec/Security/SecKey.c | 126 +- .../{SecKeyAdaptors.c => SecKeyAdaptors.m} | 20 +- OSX/sec/Security/SecKeyInternal.h | 1 - OSX/sec/Security/SecKeyProxy.m | 355 ++ OSX/sec/Security/SecOTRDHKey.c | 47 +- OSX/sec/Security/SecOTRDHKey.h | 2 +- OSX/sec/Security/SecOTRPublicIdentity.c | 5 +- OSX/sec/Security/SecOTRSession.c | 6 +- OSX/sec/Security/SecPBKDF.c | 36 +- OSX/sec/Security/SecPBKDF.h | 54 +- OSX/sec/Security/SecPasswordGenerate.c | 20 +- OSX/sec/Security/SecPolicy.c | 138 +- OSX/sec/Security/SecPolicy.list | 4 + OSX/sec/Security/SecPolicyChecks.list | 8 +- OSX/sec/Security/SecPolicyLeafCallbacks.c | 10 +- OSX/sec/Security/SecSCEP.c | 22 +- OSX/sec/Security/SecServerEncryptionSupport.h | 2 +- OSX/sec/Security/SecTrust.c | 215 +- OSX/sec/Security/SecuritydXPC.c | 33 +- OSX/sec/Security/Tool/keychain_find.m | 237 +- OSX/sec/Security/ios_tapi_hacks.h | 4 + OSX/sec/Security/p12pbegen.c | 18 +- OSX/sec/SecurityTool/sos.m | 10 - OSX/sec/SharedWebCredential/swcagent.m | 14 +- OSX/sec/SharedWebCredential/swcagent_client.h | 3 - OSX/sec/ipc/client.c | 149 +- OSX/sec/ipc/com.apple.secd.plist | 2 + OSX/sec/ipc/com.apple.securityd.plist | 2 + OSX/sec/ipc/securityd_client.h | 51 +- OSX/sec/ipc/server.c | 202 +- OSX/sec/ipc/server_entitlement_helpers.c | 185 +- OSX/sec/ipc/server_entitlement_helpers.h | 4 - OSX/sec/ipc/server_security_helpers.c | 4 - OSX/sec/ipc/server_security_helpers.h | 1 + OSX/sec/ipc/server_xpc.m | 2 +- OSX/sec/securityd/OTATrustUtilities.h | 4 + OSX/sec/securityd/OTATrustUtilities.m | 330 +- .../securityd/Regressions/SOSAccountTesting.h | 36 +- .../Regressions/SOSTransportTestTransports.h | 25 - .../Regressions/SOSTransportTestTransports.m | 351 -- .../secd-02-upgrade-while-locked.m | 2 +- .../secd-155-otr-negotiation-monitor.m | 218 - .../Regressions/secd-20-keychain_upgrade.m | 2 +- .../securityd/Regressions/secd-200-logstate.m | 36 +- .../securityd/Regressions/secd-201-coders.m | 196 - .../Regressions/secd-21-transmogrify.m | 2 +- .../Regressions/secd-230-keybagtable.m | 2 +- .../secd-35-keychain-migrate-inet.m | 2 +- .../secd-37-pairing-initial-sync.m | 2 +- .../Regressions/secd-40-cc-gestalt.m | 2 +- .../Regressions/secd-55-account-circle.m | 15 +- .../secd-57-1-account-last-standing.m | 2 +- .../Regressions/secd-57-account-leave.m | 2 +- .../secd-63-account-resurrection.m | 4 +- .../secd-65-account-retirement-reset.m | 6 +- .../securityd/Regressions/secd-668-ghosts.m | 6 +- OSX/sec/securityd/Regressions/secd-700-sftm.m | 66 - .../Regressions/secd-82-secproperties-basic.m | 129 - .../securityd/Regressions/secd_regressions.h | 4 - OSX/sec/securityd/SFKeychainServer.h | 51 + OSX/sec/securityd/SFKeychainServer.m | 450 ++ OSX/sec/securityd/SOSCloudCircleServer.h | 26 +- OSX/sec/securityd/SOSCloudCircleServer.m | 505 +- OSX/sec/securityd/SecCAIssuerCache.c | 101 +- OSX/sec/securityd/SecCAIssuerCache.h | 7 +- OSX/sec/securityd/SecCAIssuerRequest.c | 274 - OSX/sec/securityd/SecCAIssuerRequest.h | 3 +- OSX/sec/securityd/SecCAIssuerRequest.m | 267 + OSX/sec/securityd/SecCertificateServer.c | 42 +- OSX/sec/securityd/SecCertificateServer.h | 8 + OSX/sec/securityd/SecCertificateSource.c | 33 +- OSX/sec/securityd/SecDbKeychainItem.m | 18 +- OSX/sec/securityd/SecDbKeychainItemV7.m | 46 +- OSX/sec/securityd/SecDbQuery.c | 3 +- OSX/sec/securityd/SecItemDb.c | 12 +- OSX/sec/securityd/SecItemSchema.c | 152 +- OSX/sec/securityd/SecItemServer.c | 200 +- OSX/sec/securityd/SecItemServer.h | 4 - OSX/sec/securityd/SecOCSPCache.c | 26 +- OSX/sec/securityd/SecOCSPRequest.c | 6 +- OSX/sec/securityd/SecOCSPResponse.c | 19 +- OSX/sec/securityd/SecOCSPResponse.h | 8 +- OSX/sec/securityd/SecPinningDb.m | 171 +- OSX/sec/securityd/SecPolicyServer.c | 197 +- OSX/sec/securityd/SecRevocationDb.c | 1899 ++++--- OSX/sec/securityd/SecRevocationDb.h | 34 +- OSX/sec/securityd/SecRevocationNetworking.h | 7 + OSX/sec/securityd/SecRevocationNetworking.m | 227 +- OSX/sec/securityd/SecRevocationServer.c | 400 +- OSX/sec/securityd/SecRevocationServer.h | 39 +- OSX/sec/securityd/SecTrustServer.c | 74 +- OSX/sec/securityd/SecTrustServer.h | 22 +- OSX/sec/securityd/SecTrustStoreServer.c | 46 +- OSX/sec/securityd/TrustURLSessionDelegate.h | 51 + OSX/sec/securityd/TrustURLSessionDelegate.m | 211 + OSX/sec/securityd/asynchttp.c | 469 -- OSX/sec/securityd/asynchttp.h | 71 - OSX/sec/securityd/com.apple.secd.sb | 4 +- OSX/sec/securityd/entitlements.plist | 6 + OSX/sec/securityd/nameconstraints.c | 52 +- OSX/sec/securityd/policytree.c | 6 +- OSX/sec/securityd/spi.c | 18 +- OSX/shared_regressions/shared_regressions.h | 4 + .../DODInteroperabilityRootCA2.cer | Bin 1778 -> 0 bytes .../ECARootCA4.cer | Bin 1407 -> 0 bytes .../FederalBridgeCA2013.cer | Bin 1641 -> 0 bytes .../PinningPolicyTrustTest.plist | 121 +- .../asset_receipt.cer | Bin 0 -> 1235 bytes .../baa_scrt_leaf.cer | Bin 0 -> 742 bytes .../baa_system_root.cer | Bin 0 -> 548 bytes .../baa_system_subca1.cer | Bin 0 -> 554 bytes .../si-20-sectrust-policies-data/gsa.cer | Bin 1030 -> 1215 bytes OSX/shared_regressions/si-44-seckey-aks.m | 87 +- OSX/shared_regressions/si-44-seckey-fv.m | 4 +- OSX/shared_regressions/si-44-seckey-proxy.m | 495 ++ .../{CA_alpha.crt => CA_alpha.cer} | Bin .../{CA_beta.crt => CA_beta.cer} | Bin ..._ca.crt => digicert_sha2_ev_server_ca.cer} | Bin .../{pilot_3055998.crt => pilot_3055998.cer} | Bin ...98_issuer.crt => pilot_3055998_issuer.cer} | Bin .../{serverA.crt => serverA.cer} | Bin .../{serverD.crt => serverD.cer} | Bin .../{serverF.crt => serverF.cer} | Bin .../{server_1601.crt => server_1601.cer} | Bin .../{server_1603.crt => server_1603.cer} | Bin .../{server_1604.crt => server_1604.cer} | Bin .../{server_1701.crt => server_1701.cer} | Bin .../{server_1704.crt => server_1704.cer} | Bin .../{server_1705.crt => server_1705.cer} | Bin .../{server_1801.crt => server_1801.cer} | Bin .../{server_1804.crt => server_1804.cer} | Bin .../{server_1805.crt => server_1805.cer} | Bin .../{server_2001.crt => server_2001.cer} | Bin ...st_00008013.crt => whitelist_00008013.cer} | Bin ...suer.crt => whitelist_00008013_issuer.cer} | Bin ...st_5555bc4f.crt => whitelist_5555bc4f.cer} | Bin ...suer.crt => whitelist_5555bc4f_issuer.cer} | Bin ...st_aaaae152.crt => whitelist_aaaae152.cer} | Bin ...st_fff9b5f6.crt => whitelist_fff9b5f6.cer} | Bin ...suer.crt => whitelist_fff9b5f6_issuer.cer} | Bin ...com_2015.crt => www_digicert_com_2015.cer} | Bin ...com_2016.crt => www_digicert_com_2016.cer} | Bin ...{www_paypal_com.crt => www_paypal_com.cer} | Bin ...m_issuer.crt => www_paypal_com_issuer.cer} | Bin OSX/shared_regressions/si-82-sectrust-ct.m | 77 +- OSX/shared_regressions/si-88-sectrust-valid.m | 114 +- OSX/trustd/iOS/entitlements.plist | 2 - OSX/trustd/trustd.c | 54 +- OSX/utilities/Regressions/su-40-secdb.c | 2 +- .../Regressions/su-41-secdb-stress.c | 4 +- OSX/utilities/src/SecAKSWrappers.h | 2 +- OSX/utilities/src/SecAutorelease.h | 30 + OSX/utilities/src/SecAutorelease.m | 33 + OSX/utilities/src/SecCFWrappers.c | 34 +- OSX/utilities/src/SecCFWrappers.h | 55 +- OSX/utilities/src/SecDb.c | 252 +- OSX/utilities/src/SecDb.h | 9 +- OSX/utilities/src/SecPLWrappers.m | 8 +- RegressionTests/Security.plist | 92 +- RegressionTests/SecurityInduceLowDisk.plist | 44 + .../secitemcanarytest.entitlements | 10 + .../secitemcanarytest/secitemcanarytest.m | 238 + SOSCCAuthPlugin/SOSCCAuthPlugin.m | 80 +- Security.exp-in | 28 +- Security.xcodeproj/project.pbxproj | 4561 +++++++++++++---- ...B3656633-AB83-4153-B404-DE14DBDC5ED6.plist | 52 + .../Info.plist | 33 + .../xcshareddata/xcschemes/CKKSTests.xcscheme | 2 +- .../xcschemes/TrustedPeers.xcscheme | 8 +- .../xcschemes/ios - Debug.xcscheme | 16 +- .../xcschemes/ios - Release.xcscheme | 12 +- .../xcschemes/ios - secdtests.xcscheme | 2 +- .../xcschemes/osx - World.xcscheme | 46 +- .../xcschemes/osx - secdtests.xcscheme | 10 +- .../xcschemes/osx - sectests.xcscheme | 4 +- .../si-88-sectrust-valid-data/ca-ki.pem | 26 + .../si-88-sectrust-valid-data/ca-unknown.pem | 23 + .../si-88-sectrust-valid-data/leaf-ki-ok1.pem | 27 + .../leaf-ki-revoked1.pem | 28 + .../leaf-unknown.pem | 22 + SecurityTool/authz.c | 33 +- SecurityTool/keychain_find.c | 8 + SecurityTool/srCdsaUtils.cpp | 2 +- SecurityTool/srCdsaUtils.h | 8 +- base/SecBase.h | 59 +- base/SecBasePriv.h | 12 +- base/SecRandom.h | 20 +- base/Security.apinotes | 8 + base/Security.h | 5 +- cssm/cssmapple.h | 4 +- header_symlinks/Security/OTConstants.h | 1 + header_symlinks/Security/SFSignInAnalytics.h | 1 + header_symlinks/Security/SecKeyProxy.h | 1 + header_symlinks/Security/SecProtocol.h | 1 + .../Security/SecProtocolMetadata.h | 1 + header_symlinks/Security/SecProtocolObject.h | 1 + header_symlinks/Security/SecProtocolOptions.h | 1 + header_symlinks/Security/SecProtocolTypes.h | 1 + .../Security/SecSharedCredential.h | 1 + .../macOS/Security/SecSharedCredential.h | 1 - .../KeychainModel.xcdatamodel/contents | 39 + keychain/CoreDataKeychain/SecCDKeychain.h | 174 + keychain/CoreDataKeychain/SecCDKeychain.m | 1495 ++++++ keychain/KeychainDataclassOwner/Info.plist | 24 + .../KeychainDataclassOwner.h | 17 +- .../KeychainDataclassOwner.m | 117 + keychain/KeychainResources/Info.plist | 22 + keychain/SecItem.h | 2 +- keychain/SecItemPriv.h | 14 +- keychain/SecKeyPriv.h | 138 +- keychain/SecKeyProxy.h | 63 + keychain/SecSharedCredential.h | 12 +- .../Resources/SFTMTests-Info.plist | 22 + .../SFSignInAnalytics+Internal.h | 26 +- keychain/Signin Metrics/SFSignInAnalytics.h | 87 + keychain/Signin Metrics/SFSignInAnalytics.m | 455 ++ keychain/Signin Metrics/SFTransactionMetric.h | 68 - keychain/Signin Metrics/SFTransactionMetric.m | 127 - .../tests/SFSignInAnalyticsTests.m | 514 ++ keychain/analytics/CKKSPowerCollection.h | 2 + keychain/analytics/CKKSPowerCollection.m | 8 + ...DKeychainCKKSRateLimiterAggregatedScores.h | 50 - ...DKeychainCKKSRateLimiterAggregatedScores.m | 264 - .../awd/AWDKeychainCKKSRateLimiterOverload.h | 47 - .../awd/AWDKeychainCKKSRateLimiterOverload.m | 227 - .../AWDKeychainCKKSRateLimiterTopWriters.h | 50 - .../AWDKeychainCKKSRateLimiterTopWriters.m | 244 - .../awd/AWDKeychainSOSKeychainBackupFailed.h | 38 - .../awd/AWDKeychainSOSKeychainBackupFailed.m | 142 - .../awd/AWDKeychainSecDbMarkedCorrupt.h | 48 - .../awd/AWDKeychainSecDbMarkedCorrupt.m | 242 - .../analytics/awd/AWDMetricIds_Keychain.h | 38 - .../awd/AwdMetadata-0x60-Keychain.bin | Bin 1067 -> 0 bytes .../categories/NSError+UsefulConstructors.h | 40 + .../categories/NSError+UsefulConstructors.m | 43 + keychain/ckks/CKKS.h | 6 +- keychain/ckks/CKKS.m | 3 +- keychain/ckks/CKKSAPSReceiver.h | 8 + keychain/ckks/CKKSAPSReceiver.m | 36 + keychain/ckks/CKKSAnalytics.m | 16 +- keychain/ckks/CKKSCKAccountStateTracker.h | 10 +- keychain/ckks/CKKSCKAccountStateTracker.m | 70 +- keychain/ckks/CKKSControl.h | 3 +- keychain/ckks/CKKSControl.m | 11 +- keychain/ckks/CKKSControlProtocol.h | 8 +- keychain/ckks/CKKSControlProtocol.m | 1 + .../CKKSFetchAllRecordZoneChangesOperation.h | 63 +- .../CKKSFetchAllRecordZoneChangesOperation.m | 506 +- keychain/ckks/CKKSFixups.m | 1 + keychain/ckks/CKKSHealKeyHierarchyOperation.m | 10 +- keychain/ckks/CKKSHealTLKSharesOperation.m | 9 +- keychain/ckks/CKKSIncomingQueueOperation.m | 230 +- keychain/ckks/CKKSItem.m | 2 +- keychain/ckks/CKKSKey.m | 2 +- keychain/ckks/CKKSKeychainView.h | 10 +- keychain/ckks/CKKSKeychainView.m | 301 +- keychain/ckks/CKKSLocalSynchronizeOperation.m | 1 + keychain/ckks/CKKSManifest.m | 2 +- keychain/ckks/CKKSMirrorEntry.m | 2 +- keychain/ckks/CKKSNearFutureScheduler.h | 2 + keychain/ckks/CKKSNearFutureScheduler.m | 8 + keychain/ckks/CKKSNewTLKOperation.m | 7 +- keychain/ckks/CKKSOutgoingQueueEntry.m | 1 + keychain/ckks/CKKSOutgoingQueueOperation.m | 34 +- .../ckks/CKKSProcessReceivedKeysOperation.m | 1 + keychain/ckks/CKKSRateLimiter.m | 54 - keychain/ckks/CKKSReachabilityTracker.h | 4 +- keychain/ckks/CKKSReachabilityTracker.m | 23 +- .../CKKSReencryptOutgoingItemsOperation.m | 1 + keychain/ckks/CKKSResultOperation.m | 2 +- keychain/ckks/CKKSSIV.m | 10 +- keychain/ckks/CKKSScanLocalItemsOperation.m | 4 +- keychain/ckks/CKKSSynchronizeOperation.m | 21 +- keychain/ckks/CKKSTLKShare.m | 1 + .../CKKSUpdateCurrentItemPointerOperation.m | 6 +- keychain/ckks/CKKSViewManager.h | 2 + keychain/ckks/CKKSViewManager.m | 30 +- keychain/ckks/CKKSZone.m | 22 +- keychain/ckks/CKKSZoneChangeFetcher.h | 38 +- keychain/ckks/CKKSZoneChangeFetcher.m | 192 +- keychain/ckks/CKKSZoneStateEntry.m | 2 +- keychain/ckks/CloudKitCategories.h | 10 - keychain/ckks/CloudKitCategories.m | 14 - keychain/ckks/CloudKitDependencies.h | 13 +- keychain/ckks/RateLimiter.h | 3 - keychain/ckks/RateLimiter.m | 66 - keychain/ckks/tests/CKKSAPSHandlingTests.m | 236 + .../ckks/tests/CKKSAPSReceiverTests.h | 22 +- keychain/ckks/tests/CKKSAPSReceiverTests.m | 18 +- keychain/ckks/tests/CKKSCloudKitTests.m | 15 +- .../ckks/tests/CKKSDeviceStateUploadTests.m | 42 +- keychain/ckks/tests/CKKSLoggerTests.m | 6 +- keychain/ckks/tests/CKKSManifestTests.m | 6 +- .../ckks/tests/CKKSNearFutureSchedulerTests.m | 27 + keychain/ckks/tests/CKKSSOSTests.m | 123 +- .../tests/CKKSServerValidationRecoveryTests.m | 28 +- keychain/ckks/tests/CKKSTLKSharingTests.m | 167 +- keychain/ckks/tests/CKKSTests+API.m | 176 +- keychain/ckks/tests/CKKSTests+Coalesce.m | 10 +- .../ckks/tests/CKKSTests+CurrentPointerAPI.m | 43 +- keychain/ckks/tests/CKKSTests.m | 533 +- .../tests/CloudKitKeychainSyncingFixupTests.m | 32 +- .../tests/CloudKitKeychainSyncingMockXCTest.h | 1 + .../tests/CloudKitKeychainSyncingMockXCTest.m | 38 +- .../tests/CloudKitKeychainSyncingTestsBase.m | 3 +- keychain/ckks/tests/CloudKitMockXCTest.h | 13 +- keychain/ckks/tests/CloudKitMockXCTest.m | 245 +- keychain/ckks/tests/MockCloudKit.h | 29 +- keychain/ckks/tests/MockCloudKit.m | 127 +- keychain/ckksctl/ckksctl.m | 4 +- keychain/ot/OTCloudStore.m | 22 +- keychain/ot/OTCloudStoreState.m | 2 +- keychain/ot/OTContext.h | 1 - keychain/ot/OTContext.m | 27 - keychain/ot/OTControl.m | 4 + keychain/ot/OTControlProtocol.h | 3 + keychain/ot/OTControlProtocol.m | 1 + keychain/ot/OTManager.m | 31 +- keychain/ot/OTRamping.h | 6 +- keychain/ot/OTRamping.m | 10 +- .../ot/tests/OTLockStateNetworkingTests.m | 6 +- keychain/ot/tests/OTRampingTests.m | 6 +- keychain/ot/tests/OTTestsBase.m | 2 +- keychain/otctl/otctl.m | 22 +- libsecurity_smime/lib/CMSDecoder.c | 39 + libsecurity_smime/lib/CMSDecoder.h | 22 +- libsecurity_smime/lib/CMSEncoder.c | 41 +- libsecurity_smime/lib/CMSEncoder.h | 16 +- libsecurity_smime/lib/SecCmsBase.h | 15 +- libsecurity_smime/lib/SecCmsSignerInfo.h | 20 + libsecurity_smime/lib/cert.c | 3 +- libsecurity_smime/lib/cmsattr.c | 1 + libsecurity_smime/lib/cmsenvdata.c | 7 +- libsecurity_smime/lib/cmspubkey.c | 13 +- libsecurity_smime/lib/cmssiginfo.c | 86 +- libsecurity_smime/lib/cmstpriv.h | 1 + libsecurity_smime/lib/crypto-embedded.c | 22 +- libsecurity_smime/lib/secoid.c | 8 + .../libCMS.xcodeproj/project.pbxproj | 22 +- ntlm/ntlmBlobPriv.c | 2 +- protocol/SecProtocol.c | 981 ++++ protocol/SecProtocol.h | 32 + protocol/SecProtocolMetadata.h | 323 ++ protocol/SecProtocolObject.h | 71 + protocol/SecProtocolOptions.h | 495 ++ protocol/SecProtocolPriv.h | 342 ++ protocol/SecProtocolTypes.h | 172 + protocol/SecProtocolTypes.m | 417 ++ resources/English.lproj/Certificate.strings | Bin 25772 -> 26038 bytes .../SharedWebCredentials.strings | Bin 5020 -> 5182 bytes resources/English.lproj/Trust.strings | Bin 15832 -> 16128 bytes secdxctests/CDKeychainTests.m | 535 ++ secdxctests/KeychainCryptoTests.m | 145 +- secdxctests/KeychainEntitlementsTest.m | 139 + secdxctests/KeychainXCTest.h | 15 +- secdxctests/KeychainXCTest.m | 130 +- secdxctests/SFCredentialStoreTests.m | 319 ++ sectask/SecTask.c | 5 +- sectask/SecTask.h | 2 - security-sysdiagnose/security-sysdiagnose.m | 43 +- .../KeyStore/KeyStoreEvents.c | 2 +- .../project.pbxproj | 22 +- .../securityd_service/main.c | 179 +- .../securityd_service/securityd_service.8 | 2 +- .../securityd_service_client.h | 1 + securityd/src/SharedMemoryServer.cpp | 13 - securityd/src/acl_keychain.cpp | 5 + securityd/src/acls.cpp | 3 + securityd/src/agentquery.cpp | 19 +- securityd/src/auditevents.cpp | 2 +- securityd/src/clientid.cpp | 8 +- securityd/src/connection.cpp | 16 +- securityd/src/csproxy.cpp | 35 +- securityd/src/database.cpp | 4 + securityd/src/database.h | 1 + securityd/src/dbcrypto.cpp | 6 +- securityd/src/kcdatabase.cpp | 107 +- securityd/src/kckey.cpp | 6 + securityd/src/main.cpp | 6 +- securityd/src/notifications.cpp | 6 +- securityd/src/notifications.h | 2 + securityd/src/process.cpp | 14 +- securityd/src/process.h | 5 +- securityd/src/server.cpp | 40 +- securityd/src/session.cpp | 8 +- securityd/src/structure.cpp | 18 +- securityd/src/structure.h | 2 - securityd/src/transition.cpp | 14 +- sslViewer/ecc-secp256r1-client.pfx | Bin 1036 -> 0 bytes sslViewer/sslAppUtils.h | 6 +- supd/Tests/SFAnalyticsTests.m | 24 +- supd/Tests/SupdTests.m | 102 +- supd/supd.h | 6 +- supd/supd.m | 63 +- supdctl/main.m | 7 +- tests/secdmockaks/mockaks.h | 5 + tests/secdmockaks/mockaks.m | 40 +- tests/secdmockaks/secdmockaks.m | 102 +- trust/SecCertificate.h | 22 +- trust/SecCertificatePriv.h | 17 +- trust/SecCertificateRequest.h | 4 +- trust/SecPolicyPriv.h | 94 +- trust/SecTrust.h | 29 +- trust/SecTrustPriv.h | 34 +- xcconfig/PlatformLibraries.xcconfig | 4 - xcconfig/Security.xcconfig | 8 +- xcscripts/install-test-framework.sh | 22 + 841 files changed, 45343 insertions(+), 23825 deletions(-) create mode 100644 Analytics/Clients/LocalKeychainAnalytics.h create mode 100644 Analytics/Clients/LocalKeychainAnalytics.m rename KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+Throttle.h => Analytics/SFAnalytics+Signin.h (61%) delete mode 100644 IDSKeychainSyncingProxy/com.apple.private.alloy.keychainsync.plist delete mode 100644 KeychainSyncingOverIDSProxy/IDSPersistentState.m delete mode 100644 KeychainSyncingOverIDSProxy/IDSProxy.h delete mode 100644 KeychainSyncingOverIDSProxy/IDSProxy.m delete mode 100644 KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m delete mode 100644 KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m delete mode 100644 KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+Throttle.m delete mode 100644 KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist delete mode 100644 KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy.8 delete mode 100644 KeychainSyncingOverIDSProxy/com.apple.private.alloy.keychainsync.plist delete mode 100644 KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.ios.plist delete mode 100644 KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.osx.plist delete mode 100644 KeychainSyncingOverIDSProxy/en.lproj/InfoPlist.strings delete mode 100644 KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist delete mode 100644 KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m create mode 100644 MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m create mode 100644 MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist create mode 100644 MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.h create mode 100644 MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.m create mode 100644 MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorMain.m create mode 100644 MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorProtocol.h create mode 100644 MultiDeviceSimulator/DeviceSimulator/Info.plist create mode 100644 MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist create mode 100644 MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.h create mode 100644 MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.m create mode 100644 MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworkingProtocol.h create mode 100644 MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceSimulatorTests.m delete mode 100644 OSX/libsecurity_cms/regressions/cms-hashagility-test.h delete mode 100644 OSX/libsecurity_cms/regressions/cms-hashagility-test.m create mode 100644 OSX/libsecurity_codesigning/lib/notarization.cpp create mode 100644 OSX/libsecurity_codesigning/lib/notarization.h create mode 100644 OSX/libsecurity_keychain/regressions/kc-keychain-file-helpers.c create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/Info.plist create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+ciphers.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth41.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+crashes.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+dhe.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+falsestart.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+noconn.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+renegotiate.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessioncache.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessionstate.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sni.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+split.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sslciphers.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+tls12.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests-Entitlements.plist create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests.h create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransportTests.m create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransport_iosTests.plist create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransport_macosTests.plist delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustOctagon.h delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustOctagon.m create mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.h create mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.m delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoSecurityProperties.h delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoSecurityProperties.m delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.h delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.m create mode 100644 OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.h create mode 100644 OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.h create mode 100644 OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.m create mode 100644 OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.h create mode 100644 OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.m rename OSX/sec/Security/Regressions/secitem/{si-89-cms-hash-agility.h => si-cms-hash-agility-data.c} (71%) create mode 100644 OSX/sec/Security/Regressions/secitem/si-cms-hash-agility-data.h create mode 100644 OSX/sec/Security/Regressions/secitem/si-cms-signing-identity-p12.c create mode 100644 OSX/sec/Security/Regressions/secitem/si-cms-signing-identity-p12.h create mode 100644 OSX/sec/Security/SecBase.c rename OSX/sec/Security/{SecCTKKey.c => SecCTKKey.m} (88%) rename OSX/sec/Security/{SecECKey.c => SecECKey.m} (95%) rename OSX/sec/Security/{SecKeyAdaptors.c => SecKeyAdaptors.m} (99%) create mode 100644 OSX/sec/Security/SecKeyProxy.m delete mode 100644 OSX/sec/securityd/Regressions/secd-700-sftm.m delete mode 100644 OSX/sec/securityd/Regressions/secd-82-secproperties-basic.m create mode 100644 OSX/sec/securityd/SFKeychainServer.h create mode 100644 OSX/sec/securityd/SFKeychainServer.m delete mode 100644 OSX/sec/securityd/SecCAIssuerRequest.c create mode 100644 OSX/sec/securityd/SecCAIssuerRequest.m create mode 100644 OSX/sec/securityd/TrustURLSessionDelegate.h create mode 100644 OSX/sec/securityd/TrustURLSessionDelegate.m delete mode 100644 OSX/sec/securityd/asynchttp.c delete mode 100644 OSX/sec/securityd/asynchttp.h delete mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/DODInteroperabilityRootCA2.cer delete mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/ECARootCA4.cer delete mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/FederalBridgeCA2013.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/asset_receipt.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/baa_scrt_leaf.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/baa_system_root.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/baa_system_subca1.cer create mode 100644 OSX/shared_regressions/si-44-seckey-proxy.m rename OSX/shared_regressions/si-82-sectrust-ct-data/{CA_alpha.crt => CA_alpha.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{CA_beta.crt => CA_beta.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{digicert_sha2_ev_server_ca.crt => digicert_sha2_ev_server_ca.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{pilot_3055998.crt => pilot_3055998.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{pilot_3055998_issuer.crt => pilot_3055998_issuer.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{serverA.crt => serverA.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{serverD.crt => serverD.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{serverF.crt => serverF.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_1601.crt => server_1601.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_1603.crt => server_1603.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_1604.crt => server_1604.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_1701.crt => server_1701.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_1704.crt => server_1704.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_1705.crt => server_1705.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_1801.crt => server_1801.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_1804.crt => server_1804.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_1805.crt => server_1805.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{server_2001.crt => server_2001.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{whitelist_00008013.crt => whitelist_00008013.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{whitelist_00008013_issuer.crt => whitelist_00008013_issuer.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{whitelist_5555bc4f.crt => whitelist_5555bc4f.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{whitelist_5555bc4f_issuer.crt => whitelist_5555bc4f_issuer.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{whitelist_aaaae152.crt => whitelist_aaaae152.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{whitelist_fff9b5f6.crt => whitelist_fff9b5f6.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{whitelist_fff9b5f6_issuer.crt => whitelist_fff9b5f6_issuer.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{www_digicert_com_2015.crt => www_digicert_com_2015.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{www_digicert_com_2016.crt => www_digicert_com_2016.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{www_paypal_com.crt => www_paypal_com.cer} (100%) rename OSX/shared_regressions/si-82-sectrust-ct-data/{www_paypal_com_issuer.crt => www_paypal_com_issuer.cer} (100%) create mode 100644 OSX/utilities/src/SecAutorelease.h create mode 100644 OSX/utilities/src/SecAutorelease.m create mode 100644 RegressionTests/SecurityInduceLowDisk.plist create mode 100644 RegressionTests/secitemcanarytest/secitemcanarytest.entitlements create mode 100644 RegressionTests/secitemcanarytest/secitemcanarytest.m create mode 100644 Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/B3656633-AB83-4153-B404-DE14DBDC5ED6.plist create mode 100644 Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/Info.plist create mode 100644 SecurityTests/si-88-sectrust-valid-data/ca-ki.pem create mode 100644 SecurityTests/si-88-sectrust-valid-data/ca-unknown.pem create mode 100644 SecurityTests/si-88-sectrust-valid-data/leaf-ki-ok1.pem create mode 100644 SecurityTests/si-88-sectrust-valid-data/leaf-ki-revoked1.pem create mode 100644 SecurityTests/si-88-sectrust-valid-data/leaf-unknown.pem create mode 100644 base/Security.apinotes create mode 120000 header_symlinks/Security/OTConstants.h create mode 120000 header_symlinks/Security/SFSignInAnalytics.h create mode 120000 header_symlinks/Security/SecKeyProxy.h create mode 120000 header_symlinks/Security/SecProtocol.h create mode 120000 header_symlinks/Security/SecProtocolMetadata.h create mode 120000 header_symlinks/Security/SecProtocolObject.h create mode 120000 header_symlinks/Security/SecProtocolOptions.h create mode 120000 header_symlinks/Security/SecProtocolTypes.h create mode 120000 header_symlinks/Security/SecSharedCredential.h delete mode 120000 header_symlinks/macOS/Security/SecSharedCredential.h create mode 100644 keychain/CoreDataKeychain/KeychainModel.xcdatamodeld/KeychainModel.xcdatamodel/contents create mode 100644 keychain/CoreDataKeychain/SecCDKeychain.h create mode 100644 keychain/CoreDataKeychain/SecCDKeychain.m create mode 100644 keychain/KeychainDataclassOwner/Info.plist rename KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h => keychain/KeychainDataclassOwner/KeychainDataclassOwner.h (53%) create mode 100644 keychain/KeychainDataclassOwner/KeychainDataclassOwner.m create mode 100644 keychain/KeychainResources/Info.plist create mode 100644 keychain/SecKeyProxy.h create mode 100644 keychain/Signin Metrics/Resources/SFTMTests-Info.plist rename KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h => keychain/Signin Metrics/SFSignInAnalytics+Internal.h (53%) create mode 100644 keychain/Signin Metrics/SFSignInAnalytics.h create mode 100644 keychain/Signin Metrics/SFSignInAnalytics.m delete mode 100644 keychain/Signin Metrics/SFTransactionMetric.h delete mode 100644 keychain/Signin Metrics/SFTransactionMetric.m create mode 100644 keychain/Signin Metrics/tests/SFSignInAnalyticsTests.m delete mode 100644 keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h delete mode 100644 keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.m delete mode 100644 keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.h delete mode 100644 keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.m delete mode 100644 keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h delete mode 100644 keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.m delete mode 100644 keychain/analytics/awd/AWDKeychainSOSKeychainBackupFailed.h delete mode 100644 keychain/analytics/awd/AWDKeychainSOSKeychainBackupFailed.m delete mode 100644 keychain/analytics/awd/AWDKeychainSecDbMarkedCorrupt.h delete mode 100644 keychain/analytics/awd/AWDKeychainSecDbMarkedCorrupt.m delete mode 100644 keychain/analytics/awd/AWDMetricIds_Keychain.h delete mode 100644 keychain/analytics/awd/AwdMetadata-0x60-Keychain.bin create mode 100644 keychain/categories/NSError+UsefulConstructors.h create mode 100644 keychain/categories/NSError+UsefulConstructors.m create mode 100644 keychain/ckks/tests/CKKSAPSHandlingTests.m rename KeychainSyncingOverIDSProxy/IDSPersistentState.h => keychain/ckks/tests/CKKSAPSReceiverTests.h (64%) create mode 100644 protocol/SecProtocol.c create mode 100644 protocol/SecProtocol.h create mode 100644 protocol/SecProtocolMetadata.h create mode 100644 protocol/SecProtocolObject.h create mode 100644 protocol/SecProtocolOptions.h create mode 100644 protocol/SecProtocolPriv.h create mode 100644 protocol/SecProtocolTypes.h create mode 100644 protocol/SecProtocolTypes.m create mode 100644 secdxctests/CDKeychainTests.m create mode 100644 secdxctests/KeychainEntitlementsTest.m create mode 100644 secdxctests/SFCredentialStoreTests.m delete mode 100644 sslViewer/ecc-secp256r1-client.pfx create mode 100644 xcscripts/install-test-framework.sh diff --git a/.gitignore b/.gitignore index dfd386e4..50a93dee 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ cscope.out .DS_Store xcuserdata +._* +build diff --git a/Analytics/Clients/LocalKeychainAnalytics.h b/Analytics/Clients/LocalKeychainAnalytics.h new file mode 100644 index 00000000..13800cf2 --- /dev/null +++ b/Analytics/Clients/LocalKeychainAnalytics.h @@ -0,0 +1,42 @@ +#ifndef LocalKeychainAnalytics_h +#define LocalKeychainAnalytics_h + +#include + +typedef enum { + LKAKeychainUpgradeOutcomeSuccess, + LKAKeychainUpgradeOutcomeUnknownFailure, + LKAKeychainUpgradeOutcomeLocked, + LKAKeychainUpgradeOutcomeInternal, + LKAKeychainUpgradeOutcomeNewDb, + LKAKeychainUpgradeOutcomeObsoleteDb, + LKAKeychainUpgradeOutcomeNoSchema, + LKAKeychainUpgradeOutcomeIndices, + LKAKeychainUpgradeOutcomePhase1AlterTables, + LKAKeychainUpgradeOutcomePhase1DropIndices, + LKAKeychainUpgradeOutcomePhase1CreateSchema, + LKAKeychainUpgradeOutcomePhase1Items, + LKAKeychainUpgradeOutcomePhase1NonItems, + LKAKeychainUpgradeOutcomePhase1DropOld, + LKAKeychainUpgradeOutcomePhase2, +} LKAKeychainUpgradeOutcome; + +void LKAReportKeychainUpgradeOutcome(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome); +void LKAReportKeychainUpgradeOutcomeWithError(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome, CFErrorRef error); + +#if __OBJC2__ + +#import +#import + +typedef NSString* LKAnalyticsFailableEvent NS_STRING_ENUM; +extern LKAnalyticsFailableEvent const LKAEventUpgrade; + +@interface LocalKeychainAnalytics : SFAnalytics + +- (void)reportKeychainUpgradeFrom:(int)oldVersion to:(int)newVersion outcome:(LKAKeychainUpgradeOutcome)result error:(NSError*)error; + +@end + +#endif // OBJC2 +#endif // LocalKeychainAnalytics_h diff --git a/Analytics/Clients/LocalKeychainAnalytics.m b/Analytics/Clients/LocalKeychainAnalytics.m new file mode 100644 index 00000000..64d5334d --- /dev/null +++ b/Analytics/Clients/LocalKeychainAnalytics.m @@ -0,0 +1,151 @@ +#include "LocalKeychainAnalytics.h" + +#if __OBJC2__ + +#import "Security/SFAnalyticsDefines.h" + +#include +#include + +#include +#include + +@interface LKAUpgradeOutcomeReport : NSObject +@property LKAKeychainUpgradeOutcome outcome; +@property NSDictionary* attributes; +- (instancetype) initWithOutcome:(LKAKeychainUpgradeOutcome)outcome attributes:(NSDictionary*)attributes; +@end + +@implementation LKAUpgradeOutcomeReport +- (instancetype) initWithOutcome:(LKAKeychainUpgradeOutcome)outcome attributes:(NSDictionary*)attributes { + if (self = [super init]) { + self.outcome = outcome; + self.attributes = attributes; + } + return self; +} +@end + +// Public consts +// rdar://problem/41745059 SFAnalytics: collect keychain upgrade outcome information +LKAnalyticsFailableEvent const LKAEventUpgrade = (LKAnalyticsFailableEvent)@"LKAEventUpgrade"; + +// Internal consts +NSString* const LKAOldSchemaKey = @"oldschema"; +NSString* const LKANewSchemaKey = @"newschema"; +NSString* const LKAUpgradeOutcomeKey = @"upgradeoutcome"; + +@implementation LocalKeychainAnalytics { + BOOL _probablyInClassD; + NSMutableArray* _pendingReports; + dispatch_queue_t _queue; + int _notificationToken; +} + +- (instancetype __nullable)init { + if (self = [super init]) { + _probablyInClassD = YES; + _pendingReports = [NSMutableArray new]; + _queue = dispatch_queue_create("LKADataQueue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + _notificationToken = NOTIFY_TOKEN_INVALID; + } + return self; +} + ++ (NSString*)databasePath { + return [self defaultAnalyticsDatabasePath:@"localkeychain"]; +} + +// MARK: Client-specific functionality + +- (BOOL)canPersistMetrics { + @synchronized(self) { + if (!_probablyInClassD) { + return YES; + } + } + + // If this gets busy we should start caching if AKS tells us no + bool hasBeenUnlocked = false; + if (!SecAKSGetHasBeenUnlocked(&hasBeenUnlocked, NULL) || !hasBeenUnlocked) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + notify_register_dispatch(kUserKeybagStateChangeNotification, &self->_notificationToken, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token) { + // For side effect of processing pending messages if out of class D + [self canPersistMetrics]; + }); + }); + return NO; + } + + @synchronized(self) { + _probablyInClassD = NO; + if (_notificationToken != NOTIFY_TOKEN_INVALID) { + notify_cancel(_notificationToken); + } + } + + [self processPendingMessages]; + return YES; +} + +- (void)processPendingMessages { + dispatch_async(_queue, ^{ + for (LKAUpgradeOutcomeReport* report in self->_pendingReports) { + [self reportKeychainUpgradeOutcome:report.outcome attributes:report.attributes]; + } + }); +} + +- (void)reportKeychainUpgradeFrom:(int)oldVersion to:(int)newVersion outcome:(LKAKeychainUpgradeOutcome)outcome error:(NSError*)error { + + NSMutableDictionary* attributes = [@{LKAOldSchemaKey : @(oldVersion), + LKANewSchemaKey : @(newVersion), + LKAUpgradeOutcomeKey : @(outcome), + } mutableCopy]; + if (error) { + [attributes addEntriesFromDictionary:@{SFAnalyticsAttributeErrorDomain : error.domain, + SFAnalyticsAttributeErrorCode : @(error.code)}]; + } + + if (![self canPersistMetrics]) { + dispatch_async(_queue, ^{ + [self->_pendingReports addObject:[[LKAUpgradeOutcomeReport alloc] initWithOutcome:outcome attributes:attributes]]; + }); + } else { + [self reportKeychainUpgradeOutcome:outcome attributes:attributes]; + } +} + +- (void)reportKeychainUpgradeOutcome:(LKAKeychainUpgradeOutcome)outcome attributes:(NSDictionary*)attributes { + if (outcome == LKAKeychainUpgradeOutcomeSuccess) { + [self logSuccessForEventNamed:LKAEventUpgrade]; + } else { + // I could try and pick out the recoverable errors but I think we're good treating these all the same + [self logHardFailureForEventNamed:LKAEventUpgrade withAttributes:attributes]; + } +} + +@end + +// MARK: C Bridging + +void LKAReportKeychainUpgradeOutcome(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome) { + [[LocalKeychainAnalytics logger] reportKeychainUpgradeFrom:fromversion to:toversion outcome:outcome error:NULL]; +} + +void LKAReportKeychainUpgradeOutcomeWithError(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome, CFErrorRef error) { + [[LocalKeychainAnalytics logger] reportKeychainUpgradeFrom:fromversion to:toversion outcome:outcome error:(__bridge NSError*)error]; +} + +#else // not __OBJC2__ + +void LKAReportKeychainUpgradeOutcome(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome) { + // nothing to do on 32 bit +} + +void LKAReportKeychainUpgradeOutcomeWithError(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome, CFErrorRef error) { + // nothing to do on 32 bit +} + +#endif // __OBJC2__ diff --git a/Analytics/Clients/SOSAnalytics.m b/Analytics/Clients/SOSAnalytics.m index fb680277..4fa217c7 100644 --- a/Analytics/Clients/SOSAnalytics.m +++ b/Analytics/Clients/SOSAnalytics.m @@ -54,16 +54,7 @@ CKDKVSPerformanceCounter* const CKDKVSPerfCounterSynchronizeFailures = (CKDKVSPe remove(filename); }); }); - WithPathInKeychainDirectory(CFSTR("Analytics"), ^(const char *path) { -#if TARGET_OS_IPHONE - mode_t permissions = 0775; -#else - mode_t permissions = 0700; -#endif // TARGET_OS_IPHONE - mkpath_np(path, permissions); - chmod(path, permissions); - }); - return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"Analytics/sos_analytics.db") path]; + return [SOSAnalytics defaultAnalyticsDatabasePath:@"sos_analytics"]; } + (instancetype)logger diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+Throttle.h b/Analytics/SFAnalytics+Signin.h similarity index 61% rename from KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+Throttle.h rename to Analytics/SFAnalytics+Signin.h index 65a2c596..44c437d7 100644 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+Throttle.h +++ b/Analytics/SFAnalytics+Signin.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,15 +21,20 @@ * @APPLE_LICENSE_HEADER_END@ */ +#ifndef SFAnalytics_Internal_h +#define SFAnalytics_Internal_h -#import "IDSProxy.h" +#if __OBJC2__ -@interface KeychainSyncingOverIDSProxy (Throttle) - -- (dispatch_source_t)setNewTimer:(int)timeout key:(NSString*)key deviceName:(NSString*)deviceName peerID:(NSString*)peerID; -- (NSDictionary*)filterForWritableValues:(NSDictionary *)values; -- (void)recordTimestampForAppropriateInterval:(NSMutableDictionary**)timeTable key:(NSString*)key consecutiveWrites:(NSNumber**)consecutiveWrites; -- (void)recordTimestampOfWriteToIDS:(NSDictionary *)values deviceName:(NSString*)name peerID:(NSString*)peerid; +#import "SFAnalytics.h" +#import "SFAnalyticsSQLiteStore.h" +@interface SFAnalytics (SignIn) +/* Typical SFA clients do not need this. SignIn Metrics needs this */ +@property (nonatomic) SFAnalyticsSQLiteStore* database; +/*queue from SFA exposed for testing only, this queue is used to protected db accesses and should NOT be used directly*/ +@property (nonatomic) dispatch_queue_t queue; +@end +#endif // objc2 +#endif /* SFAnalytics_Internal_h */ -@end diff --git a/Analytics/SFAnalytics.h b/Analytics/SFAnalytics.h index 66b0fe36..130aec0f 100644 --- a/Analytics/SFAnalytics.h +++ b/Analytics/SFAnalytics.h @@ -39,6 +39,8 @@ extern const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport; + (NSInteger)fuzzyDaysSinceDate:(NSDate*)date; + (void)addOSVersionToEvent:(NSMutableDictionary*)event; +// Help for the subclass to pick a prefered location ++ (NSString *)defaultAnalyticsDatabasePath:(NSString *)basename; // Log event-based metrics: create an event corresponding to some event in your feature // and call the appropriate method based on the successfulness of that event diff --git a/Analytics/SFAnalytics.m b/Analytics/SFAnalytics.m index af07dd86..28e674cb 100644 --- a/Analytics/SFAnalytics.m +++ b/Analytics/SFAnalytics.m @@ -30,7 +30,9 @@ #import "SFAnalyticsMultiSampler+Internal.h" #import "SFAnalyticsSQLiteStore.h" #import "utilities/debugging.h" +#import #import +#import #import // SFAnalyticsDefines constants @@ -107,6 +109,8 @@ NSString* const SFAnalyticsTableSchema = @"CREATE TABLE IF NOT EXISTS hard_fa NSUInteger const SFAnalyticsMaxEventsToReport = 1000; +NSString* const SFAnalyticsErrorDomain = @"com.apple.security.sfanalytics"; + // Local constants NSString* const SFAnalyticsEventBuild = @"build"; NSString* const SFAnalyticsEventProduct = @"product"; @@ -114,6 +118,7 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; @interface SFAnalytics () @property (nonatomic) SFAnalyticsSQLiteStore* database; +@property (nonatomic) dispatch_queue_t queue; @end @implementation SFAnalytics { @@ -154,6 +159,24 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; return nil; } ++ (NSString *)defaultAnalyticsDatabasePath:(NSString *)basename +{ + WithPathInKeychainDirectory(CFSTR("Analytics"), ^(const char *path) { +#if TARGET_OS_IPHONE + mode_t permissions = 0775; +#else + mode_t permissions = 0700; +#endif // TARGET_OS_IPHONE + int ret = mkpath_np(path, permissions); + if (!(ret == 0 || ret == EEXIST)) { + secerror("could not create path: %s (%s)", path, strerror(ret)); + } + chmod(path, permissions); + }); + NSString *path = [NSString stringWithFormat:@"Analytics/%@.db", basename]; + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)path) path]; +} + + (NSInteger)fuzzyDaysSinceDate:(NSDate*)date { // Sentinel: it didn't happen at all @@ -192,6 +215,9 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; { if (!_database) { _database = [SFAnalyticsSQLiteStore storeWithPath:self.class.databasePath schema:SFAnalyticsTableSchema]; + if (!_database) { + seccritical("Did not get a database! (Client %@)", NSStringFromClass([self class])); + } } return _database; } @@ -463,7 +489,7 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; } __weak __typeof(self) weakSelf = self; - dispatch_sync(_queue, ^{ + dispatch_async(_queue, ^{ __strong __typeof(self) strongSelf = weakSelf; if (strongSelf) { [strongSelf->_samplers[samplerName] pauseSampling]; // when dealloced it would also stop, but we're not sure when that is so let's stop it right away @@ -480,7 +506,7 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; } __weak __typeof(self) weakSelf = self; - dispatch_sync(_queue, ^{ + dispatch_async(_queue, ^{ __strong __typeof(self) strongSelf = weakSelf; if (strongSelf) { [strongSelf->_multisamplers[samplerName] pauseSampling]; // when dealloced it would also stop, but we're not sure when that is so let's stop it right away @@ -496,8 +522,9 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; return nil; } SFAnalyticsActivityTracker* tracker = [[SFAnalyticsActivityTracker alloc] initWithName:eventName clientClass:[self class]]; - if (action) + if (action) { [tracker performAction:action]; + } return tracker; } @@ -514,7 +541,7 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; } __weak __typeof(self) weakSelf = self; - dispatch_sync(_queue, ^{ + dispatch_async(_queue, ^{ __strong __typeof(self) strongSelf = weakSelf; if (strongSelf && !strongSelf->_disableLogging) { if (once) { diff --git a/Analytics/SFAnalyticsActivityTracker.m b/Analytics/SFAnalyticsActivityTracker.m index f2c628a2..4d1379bd 100644 --- a/Analytics/SFAnalyticsActivityTracker.m +++ b/Analytics/SFAnalyticsActivityTracker.m @@ -45,7 +45,7 @@ } if (self = [super init]) { - _queue = dispatch_queue_create("SFAnalyticsActivityTracker queue", DISPATCH_QUEUE_SERIAL); + _queue = dispatch_queue_create("SFAnalyticsActivityTracker queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); _name = name; _clientClass = className; _measurement = nil; @@ -57,15 +57,18 @@ - (void)performAction:(void (^)(void))action { - _start = mach_absolute_time(); - action(); + [self start]; + dispatch_sync(_queue, ^{ + action(); + }); [self stop]; } - (void)start { - if (_canceled) + if (_canceled) { return; + } NSAssert(_start == 0, @"SFAnalyticsActivityTracker user called start twice"); _start = mach_absolute_time(); } @@ -73,14 +76,17 @@ - (void)stop { uint64_t end = mach_absolute_time(); + + if (_canceled) { + _start = 0; + return; + } + NSAssert(_start != 0, @"SFAnalyticsActivityTracker user called stop w/o calling start"); + static mach_timebase_info_data_t sTimebaseInfo; if ( sTimebaseInfo.denom == 0 ) { (void)mach_timebase_info(&sTimebaseInfo); } - if (_canceled) - return; - - NSAssert(_start != 0, @"SFAnalyticsActivityTracker user called stop w/o calling start"); _measurement = @([_measurement doubleValue] + (1.0f * (end - _start) * (1.0f * sTimebaseInfo.numer / sTimebaseInfo.denom))); _start = 0; @@ -93,6 +99,9 @@ - (void)dealloc { + if (_start != 0) { + [self stop]; + } if (!_canceled && _measurement != nil) { [[_clientClass logger] logMetric:_measurement withName:_name]; } diff --git a/Analytics/SFAnalyticsDefines.h b/Analytics/SFAnalyticsDefines.h index aa6af75c..53d8420f 100644 --- a/Analytics/SFAnalyticsDefines.h +++ b/Analytics/SFAnalyticsDefines.h @@ -67,6 +67,8 @@ extern NSString* const SFAnalyticsTableSchema; // We can only send this many events in total to splunk per upload extern NSUInteger const SFAnalyticsMaxEventsToReport; +extern NSString* const SFAnalyticsErrorDomain; + #endif /* __OBJC2__ */ #endif /* SFAnalyticsDefines_h */ diff --git a/Analytics/SFAnalyticsSQLiteStore.m b/Analytics/SFAnalyticsSQLiteStore.m index f779d289..76b4c43f 100644 --- a/Analytics/SFAnalyticsSQLiteStore.m +++ b/Analytics/SFAnalyticsSQLiteStore.m @@ -36,6 +36,15 @@ NSString* const SFAnalyticsUploadDate = @"upload_date"; + (instancetype)storeWithPath:(NSString*)path schema:(NSString*)schema { + if (![path length]) { + seccritical("Cannot init db with empty path"); + return nil; + } + if (![schema length]) { + seccritical("Cannot init db without schema"); + return nil; + } + SFAnalyticsSQLiteStore* store = nil; @synchronized([SFAnalyticsSQLiteStore class]) { static NSMutableDictionary* loggingStores = nil; diff --git a/Analytics/SQLite/SFSQLite.h b/Analytics/SQLite/SFSQLite.h index 4eda2730..6ec9d0f8 100644 --- a/Analytics/SQLite/SFSQLite.h +++ b/Analytics/SQLite/SFSQLite.h @@ -65,7 +65,6 @@ typedef NS_ENUM(NSInteger, SFSQLiteSynchronousMode) { NSMutableDictionary* _unitTestOverrides; #endif BOOL _hasMigrated; - BOOL _shouldVacuum; BOOL _corrupt; BOOL _traced; } @@ -80,7 +79,6 @@ typedef NS_ENUM(NSInteger, SFSQLiteSynchronousMode) { @property (nonatomic, assign) SFSQLiteSynchronousMode synchronousMode; @property (nonatomic, readonly) BOOL isOpen; @property (nonatomic, readonly) BOOL hasMigrated; -@property (nonatomic, assign) BOOL shouldVacuum; // vacuum the db on open (default:YES) @property (nonatomic, assign) BOOL traced; @property (nonatomic, strong) id delegate; diff --git a/Analytics/SQLite/SFSQLite.m b/Analytics/SQLite/SFSQLite.m index b7512c12..48aec13c 100644 --- a/Analytics/SQLite/SFSQLite.m +++ b/Analytics/SQLite/SFSQLite.m @@ -32,12 +32,9 @@ #define kSFSQLiteBusyTimeout (5*60*1000) -// Vaccuum our databases approximately once a week -#define kCKSQLVacuumInterval ((60*60*24)*7) -#define kSFSQLiteLastVacuumKey @"LastVacuum" - #define kSFSQLiteSchemaVersionKey @"SchemaVersion" #define kSFSQLiteCreatedDateKey @"Created" +#define kSFSQLiteAutoVacuumFull 1 static NSString *const kSFSQLiteCreatePropertiesTableSQL = @"create table if not exists Properties (\n" @@ -223,7 +220,6 @@ allDone: @synthesize userVersion = _userVersion; @synthesize synchronousMode = _synchronousMode; @synthesize hasMigrated = _hasMigrated; -@synthesize shouldVacuum = _shouldVacuum; @synthesize traced = _traced; @synthesize db = _db; @synthesize openCount = _openCount; @@ -235,8 +231,16 @@ allDone: #endif - (instancetype)initWithPath:(NSString *)path schema:(NSString *)schema { + if (![path length]) { + seccritical("Cannot init db with empty path"); + return nil; + } + if (![schema length]) { + seccritical("Cannot init db without schema"); + return nil; + } + if ((self = [super init])) { - NSAssert([path length], @"Can't init a database with a zero-length path"); _path = path; _schema = schema; _schemaVersion = [self _createSchemaHash]; @@ -244,7 +248,6 @@ allDone: _objectClassPrefix = @"CK"; _synchronousMode = SFSQLiteSynchronousModeNormal; _hasMigrated = NO; - _shouldVacuum = YES; } return self; } @@ -288,25 +291,6 @@ allDone: return _db != NULL; } -- (void)_periodicVacuum { - // "When the auto-vacuum mode is 1 or "full", the freelist pages are moved to the end of the database file and the database file is truncated to remove the freelist pages at every transaction commit. - // Note, however, that auto-vacuum only truncates the freelist pages from the file. Auto-vacuum does not defragment the database nor repack individual database pages the way that the VACUUM command does. - // In fact, because it moves pages around within the file, auto-vacuum can actually make fragmentation worse." - // https://sqlite.org/pragma.html#pragma_auto_vacuum - NSDate *lastVacuumDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[[self propertyForKey:kSFSQLiteLastVacuumKey] floatValue]]; - if ([lastVacuumDate timeIntervalSinceNow] < -(kCKSQLVacuumInterval)) { - @autoreleasepool { - os_transaction_t transaction = os_transaction_create("SFSQLITE DB Vacuum"); - secnotice("SFSQLITE", "performing periodic vacuum"); - [self executeSQL:@"VACUUM"]; - (void)transaction; // dead store - - NSString *vacuumDateString = [NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSinceReferenceDate]]; - [self setProperty:vacuumDateString forKey:kSFSQLiteLastVacuumKey]; - } - } -} - /* Best-effort attempts to set/correct filesystem permissions. May fail when we don't own DB which means we must wait for them to update permissions, @@ -374,8 +358,11 @@ allDone: if (![self executeSQL:@"pragma synchronous = %@", [self _synchronousModeString]]) { goto done; } - if (![self executeSQL:@"pragma auto_vacuum = FULL"]) { - goto done; + if ([self autoVacuumSetting] != kSFSQLiteAutoVacuumFull) { + /* After changing the auto_vacuum setting the DB must be vacuumed */ + if (![self executeSQL:@"pragma auto_vacuum = FULL"] || ![self executeSQL:@"VACUUM"]) { + goto done; + } } // rdar://problem/32168789 @@ -432,8 +419,6 @@ allDone: } #endif - if (self.shouldVacuum) [self _periodicVacuum]; - if (create || _hasMigrated) { [self setProperty:self.schemaVersion forKey:kSFSQLiteSchemaVersionKey]; if (self.userVersion) { @@ -606,7 +591,10 @@ done: } - (NSString *)propertyForKey:(NSString *)key { - NSAssert(key, @"Null key"); + if (![key length]) { + secerror("SFSQLite: attempt to retrieve property without a key"); + return nil; + } NSString *value = nil; @@ -621,7 +609,10 @@ done: } - (void)setProperty:(NSString *)value forKey:(NSString *)key { - NSAssert(key, @"Null key"); + if (![key length]) { + secerror("SFSQLite: attempt to set property without a key"); + return; + } if (value) { SFSQLiteStatement *statement = [self statementForSQL:@"insert or replace into Properties (key, value) values (?,?)"]; @@ -660,7 +651,9 @@ done: } - (void)removePropertyForKey:(NSString *)key { - NSAssert(key, @"Null key"); + if (![key length]) { + return; + } SFSQLiteStatement *statement = [self statementForSQL:@"delete from Properties where key = ?"]; [statement bindText:key atIndex:0]; @@ -805,10 +798,12 @@ done: } - (void)update:(NSString *)tableName set:(NSString *)setSQL where:(NSString *)whereSQL bindings:(NSArray *)whereBindings limit:(NSNumber *)limit { + if (![setSQL length]) { + return; + } + NSMutableString *SQL = [[NSMutableString alloc] init]; [SQL appendFormat:@"update %@", tableName]; - - NSAssert(setSQL.length > 0, @"null set expression"); [SQL appendFormat:@" set %@", setSQL]; if (whereSQL.length) { @@ -918,6 +913,17 @@ done: return userVersion; } +- (SInt32)autoVacuumSetting { + SInt32 vacuumMode = 0; + SFSQLiteStatement *statement = [self statementForSQL:@"pragma auto_vacuum"]; + while ([statement step]) { + vacuumMode = [statement intAtIndex:0]; + } + [statement reset]; + + return vacuumMode; +} + @end #endif diff --git a/IDSKeychainSyncingProxy/com.apple.private.alloy.keychainsync.plist b/IDSKeychainSyncingProxy/com.apple.private.alloy.keychainsync.plist deleted file mode 100644 index f08f2617b1ce77c9f0708dda9741267278cb8c15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 458 zcma)$O-{ow6ojA4Ut4}^V8H^|u|a~U3l7kzEcmS|wL+pz6&d@Ln7XkQJFT*3#Z5Q> z+=T@f;1r|~mPmP<(LBvJng^q#bJNsfa{ zfw7ZgiOKL>TBBIjVN<;CrZ(zpBY8* +#include #include #include @@ -49,9 +50,6 @@ #import "XPCNotificationDispatcher.h" -CFStringRef const CKDAggdIncreaseThrottlingKey = CFSTR("com.apple.cloudkeychainproxy.backoff.increase"); -CFStringRef const CKDAggdDecreaseThrottlingKey = CFSTR("com.apple.cloudkeychainproxy.backoff.decrease"); - @interface NSSet (CKDLogging) - (NSString*) logKeys; - (NSString*) logIDs; @@ -112,11 +110,6 @@ static NSString *kMonitorThirdMinute = @"CThirdMinute"; static NSString *kMonitorFourthMinute = @"DFourthMinute"; static NSString *kMonitorFifthMinute = @"EFifthMinute"; static NSString *kMonitorWroteInTimeSlice = @"TimeSlice"; -const CFStringRef kSOSKVSKeyParametersKey = CFSTR(">KeyParameters"); -const CFStringRef kSOSKVSInitialSyncKey = CFSTR("^InitialSync"); -const CFStringRef kSOSKVSAccountChangedKey = CFSTR("^AccountChanged"); -const CFStringRef kSOSKVSRequiredKey = CFSTR("^Required"); -const CFStringRef kSOSKVSOfficialDSIDKey = CFSTR("^OfficialDSID"); #define kSecServerKeychainChangedNotification "com.apple.security.keychainchanged" diff --git a/KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.osx.plist b/KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.osx.plist index 14f56bbf..37caef67 100644 --- a/KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.osx.plist +++ b/KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.osx.plist @@ -4,8 +4,6 @@ ProcessType Adaptive - LimitLoadToSessionType - Background EnablePressuredExit ProgramArguments diff --git a/KeychainCircle/KCAESGCMDuplexSession.m b/KeychainCircle/KCAESGCMDuplexSession.m index b3d5516e..2f512e16 100644 --- a/KeychainCircle/KCAESGCMDuplexSession.m +++ b/KeychainCircle/KCAESGCMDuplexSession.m @@ -299,6 +299,8 @@ static NSString* KCDSContext = @"context"; error:error] ? decrypted : nil; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" - (void) finalize { if (self.send) { ccgcm_ctx_clear(sizeof(*self.send), self.send); @@ -310,5 +312,6 @@ static NSString* KCDSContext = @"context"; } [super finalize]; } +#pragma clang diagnostic pop @end diff --git a/KeychainCircle/KCSRPContext.m b/KeychainCircle/KCSRPContext.m index 8686fdcd..3d9d8a8e 100644 --- a/KeychainCircle/KCSRPContext.m +++ b/KeychainCircle/KCSRPContext.m @@ -61,6 +61,8 @@ static const NSStringEncoding srpStringEncoding = NSUTF8StringEncoding; return self; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" - (void) finalize { ccsrp_ctx_clear(ccsrp_ctx_di(self.context), ccsrp_ctx_gp(self.context), @@ -68,6 +70,7 @@ static const NSStringEncoding srpStringEncoding = NSUTF8StringEncoding; free(self.context); } +#pragma clang diagnostic pop - (NSData*) getKey { size_t key_length = 0; diff --git a/KeychainCircle/PairingChannel.h b/KeychainCircle/PairingChannel.h index 66522092..a7c6870f 100644 --- a/KeychainCircle/PairingChannel.h +++ b/KeychainCircle/PairingChannel.h @@ -35,5 +35,6 @@ typedef void(^KCPairingChannelCompletion)(BOOL complete, NSData *packet, NSError /* for tests cases only */ - (void)setXPCConnectionObject:(NSXPCConnection *)connection; ++ (bool)isSupportedPlatform; @end diff --git a/KeychainCircle/Tests/KCDerTest.m b/KeychainCircle/Tests/KCDerTest.m index c4dcc319..16bf0ba7 100644 --- a/KeychainCircle/Tests/KCDerTest.m +++ b/KeychainCircle/Tests/KCDerTest.m @@ -34,28 +34,28 @@ if (size == 0) return; - uint8_t buffer[size]; + NSMutableData *buffer = [NSMutableData dataWithLength:size]; error = nil; - uint8_t* beginning = kcder_encode_data(data, &error, buffer, buffer + sizeof(buffer)); + uint8_t* beginning = kcder_encode_data(data, &error, [buffer mutableBytes], [buffer mutableBytes] + size); XCTAssert(beginning != NULL, "Error encoding: %@", error); if (beginning == NULL) return; - XCTAssertEqual(beginning, &buffer[0], @"Size != buffer use"); + XCTAssertEqual(beginning, [buffer mutableBytes], @"Size != buffer use"); NSData* recovered = nil; error = nil; - const uint8_t* end = kcder_decode_data(&recovered, &error, buffer, buffer + sizeof(buffer)); + const uint8_t* end = kcder_decode_data(&recovered, &error, [buffer mutableBytes], [buffer mutableBytes] + size); XCTAssert(end != NULL, "Error decoding: %@", error); if (end == NULL) return; - XCTAssertEqual(end, buffer + sizeof(buffer), @"readback didn't use all the buffer"); + XCTAssertEqual(end, [buffer mutableBytes] + size, @"readback didn't use all the buffer"); XCTAssertEqualObjects(data, recovered, @"Didn't get equal object"); @@ -78,28 +78,28 @@ if (size == 0) return; - uint8_t buffer[size]; + NSMutableData *buffer = [NSMutableData dataWithLength:size]; error = nil; - uint8_t* beginning = kcder_encode_string(string, &error, buffer, buffer + sizeof(buffer)); + uint8_t* beginning = kcder_encode_string(string, &error, [buffer mutableBytes], [buffer mutableBytes] + size); XCTAssert(beginning != NULL, "Error encoding: %@", error); if (beginning == NULL) return; - XCTAssertEqual(beginning, &buffer[0], @"Size != buffer use"); + XCTAssertEqual(beginning, [buffer mutableBytes], @"Size != buffer use"); NSString* recovered = nil; error = nil; - const uint8_t* end = kcder_decode_string(&recovered, &error, buffer, buffer + sizeof(buffer)); + const uint8_t* end = kcder_decode_string(&recovered, &error, [buffer mutableBytes], [buffer mutableBytes] + size); XCTAssert(end != NULL, "Error decoding: %@", error); if (end == NULL) return; - XCTAssertEqual(end, buffer + sizeof(buffer), @"readback didn't use all the buffer"); + XCTAssertEqual(end, [buffer mutableBytes] + size, @"readback didn't use all the buffer"); XCTAssertEqualObjects(string, recovered, @"Didn't get equal object"); diff --git a/KeychainCircle/Tests/KCPairingTest.m b/KeychainCircle/Tests/KCPairingTest.m index 19694e48..0d4e7c1b 100644 --- a/KeychainCircle/Tests/KCPairingTest.m +++ b/KeychainCircle/Tests/KCPairingTest.m @@ -198,10 +198,7 @@ { complete(@{}); } -- (void)idsPerformanceCounters:(void(^)(NSDictionary *))complete -{ - complete(@{}); -} + - (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary *))complete { complete(@{}); @@ -353,6 +350,10 @@ - (void)testSecPairBasicTest { + if (![KCPairingChannel isSupportedPlatform]) { + return; + } + bool sp1compete = false, sp2compete = false; NSData *sp1data = NULL; NSData *sp2data = NULL; diff --git a/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m b/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m index 09cbfb96..799decdd 100644 --- a/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m +++ b/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m @@ -18,31 +18,7 @@ #include #endif #import "utilities/debugging.h" - -#if OCTAGON - -static bool SecOTIsEnabled(void) -{ - bool userDefaultsShouldBottledPeer = true; - CFBooleanRef enabled = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("EnableOTRestore"), - CFSTR("com.apple.security"), - kCFPreferencesAnyUser, kCFPreferencesAnyHost); - if(enabled && CFGetTypeID(enabled) == CFBooleanGetTypeID()){ - if(enabled == kCFBooleanFalse){ - secnotice("octagon", "Octagon Restore Disabled"); - userDefaultsShouldBottledPeer = false; - } - if(enabled == kCFBooleanTrue){ - secnotice("octagon", "Octagon Restore Enabled"); - userDefaultsShouldBottledPeer = true; - } - } - - CFReleaseNull(enabled); - return userDefaultsShouldBottledPeer; -} - -#endif +#import "OT.h" @implementation KeychainSyncAccountNotification @@ -55,10 +31,12 @@ static bool SecOTIsEnabled(void) #endif } +// this is where we initialize SOS and OT for account sign-in +// the complement to this logic where we turn off SOS and OT is in KeychainDataclassOwner +// in the future we may bring this logic over there and delete KeychainSyncAccountNotification, but accounts people say that's a change that today would require coordination across multiple teams +// was asked to file this radar for accounts: Invoke DataclassOwner when enabling or signing into an account - (BOOL)account:(ACAccount *)account willChangeWithType:(ACAccountChangeType)changeType inStore:(ACDAccountStore *)store oldAccount:(ACAccount *)oldAccount { - NSString* oldAccountIdentifier = oldAccount.identifier; - NSString* accountIdentifier = account.identifier; - + if((changeType == kACAccountChangeTypeAdded) && [account.accountType.identifier isEqualToString: ACAccountTypeIdentifierAppleAccount] && [self accountIsPrimary:account]) { @@ -92,51 +70,26 @@ static bool SecOTIsEnabled(void) } #endif } + if ((changeType == kACAccountChangeTypeDeleted) && [oldAccount.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) { - if(oldAccountIdentifier != NULL && oldAccount.username !=NULL) { + + NSString *accountIdentifier = oldAccount.identifier; + NSString *username = oldAccount.username; + + if(accountIdentifier != NULL && username !=NULL) { if ([self accountIsPrimary:oldAccount]) { CFErrorRef removalError = NULL; - - secinfo("accounts", "Performing SOS circle credential removal for account %@: %@", oldAccountIdentifier, oldAccount.username); - + + secinfo("accounts", "Performing SOS circle credential removal for account %@: %@", accountIdentifier, username); + if (!SOSCCLoggedOutOfAccount(&removalError)) { - secerror("Account %@ could not leave the SOS circle: %@", oldAccountIdentifier, removalError); - } -#if OCTAGON - if(SecOTIsEnabled()){ - __block NSError* error = nil; - OTControl* otcontrol = [OTControl controlObject:&error]; - - if (nil == otcontrol) { - secerror("octagon: Failed to get OTControl: %@", error.localizedDescription); - } else { - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - - [otcontrol signOut:^(BOOL result, NSError * _Nullable signedOutError) { - if(!result || signedOutError){ - secerror("octagon: error signing out: %s", [[signedOutError description] UTF8String]); - } - else{ - secnotice("octagon", "signed out of octagon trust"); - } - dispatch_semaphore_signal(sema); - }]; - if (0 != dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60 * 5))) { - secerror("octagon: Timed out signing out"); - } - } + secerror("Account %@ could not leave the SOS circle: %@", accountIdentifier, removalError); } - else{ - secerror("Octagon not enabled!"); - } -#endif - } else { - secinfo("accounts", "NOT performing SOS circle credential removal for secondary account %@: %@", accountIdentifier, account.username); + } - } else{ - secinfo("accounts", "Already logged out of account"); } } + return YES; } diff --git a/KeychainSyncingOverIDSProxy/IDSPersistentState.m b/KeychainSyncingOverIDSProxy/IDSPersistentState.m deleted file mode 100644 index 0c884467..00000000 --- a/KeychainSyncingOverIDSProxy/IDSPersistentState.m +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2012-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@ - */ - -// -// IDSPersistentState.m -// - -#import -#import -#import -#import -#import -#import -#import -#import - -#import "IDSPersistentState.h" - -#if ! __has_feature(objc_arc) -#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag -#endif - -static CFStringRef kRegistrationFileName = CFSTR("com.apple.security.keychainsyncingoveridsproxy.unhandledMessages.plist"); - -@implementation KeychainSyncingOverIDSProxyPersistentState - -+ (BOOL)write:(NSURL *)path data:(id)plist error:(NSError **)error -{ - if (![NSPropertyListSerialization propertyList: plist isValidForFormat: NSPropertyListXMLFormat_v1_0]) - { - secerror("can't save PersistentState as XML"); - return false; - } - - NSData *data = [NSPropertyListSerialization dataWithPropertyList: plist - format: NSPropertyListXMLFormat_v1_0 options: 0 error: error]; - if (data == nil) - { - secerror("error serializing PersistentState to xml: %@", *error); - return false; - } - - BOOL writeStatus = [data writeToURL: path options: NSDataWritingAtomic error: error]; - if (!writeStatus) - secerror("error writing PersistentState to file: %@", *error); - - return writeStatus; -} - -+ (id)read: (NSURL *)path error:(NSError **)error -{ - NSData *data = [NSData dataWithContentsOfURL: path options: 0 error: error]; - if (data == nil) - { - secdebug("unhandledmessages", "error reading PersistentState from %@: %@", path, *error); - return nil; - } - - // Now the deserializing: - - NSPropertyListFormat format; - id plist = [NSPropertyListSerialization propertyListWithData: data - options: NSPropertyListMutableContainersAndLeaves format: &format error: error]; - - if (plist == nil) - secerror("could not deserialize PersistentState from %@: %@", path, *error); - - return plist; -} - -+ (NSURL *)registrationFileURL -{ - return (NSURL *)CFBridgingRelease(SecCopyURLForFileInPreferencesDirectory(kRegistrationFileName)); -} - -+ (NSString *)dictionaryDescription: (NSDictionary *)state -{ - NSMutableArray *elements = [NSMutableArray array]; - [state enumerateKeysAndObjectsUsingBlock: ^(NSString *key, id obj, BOOL *stop) { - [elements addObject: [key stringByAppendingString: @":"]]; - if ([obj isKindOfClass:[NSArray class]]) { - [elements addObject: [(NSArray *)obj componentsJoinedByString: @" "]]; - } else { - [elements addObject: [NSString stringWithFormat:@"%@", obj]]; - } - }]; - return [elements componentsJoinedByString: @" "]; -} - -+ (NSMutableDictionary *)idsState -{ - NSError *error = NULL; - id stateDictionary = [KeychainSyncingOverIDSProxyPersistentState read:[[self class] registrationFileURL] error:&error]; - secdebug("keyregister", "Read registeredKeys: <%@>", [self dictionaryDescription: stateDictionary]); - // Ignore older states with an NSArray - if (![stateDictionary isKindOfClass:[NSDictionary class]]) - return NULL; - return [NSMutableDictionary dictionaryWithDictionary:stateDictionary]; -} - -+ (void)setUnhandledMessages: (NSDictionary *)unhandledMessages -{ - NSError *error = NULL; - secdebug("IDS unhandled message", "Write unhandled Messages and monitor state: <%@>", [self dictionaryDescription: unhandledMessages]); - [KeychainSyncingOverIDSProxyPersistentState write:[[self class] registrationFileURL] data:unhandledMessages error:&error]; -} - -@end diff --git a/KeychainSyncingOverIDSProxy/IDSProxy.h b/KeychainSyncingOverIDSProxy/IDSProxy.h deleted file mode 100644 index ec09a8fe..00000000 --- a/KeychainSyncingOverIDSProxy/IDSProxy.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2012-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import -#import -#import -#import "SOSCloudKeychainClient.h" -#import -#import - -typedef enum { - kIDSStartPingTestMessage = 1, - kIDSEndPingTestMessage= 2, - kIDSSendOneMessage = 3, - kIDSPeerReceivedACK = 4, - kIDSPeerAvailability = 6, - kIDSPeerAvailabilityDone = 7, - kIDSKeychainSyncIDSFragmentation = 8, -} idsOperation; - -@interface KeychainSyncingOverIDSProxy : NSObject -{ - IDSService *_service; - NSString *deviceID; - NSMutableDictionary *deviceIDFromAuthToken; -} - -@property (retain, nonatomic) NSMutableDictionary *deviceIDFromAuthToken; -@property (retain, nonatomic) NSString *deviceID; -@property (retain, nonatomic) NSMutableDictionary *shadowPendingMessages; -@property (retain, nonatomic) NSMutableDictionary *allFragmentedMessages; -@property (retain, atomic) NSMutableDictionary *pingTimers; -@property (retain, nonatomic) NSMutableDictionary *peerNextSendCache; //dictionary of device ID -> time stamp of when to send next - -// Only touch these three dictionaries from the dataQueue or you will crash, eventually. -@property (retain, nonatomic) NSMutableDictionary *messagesInFlight; -@property (retain, nonatomic) NSMutableDictionary *unhandledMessageBuffer; -@property (retain, nonatomic) NSMutableDictionary *monitor; -@property (atomic) dispatch_source_t penaltyTimer; -@property (atomic) bool penaltyTimerScheduled; -@property (retain, atomic) NSDictionary *queuedMessages; - -@property (retain, atomic) NSMutableDictionary *counterValues; -@property (atomic) NSInteger outgoingMessages; -@property (atomic) NSInteger incomingMessages; - - - - - -@property (atomic) bool isIDSInitDone; -@property (atomic) bool shadowDoInitializeIDSService; -@property (atomic) bool isSecDRunningAsRoot; -@property (atomic) bool doesSecDHavePeer; - -@property (atomic) dispatch_queue_t calloutQueue; -@property (atomic) dispatch_queue_t pingQueue; -@property dispatch_queue_t dataQueue; - -@property (atomic) bool isLocked; -@property (atomic) bool unlockedSinceBoot; -@property (atomic) dispatch_source_t retryTimer; -@property (atomic) bool retryTimerScheduled; -@property (atomic) bool inCallout; -@property (atomic) bool setIDSDeviceID; -@property (atomic) bool shadowDoSetIDSDeviceID; - -@property (atomic) bool handleAllPendingMessages; -@property (atomic) bool shadowHandleAllPendingMessages; -@property (atomic) bool sendRestoredMessages; -@property (atomic) bool allowKVSFallBack; - -+ (KeychainSyncingOverIDSProxy *) idsProxy; - -- (id)init; - -- (void) doSetIDSDeviceID; -- (void) doIDSInitialization; -- (void) calloutWith: (void(^)(NSMutableDictionary *pending, - bool handlePendingMesssages, - bool doSetDeviceID, - dispatch_queue_t queue, - void(^done)(NSMutableDictionary *handledMessages, - bool handledPendingMessage, - bool handledSettingDeviceID))) callout; -- (void) sendKeysCallout: (NSMutableDictionary *(^)(NSMutableDictionary* pending, NSError** error)) handleMessages; -- (void) persistState; -- (void) sendPersistedMessagesAgain; -- (NSDictionary*) retrievePendingMessages; -- (NSDictionary*) collectStats; -- (void) scheduleRetryRequestTimer; -- (BOOL) haveMessagesInFlight; --(void) printMessage:(NSDictionary*) message state:(NSString*)state; - -@end - -NSString* createErrorString(NSString* format, ...) - NS_FORMAT_FUNCTION(1, 2); - - diff --git a/KeychainSyncingOverIDSProxy/IDSProxy.m b/KeychainSyncingOverIDSProxy/IDSProxy.m deleted file mode 100644 index 0f09c6e9..00000000 --- a/KeychainSyncingOverIDSProxy/IDSProxy.m +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright (c) 2012-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import - -#import -#import -#import -#import - -#include -#include -#include -#include - -#import -#import - -#include -#include -#include -#include - -#import "IDSProxy.h" -#import "KeychainSyncingOverIDSProxy+ReceiveMessage.h" -#import "KeychainSyncingOverIDSProxy+SendMessage.h" -#import "IDSPersistentState.h" - -#define kSecServerKeychainChangedNotification "com.apple.security.keychainchanged" -#define kSecServerPeerInfoAvailable "com.apple.security.fpiAvailable" - -#define IDSServiceNameKeychainSync "com.apple.private.alloy.keychainsync" -static NSString *kMonitorState = @"MonitorState"; -static NSString *kExportUnhandledMessages = @"UnhandledMessages"; -static NSString *kMessagesInFlight = @"MessagesInFlight"; -static const char *kStreamName = "com.apple.notifyd.matching"; -static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; -static NSString *const kIDSNumberOfFragments = @"NumberOfIDSMessageFragments"; -static NSString *const kIDSFragmentIndex = @"kFragmentIndex"; - -static NSString *const kOutgoingMessages = @"IDS Outgoing Messages"; -static NSString *const kIncomingMessages = @"IDS Incoming Messages"; - -NSString *const IDSSendMessageOptionForceEncryptionOffKey = @"IDSSendMessageOptionForceEncryptionOff"; -static const int64_t kRetryTimerLeeway = (NSEC_PER_MSEC * 250); // 250ms leeway for handling unhandled messages. -static const int64_t kMinMessageRetryDelay = (NSEC_PER_SEC * 8); - -CFIndex SECD_RUN_AS_ROOT_ERROR = 1041; - -#define IDSPROXYSCOPE "IDSProxy" - -@implementation KeychainSyncingOverIDSProxy - -@synthesize deviceID = deviceID; -@synthesize deviceIDFromAuthToken = deviceIDFromAuthToken; - -+ (KeychainSyncingOverIDSProxy *) idsProxy -{ - static KeychainSyncingOverIDSProxy *idsProxy; - if (!idsProxy) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - idsProxy = [[self alloc] init]; - }); - } - return idsProxy; -} - --(NSDictionary*) exportState -{ - return @{ kMonitorState:self.monitor, - kExportUnhandledMessages:self.unhandledMessageBuffer, - kMessagesInFlight:self.messagesInFlight - }; - -} - --(NSDictionary*) retrievePendingMessages -{ - NSDictionary * __block messages; - dispatch_sync(self.dataQueue, ^{ - messages = [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight copy]; - }); - return messages; -} - -@synthesize unhandledMessageBuffer = _unhandledMessageBuffer; - -- (NSMutableDictionary *) unhandledMessageBuffer { - dispatch_assert_queue(self.dataQueue); - return _unhandledMessageBuffer; -} - -- (void) setUnhandledMessageBuffer:(NSMutableDictionary *)unhandledMessageBuffer { - dispatch_assert_queue(self.dataQueue); - _unhandledMessageBuffer = unhandledMessageBuffer; -} - -@ synthesize messagesInFlight = _messagesInFlight; - -- (NSMutableDictionary *) messagesInFlight { - dispatch_assert_queue(self.dataQueue); - return _messagesInFlight; -} - -- (void) setMessagesInFlight:(NSMutableDictionary *)messagesInFlight { - dispatch_assert_queue(self.dataQueue); - _messagesInFlight = messagesInFlight; -} - -@synthesize monitor = _monitor; - -- (NSMutableDictionary *) monitor { - dispatch_assert_queue(self.dataQueue); - return _monitor; -} - -- (void) setMonitor:(NSMutableDictionary *)monitor { - dispatch_assert_queue(self.dataQueue); - _monitor = monitor; -} - -- (void) persistState -{ - dispatch_sync(self.dataQueue, ^{ - [KeychainSyncingOverIDSProxyPersistentState setUnhandledMessages:[self exportState]]; - }); -} - -- (BOOL) haveMessagesInFlight { - BOOL __block inFlight = NO; - dispatch_sync(self.dataQueue, ^{ - inFlight = [self.messagesInFlight count] > 0; - }); - return inFlight; -} - -- (void) sendPersistedMessagesAgain -{ - NSMutableDictionary * __block copy; - - dispatch_sync(self.dataQueue, ^{ - copy = [NSMutableDictionary dictionaryWithDictionary:self.messagesInFlight]; - }); - - if(copy && [copy count] > 0){ - [copy enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - NSDictionary* idsMessage = (NSDictionary*)obj; - NSString *uniqueMessageID = (NSString*)key; - - NSString *peerID = (NSString*)[idsMessage objectForKey:(__bridge NSString*)kIDSMessageRecipientPeerID]; - NSString *ID = (NSString*)[idsMessage objectForKey:(__bridge NSString*)kIDSMessageRecipientDeviceID]; - NSString *senderDeviceID = (NSString*)[idsMessage objectForKey:(__bridge NSString*)kIDSMessageSenderDeviceID]; - dispatch_sync(self.dataQueue, ^{ - [self.messagesInFlight removeObjectForKey:key]; - }); - - if (!peerID || !ID) { - return; - } - [self printMessage:idsMessage state:@"sending persisted message"]; - - if([self sendIDSMessage:idsMessage name:ID peer:peerID senderDeviceID:senderDeviceID]){ - NSString *useAckModel = [idsMessage objectForKey:kIDSMessageUseACKModel]; - if([useAckModel compare:@"YES"] == NSOrderedSame && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack){ - secnotice("IDS Transport", "setting timer!"); - [self setMessageTimer:uniqueMessageID deviceID:ID message:idsMessage]; - } - } - }]; - } -} - -- (id)init -{ - if (self = [super init]) - { - secnotice("event", "%@ start", self); - - _isIDSInitDone = false; - _service = nil; - _calloutQueue = dispatch_queue_create("IDSCallout", DISPATCH_QUEUE_SERIAL); - _pingQueue = dispatch_queue_create("PingQueue", DISPATCH_QUEUE_SERIAL); - _dataQueue = dispatch_queue_create("DataQueue", DISPATCH_QUEUE_SERIAL); - _pingTimers = [[NSMutableDictionary alloc] init]; - deviceIDFromAuthToken = [[NSMutableDictionary alloc] init]; - _peerNextSendCache = [[NSMutableDictionary alloc] init]; - _counterValues = [[NSMutableDictionary alloc] init]; - _outgoingMessages = 0; - _incomingMessages = 0; - _isSecDRunningAsRoot = false; - _doesSecDHavePeer = true; - _allowKVSFallBack = true; - secdebug(IDSPROXYSCOPE, "%@ done", self); - - [self doIDSInitialization]; - if(_isIDSInitDone) - [self doSetIDSDeviceID]; - - // Register for lock state changes - xpc_set_event_stream_handler(kStreamName, dispatch_get_main_queue(), - ^(xpc_object_t notification){ - [self streamEvent:notification]; - }); - - _retryTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); - dispatch_source_set_timer(_retryTimer, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, kRetryTimerLeeway); - dispatch_source_set_event_handler(_retryTimer, ^{ - [self timerFired]; - }); - dispatch_resume(_retryTimer); - NSMutableDictionary *state = [KeychainSyncingOverIDSProxyPersistentState idsState]; - - _unhandledMessageBuffer = state[kExportUnhandledMessages]; - if (!_unhandledMessageBuffer) { - _unhandledMessageBuffer = [NSMutableDictionary dictionary]; - } - _messagesInFlight = state[kMessagesInFlight]; - if(_messagesInFlight == nil) { - _messagesInFlight = [NSMutableDictionary dictionary]; - } - _monitor = state[kMonitorState]; - if(_monitor == nil) { - _monitor = [NSMutableDictionary dictionary]; - } - - if([_messagesInFlight count ] > 0) - _sendRestoredMessages = true; - int notificationToken; - notify_register_dispatch(kSecServerKeychainChangedNotification, ¬ificationToken, self.dataQueue, - ^ (int token __unused) - { - secinfo("backoff", "keychain changed, wiping backoff monitor state"); - self.monitor = [NSMutableDictionary dictionary]; - }); - int peerInfo; - notify_register_dispatch(kSecServerPeerInfoAvailable, &peerInfo, dispatch_get_main_queue(), - ^ (int token __unused) - { - secinfo("IDS Transport", "secd has a peer info"); - if(self.doesSecDHavePeer == false){ - self.doesSecDHavePeer = true; - [self doSetIDSDeviceID]; - } - }); - - [self updateUnlockedSinceBoot]; - [self updateIsLocked]; - if (!_isLocked) - [self keybagDidUnlock]; - - - } - return self; -} - -- (void)streamEvent:(xpc_object_t)notification -{ -#if (!TARGET_IPHONE_SIMULATOR) - const char *notificationName = xpc_dictionary_get_string(notification, "Notification"); - if (!notificationName) { - } else if (strcmp(notificationName, kUserKeybagStateChangeNotification)==0) { - return [self keybagStateChange]; - } - const char *eventName = xpc_dictionary_get_string(notification, "XPCEventName"); - char *desc = xpc_copy_description(notification); - secnotice("event", "%@ event: %s name: %s desc: %s", self, eventName, notificationName, desc); - if (desc) - free((void *)desc); -#endif -} - -- (void) keybagDidLock -{ - secnotice("IDS Transport", "%@ locking!", self); -} - -- (void) keybagDidUnlock -{ - secnotice("IDS Transport", "%@ unlocking!", self); - [self handleAllPendingMessage]; -} - -- (BOOL) updateUnlockedSinceBoot -{ - CFErrorRef aksError = NULL; - if (!SecAKSGetHasBeenUnlocked(&_unlockedSinceBoot, &aksError)) { - secerror("%@ Got error from SecAKSGetHasBeenUnlocked: %@", self, aksError); - CFReleaseSafe(aksError); - return NO; - } - return YES; -} - -- (BOOL) updateIsLocked -{ - CFErrorRef aksError = NULL; - if (!SecAKSGetIsLocked(&_isLocked, &aksError)) { - secerror("%@ Got error querying lock state: %@", self, aksError); - CFReleaseSafe(aksError); - return NO; - } - secerror("updateIsLocked: %d", _isLocked); - if (!_isLocked) - _unlockedSinceBoot = YES; - return YES; -} - -- (void) keybagStateChange -{ - os_activity_initiate("keybagStateChanged", OS_ACTIVITY_FLAG_DEFAULT, ^{ - secerror("keybagStateChange! was locked: %d", self->_isLocked); - BOOL wasLocked = self->_isLocked; - if ([self updateIsLocked]) { - if (wasLocked == self->_isLocked) - secdebug("IDS Transport", "%@ still %s ignoring", self, self->_isLocked ? "locked" : "unlocked"); - else if (self->_isLocked) - [self keybagDidLock]; - else - [self keybagDidUnlock]; - } - }); -} - - -- (void)timerFired -{ - NSUInteger __block messagecount = 0; - dispatch_sync(self.dataQueue, ^{ - if(self.unhandledMessageBuffer) { - secnotice("IDS Transport", "%@ attempting to hand unhandled messages to securityd, here is our message queue: %@", self, self.unhandledMessageBuffer); - messagecount = [self.unhandledMessageBuffer count]; - } - }); - - if(self.isLocked) { - self.retryTimerScheduled = NO; - } else if(messagecount == 0) { - self.retryTimerScheduled = NO; - } else if (self.retryTimerScheduled && !self.isLocked) { - [self handleAllPendingMessage]; - } else { - [[KeychainSyncingOverIDSProxy idsProxy] scheduleRetryRequestTimer]; - } -} - -- (void)scheduleRetryRequestTimer -{ - secnotice("IDS Transport", "scheduling unhandled messages timer"); - dispatch_source_set_timer(_retryTimer, dispatch_time(DISPATCH_TIME_NOW, kMinMessageRetryDelay), DISPATCH_TIME_FOREVER, kRetryTimerLeeway); - _retryTimerScheduled = YES; -} - -- (void)doIDSInitialization -{ - - dispatch_async(self.calloutQueue, ^{ - secnotice("IDS Transport", "doIDSInitialization!"); - - self->_service = [[IDSService alloc] initWithService: @IDSServiceNameKeychainSync]; - - if( self->_service == nil ){ - self->_isIDSInitDone = false; - secerror("Could not create ids service"); - } - else{ - secnotice("IDS Transport", "IDS Transport Successfully set up IDS!"); - [self->_service addDelegate:self queue: dispatch_get_main_queue()]; - - self->_isIDSInitDone = true; - if(self->_isSecDRunningAsRoot == false) - [self doSetIDSDeviceID]; - } - }); -} - -- (void) doSetIDSDeviceID -{ - NSInteger code = 0; - NSString *errorMessage = nil; - - if(!_isIDSInitDone){ - [self doIDSInitialization]; - } - _setIDSDeviceID = YES; - - if(_isSecDRunningAsRoot != false) - { - errorMessage = @"cannot set IDS device ID, secd is running as root"; - code = SECD_RUN_AS_ROOT_ERROR; - secerror("Setting device ID error: %@, code: %ld", errorMessage, (long)code); - - } - else if(_doesSecDHavePeer != true) - { - errorMessage = @"cannot set IDS deviceID, secd does not have a full peer info for account"; - code = kSOSErrorPeerNotFound; - secerror("Setting device ID error: %@, code: %ld", errorMessage, (long)code); - - } - else if(!_isIDSInitDone){ - errorMessage = @"KeychainSyncingOverIDSProxy can't set up the IDS service"; - code = kSecIDSErrorNotRegistered; - secerror("Setting device ID error: %@, code: %ld", errorMessage, (long)code); - } - else if(_isLocked){ - errorMessage = @"KeychainSyncingOverIDSProxy can't set device ID, device is locked"; - code = kSecIDSErrorDeviceIsLocked; - secerror("Setting device ID error: %@, code: %ld", errorMessage, (long)code); - } - - else{ - [self calloutWith:^(NSMutableDictionary *pending, bool handlePendingMesssages, bool doSetDeviceID, dispatch_queue_t queue, void(^done)(NSMutableDictionary *, bool, bool)) { - CFErrorRef localError = NULL; - bool handledSettingID = false; - NSString *ID = IDSCopyLocalDeviceUniqueID(); - self->deviceID = ID; - - if(ID){ - handledSettingID = SOSCCSetDeviceID((__bridge CFStringRef) ID, &localError); - - if(!handledSettingID && localError != NULL){ - if(CFErrorGetCode(localError) == SECD_RUN_AS_ROOT_ERROR){ - secerror("SETTING RUN AS ROOT ERROR: %@", localError); - self->_isSecDRunningAsRoot = true; - } - else if (CFErrorIsMalfunctioningKeybagError(localError)) { - secnotice("IDS Transport", "system is unavailable, cannot set device ID, error: %@", localError); - self->_isLocked = true; - } - else if (CFErrorGetCode(localError) == kSOSErrorPeerNotFound && CFStringCompare(CFErrorGetDomain(localError), kSOSErrorDomain, 0) == 0){ - secnotice("IDS Transport","securityd does not have a peer yet , error: %@", localError); - self->_doesSecDHavePeer = false; - } - } - else - self->_setIDSDeviceID = NO; - - CFReleaseNull(localError); - dispatch_async(queue, ^{ - done(nil, NO, YES); - }); - } else { - dispatch_async(queue, ^{ - done(nil, NO, NO); - }); - } - if(errorMessage != nil){ - secerror("Setting device ID error: KeychainSyncingOverIDSProxy could not retrieve device ID from keychain, code: %ld", (long)kSecIDSErrorNoDeviceID); - } - }]; - } -} - -- (void) calloutWith: (void(^)(NSMutableDictionary *pending, bool handlePendingMesssages, bool doSetDeviceID, dispatch_queue_t queue, void(^done)(NSMutableDictionary *handledMessages, bool handledPendingMessage, bool handledSettingDeviceID))) callout -{ - // In KeychainSyncingOverIDSProxy serial queue - dispatch_queue_t idsproxy_queue = dispatch_get_main_queue(); - - // dispatch_get_global_queue - well-known global concurrent queue - // dispatch_get_main_queue - default queue that is bound to the main thread - xpc_transaction_begin(); - dispatch_async(_calloutQueue, ^{ - __block NSMutableDictionary *myPending; - __block bool myHandlePendingMessage; - __block bool myDoSetDeviceID; - __block bool wasLocked; - dispatch_sync(idsproxy_queue, ^{ - dispatch_sync(self.dataQueue, ^{ - myPending = [self.unhandledMessageBuffer copy]; - }); - myHandlePendingMessage = self.handleAllPendingMessages; - myDoSetDeviceID = self.setIDSDeviceID; - wasLocked = self.isLocked; - - self.inCallout = YES; - - self.shadowHandleAllPendingMessages = NO; - }); - - callout(myPending, myHandlePendingMessage, myDoSetDeviceID, idsproxy_queue, ^(NSMutableDictionary *handledMessages, bool handledPendingMessage, bool handledSetDeviceID) { - secdebug("event", "%@ %s%s before callout handled: %s%s", self, myHandlePendingMessage ? "P" : "p", myDoSetDeviceID ? "D" : "d", handledPendingMessage ? "H" : "h", handledSetDeviceID ? "I" : "i"); - - // In IDSKeychainSyncingProxy's serial queue - self->_inCallout = NO; - - // Update setting device id - self->_setIDSDeviceID = ((myDoSetDeviceID && !handledSetDeviceID)); - - self->_shadowDoSetIDSDeviceID = NO; - - xpc_transaction_end(); - }); - }); -} - -- (void) sendKeysCallout: (NSMutableDictionary*(^)(NSMutableDictionary* pending, NSError** error)) handleMessages { - [self calloutWith: ^(NSMutableDictionary *pending, bool handlePendingMesssages, bool doSetDeviceID, dispatch_queue_t queue, void(^done)(NSMutableDictionary *, bool, bool)) { - NSError* error = NULL; - - NSMutableDictionary* handled = handleMessages(pending, &error); - - dispatch_async(queue, ^{ - if (!handled && error) { - secerror("%@ did not handle message: %@", self, error); - } - - done(handled, NO, NO); - }); - }]; -} - -NSString* createErrorString(NSString* format, ...) -{ - va_list va; - va_start(va, format); - NSString* errorString = ([[NSString alloc] initWithFormat:format arguments:va]); - va_end(va); - return errorString; - -} - -- (NSDictionary*) collectStats{ - [_counterValues setObject:[NSNumber numberWithInteger:[KeychainSyncingOverIDSProxy idsProxy].outgoingMessages] forKey:kOutgoingMessages]; - [_counterValues setObject:[NSNumber numberWithInteger:[KeychainSyncingOverIDSProxy idsProxy].incomingMessages] forKey:kIncomingMessages]; - - return _counterValues; -} - --(void) printMessage:(NSDictionary*) message state:(NSString*)state -{ - secnotice("IDS Transport", "message state: %@", state); - secnotice("IDS Transport", "msg id: %@", message[(__bridge NSString*)kIDSMessageUniqueID]); - secnotice("IDS Transport", "receiver ids device id: %@", message[(__bridge NSString*)kIDSMessageRecipientDeviceID]); - secnotice("IDS Transport", "sender device id: %@", message[(__bridge NSString*)kIDSMessageSenderDeviceID]); - secnotice("IDS Transport", "receiver peer id: %@", message[(__bridge NSString*)kIDSMessageRecipientPeerID]); - secnotice("IDS Transport", "fragment index: %@", (NSNumber*)message[kIDSFragmentIndex]); - secnotice("IDS Transport", "total number of fragments: %@", (NSNumber*)message[kIDSNumberOfFragments]); - secnotice("IDS Transport", "%@ data: %@", state, message[(__bridge NSString*)kIDSMessageToSendKey]); -} - -@end diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m deleted file mode 100644 index d3e0317a..00000000 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (c) 2012-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -#import -#import -#import - -#import -#import -#import -#import - -#include -#include -#include -#include -#include - -#import -#import - -#include -#include -#include - -#import "IDSPersistentState.h" -#import "KeychainSyncingOverIDSProxy+ReceiveMessage.h" -#import "KeychainSyncingOverIDSProxy+SendMessage.h" -#import "IDSProxy.h" - - -static NSString *const kIDSNumberOfFragments = @"NumberOfIDSMessageFragments"; -static NSString *const kIDSFragmentIndex = @"kFragmentIndex"; -static NSString *const kIDSMessageRecipientID = @"RecipientPeerID"; -static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; -static NSString *const kIDSMessageSendersDeviceID = @"SendersDeviceID"; - -@implementation KeychainSyncingOverIDSProxy (ReceiveMessage) - --(int) countNumberOfValidObjects:(NSMutableArray*)fragmentsForDeviceID -{ - __block int count = 0; - [fragmentsForDeviceID enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * _Nonnull stop) { - if(obj != [NSNull null]){ - count++; - } - }]; - return count; -} - --(BOOL) checkForFragmentation:(NSDictionary*)message id:(NSString*)fromID data:(NSData*)messageData -{ - BOOL handOffMessage = false; - - if([message valueForKey:kIDSNumberOfFragments] != nil){ - NSNumber *idsNumberOfFragments = [message objectForKey:kIDSNumberOfFragments]; - NSNumber *index = [message objectForKey:kIDSFragmentIndex]; - NSString *uuidString = [message objectForKey:(__bridge NSString*)kIDSMessageUniqueID]; - - if([KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages == nil) - [KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages = [NSMutableDictionary dictionary]; - - NSMutableDictionary *uniqueMessages = [[KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages objectForKey: fromID]; - if(uniqueMessages == nil) - uniqueMessages = [NSMutableDictionary dictionary]; - - NSMutableArray *fragmentsForDeviceID = [uniqueMessages objectForKey: uuidString]; - if(fragmentsForDeviceID == nil){ - fragmentsForDeviceID = [ [NSMutableArray alloc] initWithCapacity: [idsNumberOfFragments longValue]]; - for (int i = 0; i <[idsNumberOfFragments longValue] ; i++) { - [fragmentsForDeviceID addObject:[NSNull null]]; - } - } - - [fragmentsForDeviceID replaceObjectAtIndex: [index intValue] withObject:messageData ]; - [uniqueMessages setObject: fragmentsForDeviceID forKey:uuidString]; - [[KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages setObject:uniqueMessages forKey: fromID]; - - if([self countNumberOfValidObjects:fragmentsForDeviceID] == [idsNumberOfFragments longValue]) - handOffMessage = true; - else - handOffMessage = false; - - } - else //no fragmentation in the message, ready to hand off to securityd - handOffMessage = true; - - return handOffMessage; - -} - --(NSMutableDictionary*) combineMessage:(NSString*)ID peerID:(NSString*)peerID uuid:(NSString*)uuid -{ - NSString *dataKey = [ NSString stringWithUTF8String: kMessageKeyIDSDataMessage ]; - NSString *deviceIDKey = [ NSString stringWithUTF8String: kMessageKeyDeviceID ]; - NSString *peerIDKey = [ NSString stringWithUTF8String: kMessageKeyPeerID ]; - - NSMutableDictionary *arrayOfFragmentedMessagesByUUID = [[KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages objectForKey:ID]; - NSMutableArray *messagesForUUID = [arrayOfFragmentedMessagesByUUID objectForKey:uuid]; - NSMutableData* completeMessage = [NSMutableData data]; - - [messagesForUUID enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - NSData *messageFragment = (NSData*)obj; - - [completeMessage appendData: messageFragment]; - }]; - //we've combined the message, now remove it from the fragmented messages dictionary - [arrayOfFragmentedMessagesByUUID removeObjectForKey:uuid]; - - return [NSMutableDictionary dictionaryWithObjectsAndKeys: completeMessage, dataKey, ID, deviceIDKey, peerID, peerIDKey, nil]; -} - --(void) handleTestMessage:(NSString*)operation id:(NSString*)ID messageID:(NSString*)uniqueID senderPeerID:(NSString*)senderPeerID -{ - int operationType = [operation intValue]; - switch(operationType){ - case kIDSPeerAvailabilityDone: - { - //set current timestamp to indicate success! - [self.peerNextSendCache setObject:[NSDate date] forKey:ID]; - - secnotice("IDS Transport","!received availability response!: %@", ID); - notify_post(kSOSCCPeerAvailable); - break; - } - case kIDSEndPingTestMessage: - secnotice("IDS Transport","received pong message from other device: %@, ping test PASSED", ID); - break; - case kIDSSendOneMessage: - secnotice("IDS Transport","received ping test message, dropping on the floor now"); - break; - - case kIDSPeerAvailability: - case kIDSStartPingTestMessage: - { - char* messageCharS; - if(operationType == kIDSPeerAvailability){ - secnotice("IDS Transport","Received Availability Message from:%@!", ID); - asprintf(&messageCharS, "%d",kIDSPeerAvailabilityDone); - } - else{ - secnotice("IDS Transport","Received PingTest Message from: %@!", ID); - asprintf(&messageCharS, "%d", kIDSEndPingTestMessage); - } - - NSString *operationString = [[NSString alloc] initWithUTF8String:messageCharS]; - NSString* messageString = @"peer availability check finished"; - NSDictionary* messsageDictionary = @{(__bridge NSString*)kIDSOperationType:operationString, (__bridge NSString*)kIDSMessageToSendKey:messageString}; - - // We can always hold on to a message and our remote peers would bother everyone - [self sendIDSMessage:messsageDictionary name:ID peer:@"me" senderDeviceID:NULL]; - - free(messageCharS); - - break; - } - case kIDSPeerReceivedACK: - { - //set current timestamp to indicate success! - [self.peerNextSendCache setObject:[[NSDate alloc] init] forKey:ID]; - - //cancel timer! - secnotice("IDS Transport", "received ack for: %@", uniqueID); - dispatch_async(self.pingQueue, ^{ - //remove timer for message id - dispatch_source_t timer = [[KeychainSyncingOverIDSProxy idsProxy].pingTimers objectForKey:uniqueID]; - if(timer != nil){ - dispatch_cancel(timer); - [[KeychainSyncingOverIDSProxy idsProxy].pingTimers removeObjectForKey:uniqueID]; - dispatch_sync(self.dataQueue, ^{ - [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight removeObjectForKey:uniqueID]; - }); - [[KeychainSyncingOverIDSProxy idsProxy] persistState]; - } - }); - //call out to securityd to set a NULL - [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) { - - CFErrorRef localError = NULL; - SOSCCClearPeerMessageKeyInKVS((__bridge CFStringRef)senderPeerID, &localError); - return NULL; - }]; - break; - } - default: - break; - } -} - -- (void)sendACK:(NSString*)ID peerID:(NSString*)sendersPeerID uniqueID:(NSString*)uniqueID senderDeviceID:(NSString*)senderDeviceID -{ - char* messageCharS; - NSString* messageString = @"ACK"; - - asprintf(&messageCharS, "%d",kIDSPeerReceivedACK); - NSString *operationString = [[NSString alloc] initWithUTF8String:messageCharS]; - - NSDictionary* messageDictionary = @{(__bridge NSString*)kIDSOperationType:operationString, (__bridge NSString*)kIDSMessageToSendKey:messageString, (__bridge NSString*)kIDSMessageUniqueID:uniqueID}; - - [self sendIDSMessage:messageDictionary name:ID peer:sendersPeerID senderDeviceID:senderDeviceID]; - - free(messageCharS); - -} - -- (void)updateDeviceList -{ - self.deviceIDFromAuthToken = nil; - self.deviceIDFromAuthToken = [NSMutableDictionary dictionary]; - [self calloutWith:^(NSMutableDictionary *pending, bool handlePendingMesssages, bool doSetDeviceID, dispatch_queue_t queue, void(^done)(NSMutableDictionary *, bool, bool)) { - }]; -} -- (void)service:(IDSService *)service account:(IDSAccount *)account incomingMessage:(NSDictionary *)message fromID:(NSString *)fromID context:(IDSMessageContext *)context -{ - NSString *dataKey = [ NSString stringWithUTF8String: kMessageKeyIDSDataMessage ]; - NSString *deviceIDKey = [ NSString stringWithUTF8String: kMessageKeyDeviceID ]; - NSString *peerIDKey = [ NSString stringWithUTF8String: kMessageKeyPeerID ]; - NSString *sendersPeerIDKey = [NSString stringWithUTF8String: kMessageKeySendersPeerID]; - - [KeychainSyncingOverIDSProxy idsProxy].incomingMessages++; - - dispatch_async(self.calloutQueue, ^{ - NSString* messageID = nil; - uint32_t operationType; - bool hadError = false; - CFStringRef errorMessage = NULL; - __block NSString* myPeerID = @""; - __block NSData *messageData = nil; - NSString* operationTypeAsString = nil; - NSMutableDictionary *messageDictionary = nil; - NSString *useAck = nil; - NSString *senderDeviceID = nil; - NSArray *devices = [self->_service devices]; - for(NSUInteger i = 0; i < [ devices count ]; i++){ - IDSDevice *device = devices[i]; - if( [(IDSCopyIDForDevice(device)) containsString: fromID] == YES){ - senderDeviceID = device.uniqueID; - break; - } - } - [[KeychainSyncingOverIDSProxy idsProxy] printMessage:message state:[NSString stringWithFormat:@"received message from: %@", senderDeviceID]]; - NSString *sendersPeerID = [message objectForKey: sendersPeerIDKey]; - - if(sendersPeerID == nil) - sendersPeerID = [NSString string]; - - if(!senderDeviceID){ - senderDeviceID = message[kIDSMessageSendersDeviceID]; - secnotice("IDS Transport", "Their device ID!: %@", senderDeviceID); - } - require_action_quiet(senderDeviceID, fail, hadError = true; errorMessage = CFSTR("require the sender's device ID")); - - operationTypeAsString = [message objectForKey: (__bridge NSString*)kIDSOperationType]; - messageDictionary = [message objectForKey: (__bridge NSString*)kIDSMessageToSendKey]; - - messageID = [message objectForKey:(__bridge NSString*)kIDSMessageUniqueID]; - useAck = [message objectForKey:kIDSMessageUseACKModel]; - - if(useAck != nil && [useAck compare:@"YES"] == NSOrderedSame) - require_quiet(messageID != nil, fail); - - secnotice("IDS Transport","from peer %@, operation: %@", senderDeviceID, operationTypeAsString); - operationType = [operationTypeAsString intValue]; - - if(operationType != kIDSKeychainSyncIDSFragmentation) - { - [self handleTestMessage:operationTypeAsString id:senderDeviceID messageID:messageID senderPeerID:sendersPeerID]; - } - else{ - - [messageDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { - myPeerID = (NSString*)key; - messageData = (NSData*)obj; - }]; - - BOOL readyToHandOffToSecD = [self checkForFragmentation:message id:senderDeviceID data:messageData]; - - NSMutableDictionary *messageAndFromID = nil; - - if(readyToHandOffToSecD && ([message objectForKey:kIDSFragmentIndex])!= nil){ - secnotice("IDS Transport", "combing message"); - NSString* uuid = [message objectForKey:(__bridge NSString*)kIDSMessageUniqueID]; - messageAndFromID = [self combineMessage:senderDeviceID peerID:myPeerID uuid:uuid]; - //update next sequence number - } - else if(readyToHandOffToSecD){ - messageAndFromID = [NSMutableDictionary dictionaryWithObjectsAndKeys: messageData, dataKey, senderDeviceID, deviceIDKey, myPeerID, peerIDKey, nil]; - } - else - return; - - //set the sender's peer id so we can check it in securityd - [messageAndFromID setObject:sendersPeerID forKey:sendersPeerIDKey]; - - if([KeychainSyncingOverIDSProxy idsProxy].isLocked){ - //hang on to the message and set the retry deadline - dispatch_sync(self.dataQueue, ^{ - [self.unhandledMessageBuffer setObject: messageAndFromID forKey: fromID]; - }); - } - else{ - [self sendMessageToSecurity:messageAndFromID fromID:fromID shouldSendAck:useAck peerID:myPeerID messageID:messageID deviceID:senderDeviceID]; - - } - } - - fail: - if(hadError) - secerror("error:%@", errorMessage); - }); -} - - -- (void) handleAllPendingMessage -{ - secnotice("IDS Transport", "Attempting to handle pending messsages"); - - NSMutableDictionary * __block copyOfUnhandled = nil; - dispatch_sync(self.dataQueue, ^{ - if ([self.unhandledMessageBuffer count] > 0) { - secnotice("IDS Transport", "handling messages: %@", self.unhandledMessageBuffer); - copyOfUnhandled = [NSMutableDictionary dictionaryWithDictionary:self.unhandledMessageBuffer]; - } - }); - - [copyOfUnhandled enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) - { - NSMutableDictionary *messageAndFromID = (NSMutableDictionary*)obj; - NSString *fromID = (NSString*)key; - //remove the message from the official message buffer (if it fails to get handled it'll be reset again in sendMessageToSecurity) - dispatch_sync(self.dataQueue, ^{ - [self.unhandledMessageBuffer removeObjectForKey: fromID]; - }); - [self sendMessageToSecurity:messageAndFromID fromID:fromID shouldSendAck:nil peerID:nil messageID:nil deviceID:nil]; - }]; -} - -- (bool) shouldPersistMessage:(NSDictionary*) newMessageAndFromID id:(NSString*)fromID -{ - //get the dictionary of messages for a particular device id - NSDictionary* __block messagesFromBuffer; - dispatch_sync(self.dataQueue, ^{ - messagesFromBuffer = [self.unhandledMessageBuffer valueForKey:fromID]; - }); - - if([messagesFromBuffer isEqual:newMessageAndFromID]) - return false; - - return true; -} - --(void)sendMessageToSecurity:(NSMutableDictionary*)messageAndFromID fromID:(NSString*)fromID shouldSendAck:(NSString *)useAck peerID:(NSString*)peerID messageID:(NSString*)messageID deviceID:(NSString*)senderDeviceID -{ - __block CFErrorRef cf_error = NULL; - __block HandleIDSMessageReason success = kHandleIDSMessageSuccess; - - [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) { - - success = SOSCCHandleIDSMessage(((__bridge CFDictionaryRef)messageAndFromID), &cf_error); - //turns out the error needs to be evaluated as sync_and_do returns bools - if(cf_error != NULL) - { - if(CFErrorIsMalfunctioningKeybagError(cf_error)){ - success = kHandleIDSMessageLocked; - } - } - - if(success == kHandleIDSMessageLocked){ - secnotice("IDS Transport","cannot handle messages from: %@ when locked, error:%@", fromID, cf_error); - // I don't think this is ever nil but it was like this when I got here - dispatch_sync(self.dataQueue, ^{ - if(!self.unhandledMessageBuffer) { - self.unhandledMessageBuffer = [NSMutableDictionary dictionary]; - } - }); - - //write message to disk if message is new to the unhandled queue - if([self shouldPersistMessage:messageAndFromID id:fromID]) { - [self persistState]; - } - - dispatch_sync(self.dataQueue, ^{ - [self.unhandledMessageBuffer setObject: messageAndFromID forKey: fromID]; - secnotice("IDS Transport", "unhandledMessageBuffer: %@", self.unhandledMessageBuffer); - }); - - return NULL; - } - else if(success == kHandleIDSMessageNotReady){ - secnotice("IDS Transport","not ready to handle message from: %@, error:%@", fromID, cf_error); - dispatch_sync(self.dataQueue, ^{ - if(!self.unhandledMessageBuffer) { - self.unhandledMessageBuffer = [NSMutableDictionary dictionary]; - } - [self.unhandledMessageBuffer setObject: messageAndFromID forKey: fromID]; - secnotice("IDS Transport","unhandledMessageBuffer: %@", self.unhandledMessageBuffer); - }); - //write message to disk if message is new to the unhandled queue - if([self shouldPersistMessage:messageAndFromID id:fromID]) - [self persistState]; - - [[KeychainSyncingOverIDSProxy idsProxy] scheduleRetryRequestTimer]; - return NULL; - } - else if(success == kHandleIDSmessageDeviceIDMismatch){ - secnotice("IDS Transport","message for a ghost! dropping message. error:%@", cf_error); - return NULL; - } - else if(success == kHandleIDSMessageDontHandle){ - secnotice("IDS Transport","error in message, dropping message. error:%@", cf_error); - return NULL; - } - else{ - secnotice("IDS Transport","IDSProxy handled this message %@, from: %@", messageAndFromID, fromID); - - if(useAck != nil && [useAck compare:@"YES"] == NSOrderedSame) - [self sendACK:senderDeviceID peerID:peerID uniqueID:messageID senderDeviceID:senderDeviceID]; - return (NSMutableDictionary*)messageAndFromID; - } - - CFReleaseNull(cf_error); - }]; -} - -@end diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m deleted file mode 100644 index dd382a3b..00000000 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (c) 2012-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -#import -#import - -#import -#import -#import -#import - -#include -#include -#include -#include - -#import -#import - -#include -#include -#include -#include - -#import "IDSProxy.h" -#import "IDSPersistentState.h" -#import "KeychainSyncingOverIDSProxy+SendMessage.h" -#include - - -static NSString *const IDSSendMessageOptionForceEncryptionOffKey = @"IDSSendMessageOptionForceEncryptionOff"; - -static NSString *const kIDSNumberOfFragments = @"NumberOfIDSMessageFragments"; -static NSString *const kIDSFragmentIndex = @"kFragmentIndex"; -static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; -static NSString *const kIDSMessageSendersDeviceID = @"SendersDeviceID"; - -static NSString *const kIDSDeviceID = @"deviceID"; -static const int64_t kRetryTimerLeeway = (NSEC_PER_MSEC * 250); // 250ms leeway for handling unhandled messages. -static const int64_t timeout = 5ull; -static const int64_t KVS_BACKOFF = 5; - -static const NSUInteger kMaxIDSMessagePayloadSize = 64000; - -@implementation KeychainSyncingOverIDSProxy (SendMessage) - --(bool) chunkAndSendKeychainPayload:(NSData*)keychainData deviceID:(NSString*)deviceName ourPeerID:(NSString*)ourPeerID theirPeerID:(NSString*) theirPeerID operation:(NSString*)operationTypeAsString uuid:(NSString*)uuidString senderDeviceID:(NSString*)senderDeviceID - error:(NSError**) error -{ - __block BOOL result = true; - - NSUInteger keychainDataLength = [keychainData length]; - int fragmentIndex = 0; - int startingPosition = 0; - - NSUInteger totalNumberOfFragments = (keychainDataLength + kMaxIDSMessagePayloadSize - 1)/kMaxIDSMessagePayloadSize; - secnotice("IDS Transport", "sending %lu number of fragments to: %@", (unsigned long)totalNumberOfFragments, deviceName); - NSMutableDictionary* fragmentDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys: - deviceName, kIDSDeviceID, - [NSNumber numberWithUnsignedInteger:totalNumberOfFragments], kIDSNumberOfFragments, - [NSNumber numberWithInt:fragmentIndex], kIDSFragmentIndex, - deviceName, kIDSMessageRecipientDeviceID, theirPeerID, kIDSMessageRecipientPeerID, - operationTypeAsString, kIDSOperationType, - uuidString, kIDSMessageUniqueID, - nil]; - - NSUInteger remainingLength = keychainDataLength; - while(remainingLength > 0 && result == true){ - NSUInteger fragmentLength = MIN(remainingLength, kMaxIDSMessagePayloadSize); - NSData *fragment = [keychainData subdataWithRange:NSMakeRange(startingPosition, fragmentLength)]; - - // Insert the current fragment data in dictionary with key peerID and message key. - [fragmentDictionary setObject:@{theirPeerID:fragment} - forKey:(__bridge NSString*)kIDSMessageToSendKey]; - // Insert the fragment number in the dictionary - [fragmentDictionary setObject:[NSNumber numberWithInt:fragmentIndex] - forKey:kIDSFragmentIndex]; - - result = [self sendIDSMessage:fragmentDictionary name:deviceName peer:ourPeerID senderDeviceID:senderDeviceID]; - if(!result) - secerror("Could not send fragmented message"); - - startingPosition+=fragmentLength; - remainingLength-=fragmentLength; - fragmentIndex++; - } - - return result; -} - -- (void)sendToKVS: (NSString*) theirPeerID message: (NSData*) message -{ - [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) { - CFErrorRef cf_error = NULL; - - bool success = SOSCCRequestSyncWithPeerOverKVS(((__bridge CFStringRef)theirPeerID), (__bridge CFDataRef)message, &cf_error); - - if(success){ - secnotice("IDS Transport", "rerouting message %@", message); - } - else{ - secerror("could not route message to %@, error: %@", theirPeerID, cf_error); - } - - CFReleaseNull(cf_error); - return NULL; - }]; -} - -- (void) sendMessageToKVS: (NSDictionary*) encapsulatedKeychainMessage -{ - SecADAddValueForScalarKey(CFSTR("com.apple.security.sos.kvsreroute"), 1); - [encapsulatedKeychainMessage enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - if ([key isKindOfClass: [NSString class]] && [obj isKindOfClass:[NSData class]]) { - [self sendToKVS:key message:obj]; - } else { - secerror("Couldn't send to KVS key: %@ obj: %@", key, obj); - } - }]; -} - - -- (void)pingTimerFired:(NSString*)IDSid peerID:(NSString*)peerID identifier:(NSString*)identifier -{ - //setting next time to send - [self updateNextTimeToSendFor5Minutes:IDSid]; - - secnotice("IDS Transport", "device ID: %@ !!!!!!!!!!!!!!!!Ping timeout is up!!!!!!!!!!!!", IDSid); - //call securityd to sync with device over KVS - __block CFErrorRef cf_error = NULL; - __block bool success = kHandleIDSMessageSuccess; - - //cleanup timers - dispatch_async(self.pingQueue, ^{ - dispatch_source_t timer = [[KeychainSyncingOverIDSProxy idsProxy].pingTimers objectForKey:IDSid]; //remove timer - dispatch_cancel(timer); //cancel timer - [[KeychainSyncingOverIDSProxy idsProxy].pingTimers removeObjectForKey:IDSid]; - }); - - [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) { - - success = SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(((__bridge CFStringRef)IDSid), &cf_error); - - if(success){ - secnotice("IDS Transport", "rerouting message for %@", peerID); - } - else{ - secerror("Could not hand peerID: %@ to securityd, error: %@", IDSid, cf_error); - } - - return NULL; - }]; - CFReleaseSafe(cf_error); -} - --(void) pingDevices:(NSArray*)list peerID:(NSString*)peerID -{ - NSDictionary *messageDictionary = @{(__bridge NSString*)kIDSOperationType : [NSString stringWithFormat:@"%d", kIDSPeerAvailability], (__bridge NSString*)kIDSMessageToSendKey : @"checking peers"}; - - [list enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * top) { - NSString* IDSid = (NSString*)obj; - NSString* identifier = [NSString string]; - bool result = false; - secnotice("IDS Transport", "sending to id: %@", IDSid); - - result = [self sendIDSMessage:messageDictionary name:IDSid peer:peerID senderDeviceID:[NSString string]]; - - if(!result){ - secerror("Could not send message over IDS"); - [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) { - CFErrorRef kvsError = nil; - bool success = SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(((__bridge CFStringRef)IDSid), &kvsError); - - if(success){ - secnotice("IDS Transport", "sent peerID: %@ to securityd to sync over KVS", IDSid); - } - else{ - secerror("Could not hand peerID: %@ to securityd, error: %@", IDSid, kvsError); - } - CFReleaseNull(kvsError); - return NULL; - }]; - } - else{ - dispatch_async(self.pingQueue, ^{ - //create a timer! - if( [self.pingTimers objectForKey:IDSid] == nil){ - dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); - dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, kRetryTimerLeeway); - dispatch_source_set_event_handler(timer, ^{ - [self pingTimerFired:IDSid peerID:peerID identifier:identifier]; - }); - dispatch_resume(timer); - - [self.pingTimers setObject:timer forKey:IDSid]; - } - }); - } - }]; -} - --(BOOL) shouldProxySendMessage:(NSString*)deviceName -{ - BOOL result = false; - - //checking peer cache to see if the message should be sent over IDS or back to KVS - if(self.peerNextSendCache == nil) - { - self.peerNextSendCache = [[NSMutableDictionary alloc]initWithCapacity:0]; - } - NSDate *nextTimeToSend = [self.peerNextSendCache objectForKey:deviceName]; - if(nextTimeToSend != nil) - { - //check if the timestamp is stale or set sometime in the future - NSDate *currentTime = [[NSDate alloc] init]; - //if the current time is greater than the next time to send -> time to send! - if([[nextTimeToSend laterDate:currentTime] isEqual:currentTime]){ - result = true; - } - } - else{ //next time to send is not set yet - result = true; - } - return result; -} - --(BOOL) isMessageAPing:(NSDictionary*)data -{ - NSDictionary *messageDictionary = [data objectForKey: (__bridge NSString*)kIDSMessageToSendKey]; - BOOL isPingMessage = false; - - if(messageDictionary && ![messageDictionary isKindOfClass:[NSDictionary class]]) - { - NSString* messageString = [data objectForKey: (__bridge NSString*)kIDSMessageToSendKey]; - if(messageString && [messageString isKindOfClass:[NSString class]]) - isPingMessage = true; - } - else if(!messageDictionary){ - secerror("IDS Transport: message is null?"); - } - - return isPingMessage; -} - --(BOOL) sendFragmentedIDSMessages:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) ourPeerID senderDeviceID:(NSString*)senderDeviceID error:(NSError**) error -{ - BOOL result = false; - BOOL isPingMessage = false; - - NSError* localError = nil; - - NSString* operationTypeAsString = [data objectForKey: (__bridge NSString*)kIDSOperationType]; - NSMutableDictionary *messageDictionary = [data objectForKey: (__bridge NSString*)kIDSMessageToSendKey]; - - isPingMessage = [self isMessageAPing:data]; - - //check the peer cache for the next time to send timestamp - //if the timestamp is set in the future, reroute the message to KVS - //otherwise send the message over IDS - if(![self shouldProxySendMessage:deviceName] && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack) - { - if(isPingMessage){ - secnotice("IDS Transport", "peer negative cache check: peer cannot send yet. not sending ping message"); - return true; - } - else{ - [self sendMessageToKVS:messageDictionary]; - return true; - } - } - - if(isPingMessage){ //foward the ping message, no processing - result = [self sendIDSMessage:data - name:deviceName - peer:ourPeerID - senderDeviceID:senderDeviceID]; - if(!result){ - secerror("Could not send ping message"); - } - return result; - } - - NSString *localMessageIdentifier = [[NSUUID UUID] UUIDString]; - - bool fragment = [operationTypeAsString intValue] == kIDSKeychainSyncIDSFragmentation; - bool useAckModel = fragment && [[data objectForKey:kIDSMessageUseACKModel] compare: @"YES"] == NSOrderedSame; - - __block NSData *keychainData = nil; - __block NSString *theirPeerID = nil; - - [messageDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { - if ([key isKindOfClass:[NSString class]] && [obj isKindOfClass:[NSData class]]) { - theirPeerID = (NSString*)key; - keychainData = (NSData*)obj; - } - *stop = YES; - }]; - - if(fragment && keychainData && [keychainData length] >= kMaxIDSMessagePayloadSize){ - secnotice("IDS Transport","sending chunked keychain messages"); - result = [self chunkAndSendKeychainPayload:keychainData - deviceID:deviceName - ourPeerID:ourPeerID - theirPeerID:theirPeerID - operation:operationTypeAsString - uuid:localMessageIdentifier - senderDeviceID:senderDeviceID - error:&localError]; - } - else{ - NSMutableDictionary* dataCopy = [NSMutableDictionary dictionaryWithDictionary:data]; - [dataCopy setObject:localMessageIdentifier forKey:(__bridge NSString*)kIDSMessageUniqueID]; - - result = [self sendIDSMessage:dataCopy - name:deviceName - peer:ourPeerID - senderDeviceID:senderDeviceID]; - } - - if(result && useAckModel && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack){ - secnotice("IDS Transport", "setting ack timer"); - [self setMessageTimer:localMessageIdentifier deviceID:deviceName message:data]; - } - - secnotice("IDS Transport","returning result: %d, error: %@", result, error ? *error : nil); - return result; -} - --(void) updateNextTimeToSendFor5Minutes:(NSString*)ID -{ - secnotice("IDS Transport", "Setting next time to send in 5 minutes for device: %@", ID); - - NSTimeInterval backOffInterval = (KVS_BACKOFF * 60); - NSDate *nextTimeToTransmit = [NSDate dateWithTimeInterval:backOffInterval sinceDate:[NSDate date]]; - - [self.peerNextSendCache setObject:nextTimeToTransmit forKey:ID]; -} - -- (void)ackTimerFired:(NSString*)identifier deviceID:(NSString*)ID -{ - secnotice("IDS Transport", "IDS device id: %@, Ping timeout is up for message identifier: %@", ID, identifier); - - //call securityd to sync with device over KVS - NSMutableDictionary * __block message; - dispatch_sync(self.dataQueue, ^{ - message = [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight objectForKey:identifier]; - [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight removeObjectForKey:identifier]; - }); - if(!message){ - return; - } - NSDictionary *mesageInFlight = [message objectForKey:(__bridge NSString*)kIDSMessageToSendKey]; - - [[KeychainSyncingOverIDSProxy idsProxy] printMessage:mesageInFlight state:@"timeout occured, rerouting to KVS"]; - - //cleanup timers - dispatch_async(self.pingQueue, ^{ - dispatch_source_t timer = [[KeychainSyncingOverIDSProxy idsProxy].pingTimers objectForKey:identifier]; //remove timer - if(timer != nil) - dispatch_cancel(timer); //cancel timer - [[KeychainSyncingOverIDSProxy idsProxy].pingTimers removeObjectForKey:identifier]; - }); - - [self sendMessageToKVS:mesageInFlight]; - - //setting next time to send - [self updateNextTimeToSendFor5Minutes:ID]; - - [[KeychainSyncingOverIDSProxy idsProxy] persistState]; -} - --(void) setMessageTimer:(NSString*)identifier deviceID:(NSString*)ID message:(NSDictionary*)message -{ - dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); - dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, kRetryTimerLeeway); - - dispatch_source_set_event_handler(timer, ^{ - [self ackTimerFired:identifier deviceID:ID]; - }); - dispatch_resume(timer); - //restructure message in flight - - - //set the timer for message id - dispatch_async(self.pingQueue, ^{ - [self.pingTimers setObject:timer forKey:identifier]; - }); - - dispatch_sync(self.dataQueue, ^{ - [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight setObject:message forKey:identifier]; - }); - [[KeychainSyncingOverIDSProxy idsProxy] persistState]; -} - -//had an immediate error, remove it from messages in flight, and immediately send it over KVS --(void) cleanupAfterHardIDSError:(NSDictionary*)data -{ - NSString *messageIdentifier = [data objectForKey:(__bridge NSString*)kIDSMessageUniqueID]; - NSMutableDictionary * __block messageToSendToKVS = nil; - - if(messageIdentifier != nil){ - secerror("removing message id: %@ from message timers", messageIdentifier); - dispatch_sync(self.dataQueue, ^{ - messageToSendToKVS = [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight objectForKey:messageIdentifier]; - [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight removeObjectForKey:messageIdentifier]; - }); - if(!messageToSendToKVS){ - secnotice("IDS Transport", "no message for identifier: %@", messageIdentifier); - return; - } - [[KeychainSyncingOverIDSProxy idsProxy] printMessage:messageToSendToKVS state:@"IDS rejected send, message rerouted to KVS"]; - - //cleanup timer for message - dispatch_async(self.pingQueue, ^{ - dispatch_source_t timer = [[KeychainSyncingOverIDSProxy idsProxy].pingTimers objectForKey:messageIdentifier]; //remove timer - if(timer) - dispatch_cancel(timer); //cancel timer - [[KeychainSyncingOverIDSProxy idsProxy].pingTimers removeObjectForKey:messageIdentifier]; - }); - } - - NSDictionary *messageInFlight = [messageToSendToKVS objectForKey:(__bridge NSString*)kIDSMessageToSendKey]; - - if([messageInFlight isKindOfClass:[NSDictionary class]]){ - [[KeychainSyncingOverIDSProxy idsProxy] printMessage:messageInFlight state:@"IDS rejected send, message rerouted to KVS"]; - [self sendMessageToKVS:messageInFlight]; - } -} - --(BOOL) sendIDSMessage:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) peerID senderDeviceID:(NSString*)senderDeviceID -{ - - if(!self->_service){ - secerror("Could not send message to peer: %@: IDS delegate uninitialized, can't use IDS to send this message", deviceName); - return NO; - } - - NSMutableDictionary *dataCopy = [NSMutableDictionary dictionaryWithDictionary: data]; - - __block NSString* senderDeviceIDCopy = nil; - if(senderDeviceID){ - senderDeviceIDCopy = [[NSString alloc]initWithString:senderDeviceID]; - } - else{ - secnotice("IDS Transport", "device id doesn't exist for peer:%@", peerID); - senderDeviceIDCopy = [NSString string]; - } - - dispatch_async(self.calloutQueue, ^{ - - IDSMessagePriority priority = IDSMessagePriorityHigh; - BOOL encryptionOff = YES; - NSString *sendersPeerIDKey = [ NSString stringWithUTF8String: kMessageKeySendersPeerID]; - - NSDictionary *options = @{IDSSendMessageOptionForceEncryptionOffKey : [NSNumber numberWithBool:encryptionOff] }; - - //set our peer id and a unique id for this message - [dataCopy setObject:peerID forKey:sendersPeerIDKey]; - [dataCopy setObject:senderDeviceIDCopy forKey:kIDSMessageSendersDeviceID]; - secnotice("IDS Transport","Our device Name: %@", senderDeviceID); - [[KeychainSyncingOverIDSProxy idsProxy] printMessage:dataCopy state:@"sending"]; - - NSDictionary *info; - NSInteger errorCode = 0; - NSUInteger numberOfDevices = 0; - NSString *errMessage = nil; - NSMutableSet *destinations = nil; - NSError *localError = nil; - NSString *identifier = nil; - IDSDevice *device = nil; - NSArray* listOfDevices = [self->_service devices]; - numberOfDevices = [listOfDevices count]; - - require_action_quiet(numberOfDevices > 0, fail, errorCode = kSecIDSErrorNotRegistered; errMessage=createErrorString(@"Could not send message to peer: %@: IDS devices are not registered yet", deviceName)); - secnotice("IDS Transport","List of devices: %@", [self->_service devices]); - - destinations = [NSMutableSet set]; - for(NSUInteger i = 0; i < numberOfDevices; i++){ - device = listOfDevices[i]; - if( [ deviceName compare:device.uniqueID ] == 0){ - [destinations addObject: IDSCopyIDForDevice(device)]; - } - } - require_action_quiet([destinations count] != 0, fail, errorCode = kSecIDSErrorCouldNotFindMatchingAuthToken; errMessage = createErrorString(@"Could not send message to peer: %@: IDS device ID for peer does not match any devices within an IDS Account", deviceName)); - - bool result = [self->_service sendMessage:dataCopy toDestinations:destinations priority:priority options:options identifier:&identifier error:&localError ] ; - - [KeychainSyncingOverIDSProxy idsProxy].outgoingMessages++; - require_action_quiet(localError == nil && result, fail, errorCode = kSecIDSErrorFailedToSend; errMessage = createErrorString(@"Had an error sending IDS message to peer: %@", deviceName)); - - [[KeychainSyncingOverIDSProxy idsProxy] printMessage:dataCopy state:@"sent!"]; - fail: - - if(errMessage != nil){ - info = [ NSDictionary dictionaryWithObjectsAndKeys:errMessage, NSLocalizedDescriptionKey, nil ]; - localError = [[NSError alloc] initWithDomain:@"com.apple.security.ids.error" code:errorCode userInfo:info ]; - secerror("%@", localError); - [self cleanupAfterHardIDSError: data]; - } - }); - - return YES; -} - -@end diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+Throttle.m b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+Throttle.m deleted file mode 100644 index 769adc8e..00000000 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+Throttle.m +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (c) 2012-2016 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@ - */ - - -#import -#import - -#import -#import -#import -#import - -#include -#include -#include -#include - -#import -#import - -#include -#include -#include - -#import "IDSPersistentState.h" -#import "KeychainSyncingOverIDSProxy+SendMessage.h" -#import "KeychainSyncingOverIDSProxy+Throttle.h" -#import - - -static NSString *kExportUnhandledMessages = @"UnhandledMessages"; -static NSString *kMonitorState = @"MonitorState"; - -static NSString *kMonitorPenaltyBoxKey = @"Penalty"; -static NSString *kMonitorMessageKey = @"Message"; -static NSString *kMonitorConsecutiveWrites = @"ConsecutiveWrites"; -static NSString *kMonitorLastWriteTimestamp = @"LastWriteTimestamp"; -static NSString *kMonitorMessageQueue = @"MessageQueue"; -static NSString *kMonitorPenaltyTimer = @"PenaltyTimer"; -static NSString *kMonitorDidWriteDuringPenalty = @"DidWriteDuringPenalty"; - -static NSString *kMonitorTimeTable = @"TimeTable"; -static NSString *kMonitorFirstMinute = @"AFirstMinute"; -static NSString *kMonitorSecondMinute = @"BSecondMinute"; -static NSString *kMonitorThirdMinute = @"CThirdMinute"; -static NSString *kMonitorFourthMinute = @"DFourthMinute"; -static NSString *kMonitorFifthMinute = @"EFifthMinute"; -static NSString *kMonitorWroteInTimeSlice = @"TimeSlice"; - -static int max_penalty_timeout = 32; -static int seconds_per_minute = 60; -static int queue_depth = 1; - -CFStringRef const IDSPAggdIncreaseThrottlingKey = CFSTR("com.apple.security.idsproxy.increasethrottle"); -CFStringRef const IDSPAggdDecreaseThrottlingKey = CFSTR("com.apple.security.idsproxy.decreasethrottle"); - -static const int64_t kRetryTimerLeeway = (NSEC_PER_MSEC * 250); // 250ms leeway for handling unhandled messages. - -@implementation KeychainSyncingOverIDSProxy (Throttle) - --(dispatch_source_t)setNewTimer:(int)timeout key:(NSString*)key deviceName:(NSString*)deviceName peerID:(NSString*)peerID -{ - - __block dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); - dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC * seconds_per_minute), DISPATCH_TIME_FOREVER, kRetryTimerLeeway); - dispatch_source_set_event_handler(timer, ^{ - [self penaltyTimerFired:key deviceName:deviceName peerID:peerID]; - }); - dispatch_resume(timer); - return timer; -} - --(void) increasePenalty:(NSNumber*)currentPenalty key:(NSString*)key keyEntry:(NSMutableDictionary**)keyEntry deviceName:(NSString*)deviceName peerID:(NSString*)peerID -{ - SecADAddValueForScalarKey((IDSPAggdIncreaseThrottlingKey), 1); - - secnotice("backoff", "increasing penalty!"); - int newPenalty = 0; - - if ([currentPenalty intValue] <= 0) - newPenalty = 1; - else - newPenalty = fmin([currentPenalty intValue]*2, max_penalty_timeout); - - secnotice("backoff", "key %@, waiting %d minutes long to send next messages", key, newPenalty); - - NSNumber* penalty_timeout = [[NSNumber alloc]initWithInt:newPenalty]; - dispatch_source_t existingTimer = [*keyEntry objectForKey:kMonitorPenaltyTimer]; - - if(existingTimer != nil){ - [*keyEntry removeObjectForKey:kMonitorPenaltyTimer]; - dispatch_suspend(existingTimer); - dispatch_source_set_timer(existingTimer,dispatch_time(DISPATCH_TIME_NOW, newPenalty * NSEC_PER_SEC * seconds_per_minute), DISPATCH_TIME_FOREVER, kRetryTimerLeeway); - dispatch_resume(existingTimer); - [*keyEntry setObject:existingTimer forKey:kMonitorPenaltyTimer]; - } - else{ - dispatch_source_t timer = [self setNewTimer:newPenalty key:key deviceName:deviceName peerID:peerID]; - [*keyEntry setObject:timer forKey:kMonitorPenaltyTimer]; - } - - [*keyEntry setObject:penalty_timeout forKey:kMonitorPenaltyBoxKey]; - [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:*keyEntry forKey:key]; -} - --(void) decreasePenalty:(NSNumber*)currentPenalty key:(NSString*)key keyEntry:(NSMutableDictionary**)keyEntry deviceName:(NSString*)deviceName peerID:(NSString*)peerID -{ - SecADAddValueForScalarKey((IDSPAggdDecreaseThrottlingKey), 1); - - int newPenalty = 0; - secnotice("backoff","decreasing penalty!"); - if([currentPenalty intValue] == 0 || [currentPenalty intValue] == 1) - newPenalty = 0; - else - newPenalty = [currentPenalty intValue]/2; - - secnotice("backoff","key %@, waiting %d minutes long to send next messages", key, newPenalty); - - NSNumber* penalty_timeout = [[NSNumber alloc]initWithInt:newPenalty]; - - dispatch_source_t existingTimer = [*keyEntry objectForKey:kMonitorPenaltyTimer]; - if(existingTimer != nil){ - [*keyEntry removeObjectForKey:kMonitorPenaltyTimer]; - dispatch_suspend(existingTimer); - if(newPenalty != 0){ - dispatch_source_set_timer(existingTimer,dispatch_time(DISPATCH_TIME_NOW, newPenalty * NSEC_PER_SEC * seconds_per_minute), DISPATCH_TIME_FOREVER, kRetryTimerLeeway); - dispatch_resume(existingTimer); - [*keyEntry setObject:existingTimer forKey:kMonitorPenaltyTimer]; - } - else{ - dispatch_resume(existingTimer); - dispatch_source_cancel(existingTimer); - } - } - else{ - if(newPenalty != 0){ - dispatch_source_t timer = [self setNewTimer:newPenalty key:key deviceName:deviceName peerID:peerID]; - [*keyEntry setObject:timer forKey:kMonitorPenaltyTimer]; - } - } - - [*keyEntry setObject:penalty_timeout forKey:kMonitorPenaltyBoxKey]; - [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:*keyEntry forKey:key]; - -} - -- (void)penaltyTimerFired:(NSString*)key deviceName:(NSString*)deviceName peerID:(NSString*)peerID -{ - secnotice("backoff", "key: %@, !!!!!!!!!!!!!!!!penalty timeout is up!!!!!!!!!!!!", key); - NSMutableDictionary *keyEntry = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:key]; - if(!keyEntry){ - [self initializeKeyEntry:key]; - keyEntry = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:key]; - } - NSMutableArray *queuedMessages = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:kMonitorMessageQueue]; - secnotice("backoff","key: %@, queuedMessages: %@", key, queuedMessages); - if(queuedMessages && [queuedMessages count] != 0){ - secnotice("backoff","key: %@, message queue not empty, writing to IDS!", key); - [queuedMessages enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { - NSError* error = nil; - NSDictionary* message = (NSDictionary*) obj; - [self sendFragmentedIDSMessages:message name:deviceName peer:peerID error:&error]; - }]; - - [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:[NSMutableArray array] forKey:kMonitorMessageQueue]; - } - //decrease timeout since we successfully wrote messages out - NSNumber *penalty_timeout = [keyEntry objectForKey:kMonitorPenaltyBoxKey]; - secnotice("backoff", "key: %@, current penalty timeout: %@", key, penalty_timeout); - - NSString* didWriteDuringTimeout = [keyEntry objectForKey:kMonitorDidWriteDuringPenalty]; - if( didWriteDuringTimeout && [didWriteDuringTimeout isEqualToString:@"YES"] ) - { - //increase timeout since we wrote during out penalty timeout - [self increasePenalty:penalty_timeout key:key keyEntry:&keyEntry deviceName:deviceName peerID:peerID]; - } - else{ - //decrease timeout since we successfully wrote messages out - [self decreasePenalty:penalty_timeout key:key keyEntry:&keyEntry deviceName:deviceName peerID:peerID]; - } - - //resetting the check - [keyEntry setObject: @"NO" forKey:kMonitorDidWriteDuringPenalty]; - - //recompute the timetable and number of consecutive writes to IDS - NSMutableDictionary *timetableForKey = [keyEntry objectForKey:kMonitorTimeTable]; - if(timetableForKey == nil){ - timetableForKey = [self initializeTimeTable:key]; - } - NSNumber *consecutiveWrites = [keyEntry objectForKey:kMonitorConsecutiveWrites]; - if(consecutiveWrites == nil){ - consecutiveWrites = [[NSNumber alloc] initWithInt:0]; - } - [self recordTimestampForAppropriateInterval:&timetableForKey key:key consecutiveWrites:&consecutiveWrites]; - - [keyEntry setObject:consecutiveWrites forKey:kMonitorConsecutiveWrites]; - [keyEntry setObject:timetableForKey forKey:kMonitorTimeTable]; - [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:keyEntry forKey:key]; - -} - --(NSMutableDictionary*)initializeTimeTable:(NSString*)key -{ - NSDate *currentTime = [NSDate date]; - NSMutableDictionary *firstMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute], kMonitorFirstMinute, @"YES", kMonitorWroteInTimeSlice, nil]; - NSMutableDictionary *secondMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute * 2],kMonitorSecondMinute, @"NO", kMonitorWroteInTimeSlice, nil]; - NSMutableDictionary *thirdMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute * 3], kMonitorThirdMinute, @"NO",kMonitorWroteInTimeSlice, nil]; - NSMutableDictionary *fourthMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute * 4],kMonitorFourthMinute, @"NO", kMonitorWroteInTimeSlice, nil]; - NSMutableDictionary *fifthMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute * 5], kMonitorFifthMinute, @"NO", kMonitorWroteInTimeSlice, nil]; - - NSMutableDictionary *timeTable = [NSMutableDictionary dictionaryWithObjectsAndKeys: firstMinute, kMonitorFirstMinute, - secondMinute, kMonitorSecondMinute, - thirdMinute, kMonitorThirdMinute, - fourthMinute, kMonitorFourthMinute, - fifthMinute, kMonitorFifthMinute, nil]; - return timeTable; -} - -- (void)initializeKeyEntry:(NSString*)key -{ - NSMutableDictionary *timeTable = [[KeychainSyncingOverIDSProxy idsProxy] initializeTimeTable:key]; - NSDate *currentTime = [NSDate date]; - - NSMutableDictionary *keyEntry = [NSMutableDictionary dictionaryWithObjectsAndKeys: key, kMonitorMessageKey, @0, kMonitorConsecutiveWrites, currentTime, kMonitorLastWriteTimestamp, @0, kMonitorPenaltyBoxKey, timeTable, kMonitorTimeTable,[NSMutableArray array], kMonitorMessageQueue, nil]; - - [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:keyEntry forKey:key]; - -} - -- (void)recordTimestampForAppropriateInterval:(NSMutableDictionary**)timeTable key:(NSString*)key consecutiveWrites:(NSNumber**)consecutiveWrites -{ - NSDate *currentTime = [NSDate date]; - __block int cWrites = [*consecutiveWrites intValue]; - __block BOOL foundTimeSlot = NO; - __block NSMutableDictionary *previousTable = nil; - - NSArray *sortedTimestampKeys = [[*timeTable allKeys] sortedArrayUsingSelector:@selector(compare:)]; - NSMutableDictionary* timeTableStrong = *timeTable; - - [sortedTimestampKeys enumerateObjectsUsingBlock:^(id arrayObject, NSUInteger idx, BOOL *stop) - { - if(foundTimeSlot == YES) - return; - - NSString *sortedKey = (NSString*)arrayObject; - - //grab the dictionary containing write information - //(date, boolean to check if a write occured in the timeslice, - NSMutableDictionary *minutesTable = [timeTableStrong objectForKey: sortedKey]; - if(minutesTable == nil) - minutesTable = [[KeychainSyncingOverIDSProxy idsProxy] initializeTimeTable:key]; - - NSString *minuteKey = (NSString*)sortedKey; - NSDate *timeStampForSlice = [minutesTable objectForKey:minuteKey]; - - if(timeStampForSlice && [timeStampForSlice compare:currentTime] == NSOrderedDescending){ - foundTimeSlot = YES; - NSString* written = [minutesTable objectForKey:kMonitorWroteInTimeSlice]; - //figure out if we have previously recorded a write in this time slice - if([written isEqualToString:@"NO"]){ - [minutesTable setObject:@"YES" forKey:kMonitorWroteInTimeSlice]; - if(previousTable != nil){ - //if we wrote in the previous time slice count the current time as in the consecutive write count - written = [previousTable objectForKey:kMonitorWroteInTimeSlice]; - if([written isEqualToString:@"YES"]){ - cWrites++; - } - else if ([written isEqualToString:@"NO"]){ - cWrites = 0; - } - } - } - return; - } - previousTable = minutesTable; - }]; - - if(foundTimeSlot == NO){ - //reset the time table - secnotice("backoff","didn't find a time slot, resetting the table"); - - //record if a write occured between the last time slice of - //the time table entries and now. - NSMutableDictionary *lastTable = [*timeTable objectForKey:kMonitorFifthMinute]; - NSDate *lastDate = [lastTable objectForKey:kMonitorFifthMinute]; - - if(lastDate && ((double)[currentTime timeIntervalSinceDate: lastDate] >= seconds_per_minute)){ - *consecutiveWrites = [[NSNumber alloc]initWithInt:0]; - } - else{ - NSString* written = [lastTable objectForKey:kMonitorWroteInTimeSlice]; - if(written && [written isEqualToString:@"YES"]){ - cWrites++; - *consecutiveWrites = [[NSNumber alloc]initWithInt:cWrites]; - } - else{ - *consecutiveWrites = [[NSNumber alloc]initWithInt:0]; - } - } - - *timeTable = [[KeychainSyncingOverIDSProxy idsProxy] initializeTimeTable:key]; - return; - } - *consecutiveWrites = [[NSNumber alloc]initWithInt:cWrites]; -} -- (void)recordTimestampOfWriteToIDS:(NSDictionary *)values deviceName:(NSString*)name peerID:(NSString*)peerid -{ - if([[KeychainSyncingOverIDSProxy idsProxy].monitor count] == 0){ - [values enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) - { - [self initializeKeyEntry: key]; - }]; - } - else{ - [values enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) - { - NSMutableDictionary *keyEntry = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:key]; - if(keyEntry == nil){ - [self initializeKeyEntry: key]; - } - else{ - NSNumber *penalty_timeout = [keyEntry objectForKey:kMonitorPenaltyBoxKey]; - NSDate *lastWriteTimestamp = [keyEntry objectForKey:kMonitorLastWriteTimestamp]; - NSMutableDictionary *timeTable = [keyEntry objectForKey: kMonitorTimeTable]; - NSNumber *existingWrites = [keyEntry objectForKey: kMonitorConsecutiveWrites]; - NSDate *currentTime = [NSDate date]; - - //record the write happened in our timetable structure - [self recordTimestampForAppropriateInterval:&timeTable key:key consecutiveWrites:&existingWrites]; - - int consecutiveWrites = [existingWrites intValue]; - secnotice("backoff","consecutive writes: %d", consecutiveWrites); - [keyEntry setObject:existingWrites forKey:kMonitorConsecutiveWrites]; - [keyEntry setObject:timeTable forKey:kMonitorTimeTable]; - [keyEntry setObject:currentTime forKey:kMonitorLastWriteTimestamp]; - [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:keyEntry forKey:key]; - - if( (penalty_timeout && [penalty_timeout intValue] != 0 ) || ((double)[currentTime timeIntervalSinceDate: lastWriteTimestamp] <= 60 && consecutiveWrites >= 5)){ - - if( (penalty_timeout == nil || [penalty_timeout intValue] == 0) && consecutiveWrites == 5){ - secnotice("backoff","written for 5 consecutive minutes, time to start throttling"); - [self increasePenalty:penalty_timeout key:key keyEntry:&keyEntry deviceName:name peerID:peerid]; - } - else - secnotice("backoff","monitor: keys have been written for 5 or more minutes, recording we wrote during timeout"); - - //record we wrote during a timeout - [keyEntry setObject: @"YES" forKey:kMonitorDidWriteDuringPenalty]; - } - else if((double)[currentTime timeIntervalSinceDate: lastWriteTimestamp] <= 60 && consecutiveWrites < 5){ - //for debugging purposes - secnotice("backoff","monitor: still writing freely"); - [keyEntry setObject: @"NO" forKey:kMonitorDidWriteDuringPenalty]; - } - else if([penalty_timeout intValue] != 0 && ((double)[currentTime timeIntervalSinceDate: lastWriteTimestamp] > 60 && consecutiveWrites > 5) ){ - - //encountered a write even though we're in throttle mode - [keyEntry setObject: @"YES" forKey:kMonitorDidWriteDuringPenalty]; - } - } - }]; - } -} - -- (NSDictionary*)filterForWritableValues:(NSDictionary *)values -{ - secnotice("backoff", "filterForWritableValues: %@", values); - NSMutableDictionary *keyEntry_operationType = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:@"IDSMessageOperation"]; - - secnotice("backoff", "keyEntry_operationType: %@", keyEntry_operationType); - - NSNumber *penalty = [keyEntry_operationType objectForKey:kMonitorPenaltyBoxKey]; - - if(penalty && [penalty intValue] != 0){ - - NSMutableArray *queuedMessage = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:kMonitorMessageQueue]; - if(queuedMessage == nil) - queuedMessage = [[NSMutableArray alloc] initWithCapacity:queue_depth]; - - secnotice("backoff", "writing to queuedMessages: %@", queuedMessage); - - if([queuedMessage count] == 0) - [queuedMessage addObject:values]; - else - [queuedMessage replaceObjectAtIndex:(queue_depth-1) withObject: values]; - - [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:queuedMessage forKey:kMonitorMessageQueue]; - return NULL; - } - - return values; -} - -@end diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist deleted file mode 100644 index 325edc2d..00000000 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Application-Group - - InternetAccounts - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - - CFBundleIdentifier - com.apple.security.keychainsyncingoveridsproxy - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - ${CURRENT_PROJECT_VERSION} - LSBackgroundOnly - - NSHumanReadableCopyright - Copyright © 2013 Apple, Inc. All rights reserved. - - diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy.8 b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy.8 deleted file mode 100644 index 1dec9683..00000000 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy.8 +++ /dev/null @@ -1,9 +0,0 @@ -.Dd November 02, 2016 -.Dt KeychainSyncingOverIDSProxy 8 -.Os -.Sh NAME -.Nm KeychainSyncingOverIDSProxy -.Nd part of iCloud Keychain syncing. -.Sh DESCRIPTION -.Nm -part of iCloud Keychain syncing. diff --git a/KeychainSyncingOverIDSProxy/com.apple.private.alloy.keychainsync.plist b/KeychainSyncingOverIDSProxy/com.apple.private.alloy.keychainsync.plist deleted file mode 100644 index f08f2617b1ce77c9f0708dda9741267278cb8c15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 458 zcma)$O-{ow6ojA4Ut4}^V8H^|u|a~U3l7kzEcmS|wL+pz6&d@Ln7XkQJFT*3#Z5Q> z+=T@f;1r|~mPmP<(LBvJng^q#bJNsfa{ zfw7ZgiOKL>TBBIjVN<;CrZ(zpBY8* - - - - EnablePressuredExit - - EnvironmentVariables - - DEBUGSCOPE - all - WAIT4DEBUGGER - NO - - Label - com.apple.security.keychainsyncingoveridsproxy - LaunchEvents - - com.apple.notifyd.matching - - com.apple.mobile.keybagd.first_unlock - - Notification - com.apple.mobile.keybagd.first_unlock - - com.apple.mobile.keybagd.lock_status - - Notification - com.apple.mobile.keybagd.lock_status - - com.apple.keystore.lockstatus - - Notification - com.apple.keystore.lockstatus - - - - MachServices - - com.apple.private.alloy.keychainsync-idswake - - com.apple.security.keychainsyncingoveridsproxy - - - Program - /System/Library/Frameworks/Security.framework/KeychainSyncingOverIDSProxy.bundle/KeychainSyncingOverIDSProxy - ProgramArguments - - /System/Library/Frameworks/Security.framework/KeychainSyncingOverIDSProxy.bundle/KeychainSyncingOverIDSProxy - - enabletransactions - - - diff --git a/KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.osx.plist b/KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.osx.plist deleted file mode 100644 index dbdcaca5..00000000 --- a/KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.osx.plist +++ /dev/null @@ -1,43 +0,0 @@ - - - - - LaunchEvents - - com.apple.notifyd.matching - - com.apple.keystore.lockstatus - - Notification - com.apple.keystore.lockstatus - - - - Program - /System/Library/Frameworks/Security.framework/Versions/A/Resources/KeychainSyncingOverIDSProxy.bundle/Contents/MacOS/KeychainSyncingOverIDSProxy - Label - com.apple.security.keychainsyncingoveridsproxy - EnvironmentVariables - - DEBUGSCOPE - all - WAIT4DEBUGGER - NO - - ProcessType - Adaptive - MachServices - - com.apple.private.alloy.keychainsync-idswake - - com.apple.security.keychainsyncingoveridsproxy - - - ProgramArguments - - /System/Library/Frameworks/Security.framework/Versions/A/Resources/KeychainSyncingOverIDSProxy.bundle/Contents/MacOS/KeychainSyncingOverIDSProxy - - EnablePressuredExit - - - diff --git a/KeychainSyncingOverIDSProxy/en.lproj/InfoPlist.strings b/KeychainSyncingOverIDSProxy/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28ff..00000000 --- a/KeychainSyncingOverIDSProxy/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist b/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist deleted file mode 100644 index 14070f34..00000000 --- a/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - keychain-cloud-circle - - com.apple.wifi.manager-access - - com.apple.private.ids.remoteurlconnection - - com.apple.private.ids.force-encryption-off - - com.apple.private.alloy.keychainsync - - com.apple.private.ids.messaging.high-priority - - com.apple.private.alloy.keychainsync - - com.apple.private.ids.messaging - - com.apple.private.alloy.keychainsync - - keychain-access-groups - - apple - IMCore - InternetAccounts - - application-identifier - com.apple.security.keychainsyncingoveridsproxy - - diff --git a/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m b/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m deleted file mode 100644 index b045d443..00000000 --- a/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 2012-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@ - */ - -#include - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#include -#include -#include "SOSCloudKeychainConstants.h" -#import -#import "KeychainSyncingOverIDSProxy+SendMessage.h" - -int idsproxymain(int argc, const char *argv[]); - -#define PROXYXPCSCOPE "idsproxy" - -static void describeXPCObject(char *prefix, xpc_object_t object) -{ - // This is useful for debugging. - if (object) - { - char *desc = xpc_copy_description(object); - secdebug(PROXYXPCSCOPE, "%s%s\n", prefix, desc); - free(desc); - } - else - secdebug(PROXYXPCSCOPE, "%s\n", prefix); - -} - -static void idskeychainsyncingproxy_peer_dictionary_handler(const xpc_connection_t peer, xpc_object_t event) -{ - bool result = false; - int err = 0; - - require_action_string(xpc_get_type(event) == XPC_TYPE_DICTIONARY, xit, err = -51, "expected XPC_TYPE_DICTIONARY"); - - const char *operation = xpc_dictionary_get_string(event, kMessageKeyOperation); - require_action(operation, xit, result = false); - - // Check protocol version - uint64_t version = xpc_dictionary_get_uint64(event, kMessageKeyVersion); - secdebug(PROXYXPCSCOPE, "Reply version: %lld\n", version); - require_action(version == kCKDXPCVersion, xit, result = false); - - // Operations - secdebug(PROXYXPCSCOPE, "Handling %s operation", operation); - - - if(operation && !strcmp(operation, kOperationGetDeviceID)){ - [[KeychainSyncingOverIDSProxy idsProxy] doSetIDSDeviceID]; - xpc_object_t replyMessage = xpc_dictionary_create_reply(event); - xpc_dictionary_set_bool(replyMessage, kMessageKeyValue, true); - xpc_connection_send_message(peer, replyMessage); - secdebug(PROXYXPCSCOPE, "Set our IDS Device ID message sent"); - - } - else if(operation && !strcmp(operation, kOperationGetIDSPerfCounters)){ - NSDictionary *counters = [[KeychainSyncingOverIDSProxy idsProxy] collectStats]; - xpc_object_t xMessages = _CFXPCCreateXPCObjectFromCFObject((__bridge CFDictionaryRef)(counters)); - - xpc_object_t replyMessage = xpc_dictionary_create_reply(event); - xpc_dictionary_set_value(replyMessage, kMessageKeyValue, xMessages); - xpc_connection_send_message(peer, replyMessage); - secdebug(PROXYXPCSCOPE, "Retrieved counters"); - } - else if (operation && !strcmp(operation, kOperationGetPendingMesages)) - { - NSDictionary* messages = [[KeychainSyncingOverIDSProxy idsProxy] retrievePendingMessages]; - xpc_object_t xMessages = _CFXPCCreateXPCObjectFromCFObject((__bridge CFDictionaryRef)(messages)); - - xpc_object_t replyMessage = xpc_dictionary_create_reply(event); - xpc_dictionary_set_value(replyMessage, kMessageKeyValue, xMessages); - - xpc_connection_send_message(peer, replyMessage); - secdebug(PROXYXPCSCOPE, "retrieved pending messages"); - - } - else if(operation && !strcmp(operation, kOperationSendDeviceList)) //IDS device availability check - { - xpc_object_t xidsDeviceList = xpc_dictionary_get_value(event, kMessageKeyValue); - xpc_object_t xPeerID = xpc_dictionary_get_value(event, kMessageKeyPeerID); - - NSArray *idsList = (__bridge_transfer NSArray*)(_CFXPCCreateCFObjectFromXPCObject(xidsDeviceList)); - NSString *peerID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xPeerID)); - - bool isMessageArray = (CFGetTypeID((__bridge CFTypeRef)(idsList)) == CFArrayGetTypeID()); - bool isPeerIDString = (CFGetTypeID((__bridge CFTypeRef)(peerID)) == CFStringGetTypeID()); - - require_quiet(isMessageArray, xit); - require_quiet(isPeerIDString, xit); - - [[KeychainSyncingOverIDSProxy idsProxy] pingDevices:idsList peerID:peerID]; - - xpc_object_t replyMessage = xpc_dictionary_create_reply(event); - xpc_dictionary_set_bool(replyMessage, kMessageKeyValue, true); - - xpc_connection_send_message(peer, replyMessage); - secdebug(PROXYXPCSCOPE, "IDS device list sent"); - } - else if (operation && !strcmp(operation, kOperationSendFragmentedIDSMessage)) - { - xpc_object_t xidsMessageData = xpc_dictionary_get_value(event, kMessageKeyValue); - xpc_object_t xDeviceName = xpc_dictionary_get_value(event, kMessageKeyDeviceName); - xpc_object_t xPeerID = xpc_dictionary_get_value(event, kMessageKeyPeerID); - xpc_object_t xSenderDeviceID = xpc_dictionary_get_value(event, kMessageKeyDeviceID); - BOOL object = false; - - NSString *deviceName = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xDeviceName)); - NSString *peerID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xPeerID)); - NSDictionary *messageDictionary = (__bridge_transfer NSDictionary*)(_CFXPCCreateCFObjectFromXPCObject(xidsMessageData)); - NSString *senderDeviceID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xSenderDeviceID)); - - NSError *error = NULL; - bool isNameString = (CFGetTypeID((__bridge CFTypeRef)(deviceName)) == CFStringGetTypeID()); - bool isPeerIDString = (CFGetTypeID((__bridge CFTypeRef)(peerID)) == CFStringGetTypeID()); - bool isMessageDictionary = (CFGetTypeID((__bridge CFTypeRef)(messageDictionary)) == CFDictionaryGetTypeID()); - bool isDeviceIDString = (CFGetTypeID((__bridge CFTypeRef)(senderDeviceID)) == CFStringGetTypeID()); - - require_quiet(isNameString, xit); - require_quiet(isPeerIDString, xit); - require_quiet(isDeviceIDString, xit); - require_quiet(isMessageDictionary, xit); - - object = [[KeychainSyncingOverIDSProxy idsProxy] sendFragmentedIDSMessages:messageDictionary name:deviceName peer:peerID senderDeviceID:senderDeviceID error:&error]; - - xpc_object_t replyMessage = xpc_dictionary_create_reply(event); - xpc_dictionary_set_bool(replyMessage, kMessageKeyValue, object); - - if(error){ - xpc_object_t xerrobj = SecCreateXPCObjectWithCFError((__bridge CFErrorRef)(error)); - xpc_dictionary_set_value(replyMessage, kMessageKeyError, xerrobj); - } - xpc_connection_send_message(peer, replyMessage); - secdebug(PROXYXPCSCOPE, "IDS message sent"); - } - else if (operation && !strcmp(operation, kOperationSendIDSMessage)) //for IDS tests - { - xpc_object_t xidsMessageData = xpc_dictionary_get_value(event, kMessageKeyValue); - xpc_object_t xDeviceName = xpc_dictionary_get_value(event, kMessageKeyDeviceName); - xpc_object_t xPeerID = xpc_dictionary_get_value(event, kMessageKeyPeerID); - xpc_object_t xSenderDeviceID = xpc_dictionary_get_value(event, kMessageKeyDeviceID); - - BOOL object = false; - - NSString *deviceName = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xDeviceName)); - NSString *peerID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xPeerID)); - NSDictionary *messageDictionary = (__bridge_transfer NSDictionary*)(_CFXPCCreateCFObjectFromXPCObject(xidsMessageData)); - NSString *senderDeviceID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xSenderDeviceID)); - - CFErrorRef error = NULL; - bool isNameString = (CFGetTypeID((__bridge CFTypeRef)(deviceName)) == CFStringGetTypeID()); - bool isPeerIDString = (CFGetTypeID((__bridge CFTypeRef)(peerID)) == CFStringGetTypeID()); - bool isMessageDictionary = (CFGetTypeID((__bridge CFTypeRef)(messageDictionary)) == CFDictionaryGetTypeID()); - bool isDeviceIDString = (CFGetTypeID((__bridge CFTypeRef)(senderDeviceID)) == CFStringGetTypeID()); - - require_quiet(isNameString, xit); - require_quiet(isPeerIDString, xit); - require_quiet(isMessageDictionary, xit); - require_quiet(isDeviceIDString, xit); - - NSString *localMessageIdentifier = [[NSUUID UUID] UUIDString]; - NSMutableDictionary* messageDictionaryCopy = [NSMutableDictionary dictionaryWithDictionary:messageDictionary]; - - [messageDictionaryCopy setObject:localMessageIdentifier forKey:(__bridge NSString*)(kIDSMessageUniqueID)]; - - if([[KeychainSyncingOverIDSProxy idsProxy] sendIDSMessage:messageDictionaryCopy name:deviceName peer:peerID senderDeviceID:senderDeviceID]) - { - object = true; - NSString *useAckModel = [messageDictionaryCopy objectForKey:(__bridge NSString*)(kIDSMessageUsesAckModel)]; - if(object && [useAckModel compare:@"YES"] == NSOrderedSame && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack){ - secnotice("IDS Transport", "setting timer!"); - [[KeychainSyncingOverIDSProxy idsProxy] setMessageTimer:localMessageIdentifier deviceID:deviceName message:messageDictionaryCopy]; - } - } - else{ - SOSErrorCreate(kSecIDSErrorFailedToSend, &error, NULL, CFSTR("Failed to send keychain data message over IDS")); - secerror("Could not send message"); - } - - xpc_object_t replyMessage = xpc_dictionary_create_reply(event); - xpc_dictionary_set_bool(replyMessage, kMessageKeyValue, object); - - if(error){ - xpc_object_t xerrobj = SecCreateXPCObjectWithCFError(error); - xpc_dictionary_set_value(replyMessage, kMessageKeyError, xerrobj); - } - CFReleaseNull(error); - xpc_connection_send_message(peer, replyMessage); - secdebug(PROXYXPCSCOPE, "IDS message sent"); - } - - else - { - char *description = xpc_copy_description(event); - secdebug(PROXYXPCSCOPE, "Unknown op=%s request from pid %d: %s", operation, xpc_connection_get_pid(peer), description); - free(description); - } - result = true; -xit: - if (!result) - describeXPCObject("handle_operation fail: ", event); -} - -static void idskeychainsyncingproxy_peer_event_handler(xpc_connection_t peer, xpc_object_t event) -{ - xpc_type_t type = xpc_get_type(event); - if (type == XPC_TYPE_ERROR) { - if (event == XPC_ERROR_CONNECTION_INVALID) { - // The client process on the other end of the connection has either - // crashed or canceled the connection. After receiving this error, - // the connection is in an invalid state, and you do not need to - // call xpc_connection_cancel(). Just tear down any associated state - // here. - } else if (event == XPC_ERROR_TERMINATION_IMMINENT) { - // Handle per-connection termination cleanup. - } - } else { - assert(type == XPC_TYPE_DICTIONARY); - dispatch_async(dispatch_get_main_queue(), ^{ - idskeychainsyncingproxy_peer_dictionary_handler(peer, event); - }); - } -} - -static void idskeychainsyncingproxy_event_handler(xpc_connection_t peer) -{ - // By defaults, new connections will target the default dispatch - // concurrent queue. - - if (xpc_get_type(peer) != XPC_TYPE_CONNECTION) - { - secdebug(PROXYXPCSCOPE, "expected XPC_TYPE_CONNECTION"); - return; - } - - xpc_connection_set_event_handler(peer, ^(xpc_object_t event) - { - idskeychainsyncingproxy_peer_event_handler(peer, event); - }); - - // This will tell the connection to begin listening for events. If you - // have some other initialization that must be done asynchronously, then - // you can defer this call until after that initialization is done. - xpc_connection_resume(peer); -} - -static bool kvsFallbackFromDefaultsWrite(void) -{ - bool kvsFallbackEnabled = true; - - //defaults write ~/Library/Preferences/com.apple.security allowKVSFallback -bool - CFBooleanRef value = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("allowKVSFallback"), CFSTR("com.apple.security"), kCFPreferencesAnyUser, kCFPreferencesCurrentHost); - if ( value ) - { - kvsFallbackEnabled = CFBooleanGetValue(value); - CFReleaseNull(value); - } - return kvsFallbackEnabled; -} - -int idsproxymain(int argc, const char *argv[]) -{ - secdebug(PROXYXPCSCOPE, "Starting IDSProxy"); - char *wait4debugger = getenv("WAIT4DEBUGGER"); - - if (wait4debugger && !strcasecmp("YES", wait4debugger)) - { - syslog(LOG_ERR, "Waiting for debugger"); - kill(getpid(), SIGTSTP); - } - - // DISPATCH_TARGET_QUEUE_DEFAULT - xpc_connection_t listener = xpc_connection_create_mach_service(xpcIDSServiceName, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER); - xpc_connection_set_event_handler(listener, ^(xpc_object_t object){ idskeychainsyncingproxy_event_handler(object); }); - - [KeychainSyncingOverIDSProxy idsProxy]; - - if([[KeychainSyncingOverIDSProxy idsProxy] haveMessagesInFlight] && - [KeychainSyncingOverIDSProxy idsProxy].isIDSInitDone && - [KeychainSyncingOverIDSProxy idsProxy].sendRestoredMessages) { - [[KeychainSyncingOverIDSProxy idsProxy] sendPersistedMessagesAgain]; - [KeychainSyncingOverIDSProxy idsProxy].sendRestoredMessages = false; - } - - [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack = kvsFallbackFromDefaultsWrite(); - - // It looks to me like there is insufficient locking to allow a request to come in on the XPC connection while doing the initial all items. - // Therefore I'm leaving the XPC connection suspended until that has time to process. - xpc_connection_resume(listener); - - @autoreleasepool - { - secdebug(PROXYXPCSCOPE, "Starting mainRunLoop"); - NSRunLoop *runLoop = [NSRunLoop mainRunLoop]; - [runLoop run]; - } - - secdebug(PROXYXPCSCOPE, "Exiting KeychainSyncingOverIDSProxy"); - - return EXIT_FAILURE; -} - -int main(int argc, const char *argv[]) -{ - return idsproxymain(argc, argv); -} diff --git a/MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m b/MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m new file mode 100644 index 00000000..88c68f52 --- /dev/null +++ b/MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m @@ -0,0 +1,295 @@ +// +// ClientInfoByNotification.m +// Security +// +// Created by murf on 4/12/18. +// + +#import +#import +#import +#import +#include +#include + +#undef DOVIEWMACRO +#define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULTSETTING, INITIALSYNCSETTING, ALWAYSONSETTING, BACKUPSETTING, V0SETTING) \ +const CFStringRef k##SYSTEM##View##VIEWNAME = CFSTR(DEFSTRING); +#include "Security/SecureObjectSync/ViewList.list" + +#import "DeviceSimulatorProtocol.h" +#import "MultiDeviceNetworking.h" +#import + + +#if 1 +@interface MDDevice2 : NSObject +@property NSXPCConnection *connection; +@property NSString *name; +- (instancetype)initWithConnection:(NSXPCConnection *)connection; +@end + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wprotocol" +@implementation MDDevice2 + +- (instancetype)initWithConnection:(NSXPCConnection *)connection +{ + self = [super init]; + if (self) { + self.connection = connection; + } + return self; +} + +/* Oh, ObjC, you are my friend */ +- (void)forwardInvocation:(NSInvocation *)invocation +{ + struct objc_method_description desc = protocol_getMethodDescription(@protocol(DeviceSimulatorProtocol), [invocation selector], true, true); + if (desc.name == NULL) { + [super forwardInvocation:invocation]; + } else { + __block bool dooooooEeeeetExclamationPoint = true; + id object = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + NSLog(@"peer failed with: %@", error); + dooooooEeeeetExclamationPoint = false; + //abort(); + }]; + if(dooooooEeeeetExclamationPoint) { + [invocation invokeWithTarget:object]; + } + } +} +@end +#pragma clang diagnostic pop +#endif + +@interface ClientInfoByNotification : XCTestCase +@property NSMutableDictionary *connections; +@property MultiDeviceNetworking *network; +@property MDDevice2 *masterDevice; +@end + +static NSString *testInstanceUUID; + +@implementation ClientInfoByNotification + + ++ (void)setUp +{ + testInstanceUUID = [[NSUUID UUID] UUIDString]; +} + +- (void)setUp +{ + self.connections = [NSMutableDictionary dictionary]; + self.network = [[MultiDeviceNetworking alloc] init]; + [self runSigninWithAdditionalDevices:0]; +} + +- (void)tearDown +{ + __block uint64_t totalUserUsec = 0, totalSysUsec = 0; + NSMutableDictionary *result = [NSMutableDictionary dictionary]; + + for (NSString *name in self.connections) { + MDDevice2 *device = self.connections[name]; + NSLog(@"device: %@", name); + [device diagnosticsCPUUsage:^(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error) { + NSLog(@"%@: %d: u:%llu s:%llu", device.name, success, (unsigned long long)user_usec, (unsigned long long)sys_usec); + totalUserUsec += user_usec; + totalSysUsec += sys_usec; + result[[NSString stringWithFormat:@"cpu-%@", name]] = @{ @"user_usec" : @(user_usec), @"system_usec" : @(sys_usec)}; + }]; + } + + result[@"cpu-total"] = @{ @"user_usec" : @(totalUserUsec), @"system_usec" : @(totalSysUsec)}; + + NSLog(@"Total: u:%llu s:%llu", (unsigned long long)totalUserUsec, (unsigned long long)totalSysUsec); + + /* XXX check for leaks in all devices */ + for (NSString *name in self.connections) { + MDDevice2 *device = self.connections[name]; + [device.connection invalidate]; + } + self.connections = NULL; + [self.network dumpKVSState]; + [self.network dumpCounters]; + [self.network disconnectAll]; + self.network = NULL; + + NSData * jsonData = [NSJSONSerialization dataWithJSONObject:result options:0 error:NULL]; + + [jsonData writeToFile:[NSString stringWithFormat:@"/tmp/test-result-%@", [self name]] atomically:NO]; + +} + +//MARK: - Device logic + +- (MDDevice2 *)device:(NSString *)name model:(NSString *)model version:(NSString *)version +{ + MDDevice2 *device = self.connections[name]; + if (device != NULL) { + return NULL; + } + + NSXPCConnection *conn = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.Security.DeviceSimulator"]; + conn.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(DeviceSimulatorProtocol)]; + [conn _setUUID:[NSUUID UUID]]; // select a random instance + [conn resume]; + + device = [[MDDevice2 alloc] initWithConnection:conn]; + device.name = name; + + self.connections[name] = device; + + [device setDevice:name + version:version + model:model + testInstance:testInstanceUUID + network:[self.network endpoint] + complete:^(BOOL success) { + if (!success) { + abort(); + } + }]; + return device; +} + +- (void)runSigninWithAdditionalDevices:(unsigned)additionalDeviceCount { + signal(SIGPIPE, SIG_IGN); + _masterDevice = [self device:@"ipad" model:@"iPad" version:@"15E143a"]; + NSMutableArray *otherDevices = [NSMutableArray array]; + + [_masterDevice setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + }]; + + [_masterDevice sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error); + }]; + + sleep(4); // give "kvs" a chance to get the word out. + for (unsigned n = 0; n < additionalDeviceCount; n++) { + MDDevice2 *dev = [self device:[NSString stringWithFormat:@"mac-%u", n] model:@"Mac Pro" version:@"17E121"]; + + [dev setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) { + XCTAssert(success, "%u: Expect success: %@", n, error); + }]; + + __block NSString *devPeerID = NULL; + [dev sosRequestToJoin:^(bool success, NSString *peerID, NSError *error) { + XCTAssert(success, "%u: Expect success: %@", n, error); + XCTAssertNotEqual(peerID, NULL, @"%u: expected to find peerID for peer2", n); + devPeerID = peerID; + }]; + + __block NSError *localErr = nil; + __block bool done = false; + for(int tries=0; tries < 5; tries++) { + + [_masterDevice sosApprovePeer:devPeerID complete:^(BOOL success, NSError *error) { + localErr = [error copy]; + if(success) { + localErr = nil; + done = true; + } + }]; + if(done) break; + sleep(10); + } + XCTAssert(done, "%u: Expect success (for approve of %@): %@", n, devPeerID, localErr); + + [otherDevices addObject:dev]; + } +} + +- (void)testSOSIsThisDeviceInCircle +{ + [self measureBlock:^{ + for(int i=0; i<100; i++) { + [self.masterDevice sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error); + }]; + } + }]; +} + +- (void)testSOSIsThisDeviceInCircleNonCached +{ + [self measureBlock:^{ + for(int i=0; i<100; i++) { + [self.masterDevice sosCircleStatusNonCached:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error); + }]; + } + }]; +} + + +#if TARGET_OS_IPHONE +- (void)testSOSViews2 +{ + [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewAutofillPasswords withCompletion: ^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCViewNotMember, @"expected to be not in view: %@", error); + }]; + [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewHomeKit withCompletion: ^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCViewMember, @"expected to be in view: %@", error); + }]; + [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewWiFi withCompletion: ^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCViewNotMember, @"expected to be not in view: %@", error); + }]; + [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewContinuityUnlock withCompletion: ^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCViewMember, @"expected to be in view: %@", error); + }]; + + [self.masterDevice sosEnableAllViews:^(BOOL success, NSError *error) { + XCTAssert(success, "Expected to enable all views"); + }]; + + //uint64_t bitmask = [self.masterDevice sosCachedCircleBitmask]; + //XCTAssertEqual(bitmask, 0, "Expected bitmask to be %llx", bitmask); + + + [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewWiFi withCompletion: ^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCViewMember, @"expected to be in view: %@", error); + }]; + + [self.masterDevice sosCachedViewBitmask:^(uint64_t bitmask) { + XCTAssertEqual(bitmask, 33554367, @"expected bitmask of %llx", bitmask); + }]; + + [self measureBlock:^{ + for(int i=0; i<100; i++) { + [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewHomeKit withCompletion: ^void(SOSCCStatus status, NSError *error) { + }]; + } + }]; +} +#endif + + +- (void)testSOSMultiView +{ + [self.masterDevice sosEnableAllViews:^(BOOL success, NSError *error) { + XCTAssert(success, "Expected to enable all views"); + }]; + + [self.masterDevice sosICKStatus: ^void(bool status) { + XCTAssert(status, "Expected to enable iCloud Keychain"); + }]; + + [self measureBlock:^{ + for(int i=0; i<100; i++) { + [self.masterDevice sosICKStatus: ^void(bool status) { + }]; + } + }]; +} + +- (void) testMaster2 +{ + [self testSOSMultiView]; +} + +@end diff --git a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist new file mode 100644 index 00000000..c01f2ad5 --- /dev/null +++ b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist @@ -0,0 +1,64 @@ + + + + + com.apple.private.aps-connection-initiate + + aps-connection-initiate + + aps-environment + serverPreferred + com.apple.aps-environment + serverPreferred + com.apple.private.cloudkit.setEnvironment + + com.apple.developer.icloud-container-identifiers + + iCloud.com.apple.security.keychain + + com.apple.developer.icloud-services + + CloudKit + + com.apple.developer.icloud-container-environment + Development + com.apple.private.cloudkit.systemService + + com.apple.private.cloudkit.buddyAccess + + com.apple.private.appleaccount.app-hidden-from-icloud-settings + + com.apple.private.tcc.allow + + kTCCServiceLiverpool + + com.apple.application-identifier + com.apple.securityd + application-identifier + com.apple.securityd + com.apple.private.keychain.sysbound + + keychain-cloud-circle + + com.apple.keystore.access-keychain-keys + + com.apple.keystore.lockassertion + + com.apple.keystore.device + + modify-anchor-certificates + + com.apple.private.system-keychain + + keychain-access-groups + + com.apple.security.regressions + lockdown-identities + apple + com.apple.security.sos + com.apple.cfnetwork + 123456.test.group + 123456.test.group2 + + + diff --git a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.h b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.h new file mode 100644 index 00000000..1ee39db3 --- /dev/null +++ b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.h @@ -0,0 +1,17 @@ +// +// DeviceSimulator.h +// DeviceSimulator +// +// + +#import +#import "DeviceSimulatorProtocol.h" + +extern NSString *deviceInstance; +void boot_securityd(NSXPCListenerEndpoint *network); + +// This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection. +@interface DeviceSimulator : NSObject +@property NSXPCConnection *conn; +@property NSString *name; +@end diff --git a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.m b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.m new file mode 100644 index 00000000..5e7603af --- /dev/null +++ b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.m @@ -0,0 +1,285 @@ +// +// DeviceSimulator.m +// DeviceSimulator +// + +#import +#import +#import +#import +#import +#import +#import + +#import +#import +#import + +#import "keychain/ckks/CKKS.h" +#import "SOSCloudKeychainClient.h" + +#import "DeviceSimulatorProtocol.h" +#import "DeviceSimulator.h" + + +@implementation DeviceSimulator + +- (void)setDevice:(NSString *)name + version:(NSString *)version + model:(NSString *)model + testInstance:(NSString *)testUUID + network:(NSXPCListenerEndpoint *)network + complete:(void(^)(BOOL success))complete +{ + self.name = name; + + SecCKKSDisable(); // for now + SecCKKSContainerName = [NSString stringWithFormat:@"com.apple.test.p01.B.%@.com.apple.security.keychain", testUUID]; + + SOSCCSetGestalt_Server((__bridge CFStringRef)name, (__bridge CFStringRef)version, + (__bridge CFStringRef)model, (__bridge CFStringRef)deviceInstance); + + boot_securityd(network); + + complete(TRUE); +} + + +- (void)secItemAdd:(NSDictionary *)input complete:(void (^)(OSStatus, NSDictionary *))reply +{ + NSMutableDictionary *attributes = [input mutableCopy]; + CFTypeRef data = NULL; + + attributes[(__bridge NSString *)kSecReturnAttributes] = @YES; + attributes[(__bridge NSString *)kSecReturnPersistentRef] = @YES; + attributes[(__bridge NSString *)kSecReturnData] = @YES; + + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, &data); + NSDictionary *returnData = CFBridgingRelease(data); + + reply(status, returnData); +} + +- (void)secItemCopyMatching:(NSDictionary *)input complete:(void (^)(OSStatus, NSArray*))reply +{ + NSMutableDictionary *attributes = [input mutableCopy]; + CFTypeRef data = NULL; + + attributes[(__bridge NSString *)kSecReturnAttributes] = @YES; + attributes[(__bridge NSString *)kSecReturnData] = @YES; + attributes[(__bridge NSString *)kSecReturnPersistentRef] = @YES; + attributes[(__bridge NSString *)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; + + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)attributes, &data); + NSArray* array = CFBridgingRelease(data); + NSMutableArray *result = [NSMutableArray array]; + for (NSDictionary *d in array) { + NSMutableDictionary *r = [d mutableCopy]; + r[@"accc"] = nil; + [result addObject:r]; + } + + reply(status, result); +} + +- (void)setupSOSCircle:(NSString *)username password:(NSString *)password complete:(void (^)(bool success, NSError *error))complete +{ + CFErrorRef cferror = NULL; + bool result = SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef)username, + (__bridge CFDataRef)[password dataUsingEncoding:NSUTF8StringEncoding], + CFSTR("1"), &cferror); + if (result) { + SOSCCStatus circleStat = SOSCCThisDeviceIsInCircle(&cferror); + if (circleStat == kSOSCCCircleAbsent) { + result = SOSCCResetToOffering(&cferror); + } + } + complete(result, (__bridge NSError *)cferror); + CFReleaseNull(cferror); +} + +- (void)sosCircleStatus:(void(^)(SOSCCStatus status, NSError *error))complete +{ + SOSCloudKeychainFlush(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef __unused returnedValues, CFErrorRef __unused sync_error) { + CFErrorRef cferror = NULL; + SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror); + complete(status, (__bridge NSError *)cferror); + CFReleaseNull(cferror); + }); +} + +- (void)sosCircleStatusNonCached:(void(^)(SOSCCStatus status, NSError *error))complete +{ + SOSCloudKeychainFlush(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef __unused returnedValues, CFErrorRef __unused sync_error) { + CFErrorRef cferror = NULL; + SOSCCStatus status = SOSCCThisDeviceIsInCircleNonCached(&cferror); + complete(status, (__bridge NSError *)cferror); + CFReleaseNull(cferror); + }); +} + + +- (void)sosViewStatus:(NSString *) viewName withCompletion: (void(^)(SOSViewResultCode status, NSError *error))complete +{ + CFErrorRef cferror = NULL; + SOSViewResultCode status = SOSCCView((__bridge CFStringRef)(viewName), kSOSCCViewQuery, &cferror); + complete(status, (__bridge NSError *)cferror); + CFReleaseNull(cferror); +} + + +- (void)sosICKStatus: (void(^)(bool status))complete +{ + CFErrorRef cferror = NULL; + bool status = SOSCCIsIcloudKeychainSyncing(); + complete(status); + CFReleaseNull(cferror); +} + +- (void)sosPeerID:(void (^)(NSString *))complete +{ + CFErrorRef cferror = NULL; + CFStringRef peerID = NULL; + SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo(&cferror); + if (peerInfo) + peerID = SOSPeerInfoGetPeerID(peerInfo); + + complete((__bridge NSString *)peerID); + CFReleaseNull(peerInfo); +} + +- (void)sosRequestToJoin:(void(^)(bool success, NSString *peerID, NSError *error))complete +{ + CFErrorRef cferror = NULL; + + os_log(NULL, "[%@] sosRequestToJoin", self.name); + + SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror); + if (status == kSOSCCCircleAbsent) { + cferror = CFErrorCreate(NULL, CFSTR("MDCircleAbsent"), 1, NULL); + complete(false, NULL, (__bridge NSError *)cferror); + CFReleaseNull(cferror); + } else if (status == kSOSCCNotInCircle) { + CFReleaseNull(cferror); + NSString *peerID = NULL; + bool result = SOSCCRequestToJoinCircle(&cferror); + if (result) { + SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo(&cferror); + if (peerInfo) { + peerID = (__bridge NSString *)SOSPeerInfoGetPeerID(peerInfo); + } + CFReleaseNull(peerInfo); + CFReleaseNull(cferror); + } + complete(result, peerID, (__bridge NSError *)cferror); + CFReleaseNull(cferror); + } else { + if(!cferror) { + cferror = CFErrorCreate(NULL, CFSTR("MDGeneralJoinError"), 1, NULL); + } + complete(false, NULL, (__bridge NSError *)cferror); + CFReleaseNull(cferror); + } +} + +- (void)sosLeaveCircle: (void(^)(bool success, NSError *error))complete { + CFErrorRef cferror = NULL; + bool retval = false; + + os_log(NULL, "[%@] sosLeaveCircle", self.name); + + SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror); + if(status == kSOSCCInCircle || status == kSOSCCRequestPending) { + retval = SOSCCRemoveThisDeviceFromCircle(&cferror); + } + complete(retval, (__bridge NSError *) cferror); + CFReleaseNull(cferror); +} + + +- (void)sosApprovePeer:(NSString *)peerID complete:(void(^)(BOOL success, NSError *error))complete +{ + CFErrorRef cferror = NULL; + os_log(NULL, "[%@] sosApprovePeer: %@", self.name, peerID); + NSArray *applicants = CFBridgingRelease(SOSCCCopyApplicantPeerInfo(&cferror)); + if ([applicants count] == 0) { + CFReleaseNull(cferror); + cferror = CFErrorCreate(NULL, CFSTR("MDNoApplicant"), 1, NULL); + complete(false, (__bridge NSError *)cferror); + CFReleaseNull(cferror); + return; + } + NSMutableArray *approvedApplicants = [NSMutableArray array]; + for (id peer in applicants) { + SOSPeerInfoRef peerInfo = (__bridge SOSPeerInfoRef)peer; + NSString *applicantPeerID = (__bridge NSString *)SOSPeerInfoGetPeerID(peerInfo); + if (peerID == NULL || [peerID isEqualToString:applicantPeerID]){ + [approvedApplicants addObject:(__bridge id)peerInfo]; + } + } + bool result = false; + if ([approvedApplicants count]) { + result = SOSCCAcceptApplicants((__bridge CFArrayRef)approvedApplicants, &cferror); + } else { + cferror = CFErrorCreate(NULL, CFSTR("MDNoApplicant"), 1, NULL); + } + complete(result, (__bridge NSError *)cferror); + CFReleaseNull(cferror); +} + +- (void)sosWaitForInitialSync:(void(^)(bool success, NSError *error))complete +{ + CFErrorRef cferror = NULL; + bool success = SOSCCWaitForInitialSync(&cferror); + complete(success, (__bridge NSError *)cferror); + CFReleaseNull(cferror); +} + +- (void)sosEnableAllViews:(void(^)(BOOL success, NSError *error))complete +{ + CFMutableSetRef viewsToEnable = SOSViewCopyViewSet(kViewSetAll); + CFMutableSetRef viewsToDisable = CFSetCreateMutable(NULL, 0, NULL); + + bool success = SOSCCViewSet(viewsToEnable, viewsToDisable); + CFRelease(viewsToEnable); + CFRelease(viewsToDisable); + complete(success, NULL); + +} + +- (void) sosCachedViewBitmask: (void(^)(uint64_t bitmask))complete { + uint64_t result = SOSCachedViewBitmask(); + complete(result); +} + + + +//PRAGMA mark: - Diagnostics + +- (void)diagnosticsLeaks:(void(^)(bool success, NSString *outout, NSError *error))complete +{ + complete(true, NULL, NULL); +} + +- (void)diagnosticsCPUUsage:(void(^)(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error))complete +{ + struct rusage usage; + getrusage(RUSAGE_SELF, &usage); + uint64_t user_usec = usage.ru_utime.tv_sec * USEC_PER_SEC + usage.ru_utime.tv_usec; + uint64_t sys_usec = usage.ru_stime.tv_sec * USEC_PER_SEC + usage.ru_stime.tv_usec; + + complete(true, user_usec, sys_usec, NULL); +} + +- (void)diagnosticsDiskUsage:(void(^)(bool success, uint64_t usage, NSError *error))complete +{ + rusage_info_current rusage; + + if (proc_pid_rusage(getpid(), RUSAGE_INFO_CURRENT, (rusage_info_t *)&rusage) == 0) { + complete(true, rusage.ri_logical_writes, NULL); + } else { + complete(false, 0, NULL); + } +} + +@end diff --git a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorMain.m b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorMain.m new file mode 100644 index 00000000..c6e1ab74 --- /dev/null +++ b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorMain.m @@ -0,0 +1,489 @@ +// +// main.m +// DeviceSimulator +// +// + +#import +#import +#import +#import +#import + +#import +#import +#import +#import +#import + +#import "DeviceSimulator.h" +#import "SOSCloudKeychainClient.h" +#import "MultiDeviceNetworkingProtocol.h" +#import "SecCFWrappers.h" +#import "spi.h" + +struct SOSCloudTransport MDNTransport; + +@class MDNetwork; + +NSString *deviceInstance = NULL; +static NSString *deviceHomeDir = NULL; +static MDNetwork *deviceNetwork = NULL; + +@interface MDNetwork : NSObject +@property NSXPCConnection *connection; +@property NSXPCListener *callbackListener; +@property dispatch_queue_t flushQueue; +@property NSMutableDictionary *pendingKeys; +@property NSSet *registeredKeys; +- (instancetype)initWithConnection:(NSXPCConnection *)connection; +@end + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wprotocol" +@implementation MDNetwork + +- (instancetype)initWithConnection:(NSXPCConnection *)connection +{ + self = [super init]; + if (self) { + self.connection = connection; + self.callbackListener = [NSXPCListener anonymousListener]; + self.callbackListener.delegate = self; + [self.callbackListener resume]; + + __typeof(self) weakSelf = self; + self.connection.invalidationHandler = ^{ + __typeof(self) strongSelf = weakSelf; + [strongSelf.callbackListener invalidate]; + strongSelf.callbackListener = nil; + + exit(0); + }; + + self.flushQueue = dispatch_queue_create("MDNetwork.flushqueue", 0); + self.pendingKeys = [NSMutableDictionary dictionary]; + self.registeredKeys = [NSSet set]; + + [[self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + NSLog(@"network register callback failed with: %@", error); + //abort(); + }] MDNRegisterCallback:[self.callbackListener endpoint] complete:^void(NSDictionary *values, NSError *error) { + ; + }]; + + } + return self; +} + +- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection +{ + newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MultiDeviceNetworkingCallbackProtocol)]; + newConnection.exportedObject = self; + [newConnection resume]; + return YES; +} + +- (void)MDNCItemsChanged:(NSDictionary *)values complete:(MDNComplete)complete +{ + NSMutableDictionary *requestedKeys = [NSMutableDictionary dictionary]; + @synchronized(self.pendingKeys) { + secnotice("MDN", "items update: %@ (already pending: %@)", values, self.pendingKeys); + + [self.pendingKeys addEntriesFromDictionary:values]; + for (NSString *key in self.registeredKeys) { + id data = self.pendingKeys[key]; + if (data) { + requestedKeys[key] = data; + self.pendingKeys[key] = nil; + } + } + } + if (requestedKeys.count) { + dispatch_async(self.flushQueue, ^{ + secnotice("MDN", "engine processing keys: %@", requestedKeys); + NSArray *handled = CFBridgingRelease(SOSCCHandleUpdateMessage((__bridge CFDictionaryRef)requestedKeys)); + /* + * Ok, our dear Engine might not have handled all messages. + * So put them back unless there are new messages around that + * have overwritten the previous message. + */ + for (NSString *key in handled) { + requestedKeys[key] = NULL; + } + if (requestedKeys.count) { + @synchronized(self.pendingKeys) { + for (NSString *key in requestedKeys) { + if (self.pendingKeys[key] == nil) { + self.pendingKeys[key] = requestedKeys[key]; + } + } + } + } + }); + } + complete(NULL, NULL); +} + +/* Oh, ObjC, you are my friend */ +- (void)forwardInvocation:(NSInvocation *)invocation +{ + struct objc_method_description desc = protocol_getMethodDescription(@protocol(MultiDeviceNetworkingProtocol), [invocation selector], true, true); + if (desc.name == NULL) { + [super forwardInvocation:invocation]; + } else { + __block bool gogogo = true; + id object = [self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + gogogo = false; + NSLog(@"network failed with: %@", error); + //abort(); + }]; + if(gogogo) [invocation invokeWithTarget:object]; + } +} +@end +#pragma clang diagnostic pop + +#define HANDLE_NO_NETWORK(_replyBlock) \ + if (deviceNetwork == NULL) { \ + replyBlock((__bridge CFDictionaryRef)@{}, (__bridge CFErrorRef)[NSError errorWithDomain:@"MDNNetwork" code:1 userInfo:NULL]); \ + return; \ + } + + +static void +DSCloudPut(SOSCloudTransportRef transport, CFDictionaryRef valuesToPut, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + @autoreleasepool { + HANDLE_NO_NETWORK(replyBlock); + secnotice("MDN", "CloudPut: %@", valuesToPut); + + [deviceNetwork MDNCloudPut:(__bridge NSDictionary *)valuesToPut complete:^(NSDictionary *returnedValues, NSError *error) { + dispatch_async(processQueue, ^{ + replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error); + }); + }]; + } +} + +static NSString *nKeyAlwaysKeys = @"AlwaysKeys"; +static NSString *nKeyFirstUnlockKeys = @"FirstUnlockKeys"; +static NSString *nKeyUnlockedKeys = @"UnlockedKeys"; +static NSString *nMessageKeyParameter = @"KeyParameter"; +static NSString *nMessageCircle = @"Circle"; +static NSString *nMessageMessage = @"Message"; + + +static void +DSCloudUpdateKeys(SOSCloudTransportRef transport, CFDictionaryRef cfkeys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + /* + * Currently doesn't deal with lock state, just smash (HULK!) them all together + */ + @autoreleasepool { + NSDictionary *keys = (__bridge NSDictionary *)cfkeys; + NSMutableSet *newSet = [NSMutableSet set]; + + @synchronized(deviceNetwork.pendingKeys) { + for (NSString *type in @[ nMessageKeyParameter, nMessageCircle, nMessageMessage]) { + NSDictionary *typeDict = keys[type]; + + for (NSString *lockType in @[ nKeyAlwaysKeys, nKeyFirstUnlockKeys, nKeyUnlockedKeys]) { + NSArray *lockArray = typeDict[lockType]; + if (lockArray) { + [newSet unionSet:[NSMutableSet setWithArray:lockArray]]; + } + } + } + deviceNetwork.registeredKeys = newSet; + } + /* update engine with stuff */ + [deviceNetwork MDNCItemsChanged:@{} complete:^(NSDictionary *returnedValues, NSError *error) { + if (replyBlock) + replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error); + }]; + } +} + +static void +DSCloudGetDeviceID(SOSCloudTransportRef transport, CloudKeychainReplyBlock replyBlock) +{ + if (replyBlock) + replyBlock((__bridge CFDictionaryRef)@{}, NULL); +} + +// Debug calls +static void +DSCloudGet(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + if (replyBlock) + replyBlock((__bridge CFDictionaryRef)@{}, NULL); +} + +static void +DSCloudGetAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + if (replyBlock) + replyBlock((__bridge CFDictionaryRef)@{}, NULL); +} + +static void +DSCloudsynchronize(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + if (replyBlock) + replyBlock((__bridge CFDictionaryRef)@{}, NULL); +} + +static void +DSCloudsynchronizeAndWait(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + @autoreleasepool { + HANDLE_NO_NETWORK(replyBlock); + + [deviceNetwork MDNCloudsynchronizeAndWait:@{} complete:^(NSDictionary *returnedValues, NSError *error) { + dispatch_async(processQueue, ^{ + replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error); + }); + }]; + } +} + +static void +DSCloudRemoveObjectForKey(SOSCloudTransportRef transport, CFStringRef keyToRemove, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + if (keyToRemove == NULL) { + dispatch_async(processQueue, ^{ + replyBlock(NULL, NULL); + }); + return; + } + + @autoreleasepool { + HANDLE_NO_NETWORK(replyBlock); + [deviceNetwork MDNCloudRemoveKeys:@[(__bridge NSString *)keyToRemove] complete:^(NSDictionary *returnedValues, NSError *error) { + dispatch_async(processQueue, ^{ + replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error); + }); + }]; + } +} + +static void DSCloudremoveKeys(SOSCloudTransportRef transport, CFArrayRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + @autoreleasepool { + HANDLE_NO_NETWORK(replyBlock); + [deviceNetwork MDNCloudRemoveKeys:(__bridge NSArray *)keys complete:^(NSDictionary *returnedValues, NSError *error) { + dispatch_async(processQueue, ^{ + replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error); + }); + }]; + } +} + +static void +DSCloudclearAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + @autoreleasepool { + HANDLE_NO_NETWORK(replyBlock); + [deviceNetwork MDNCloudRemoveKeys:NULL complete:^(NSDictionary *returnedValues, NSError *error) { + dispatch_async(processQueue, ^{ + replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error); + }); + }]; + } +} + +static bool +DSCloudhasPendingKey(SOSCloudTransportRef transport, CFStringRef keyName, CFErrorRef* error) +{ + bool status = false; + @synchronized(deviceNetwork.pendingKeys) { + status = deviceNetwork.pendingKeys[(__bridge NSString *)keyName] != nil; + } + return status; +} + + +static void +DSCloudrequestSyncWithPeers(SOSCloudTransportRef transport, CFArrayRef /* CFStringRef */ peers, CFArrayRef /* CFStringRef */ backupPeers, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + CFSetRef sPeers = CFSetCreateCopyOfArrayForCFTypes(peers); + CFSetRef sBackupPeers = CFSetCreateCopyOfArrayForCFTypes(backupPeers); + + if (sPeers == NULL || sBackupPeers == NULL) { + CFReleaseNull(sPeers); + CFReleaseNull(sBackupPeers); + } else { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + CFErrorRef error = NULL; + CFSetRef result = SOSCCProcessSyncWithPeers_Server(sPeers, sBackupPeers, &error); + + CFRelease(sPeers); + CFRelease(sBackupPeers); + CFReleaseNull(result); + CFReleaseNull(error); + }); + } + if (replyBlock) { + dispatch_async(processQueue, ^{ + replyBlock((__bridge CFDictionaryRef)@{}, NULL); + }); + } +} + +static bool +DSCloudhasPeerSyncPending(SOSCloudTransportRef transport, CFStringRef peerID, CFErrorRef* error) +{ + return false; +} + +static void +DSCloudrequestEnsurePeerRegistration(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + CFErrorRef eprError = NULL; + if (!SOSCCProcessEnsurePeerRegistration_Server(&eprError)) { + secnotice("coder", "SOSCCProcessEnsurePeerRegistration failed with: %@", eprError); + } + CFReleaseNull(eprError); + if (replyBlock) + replyBlock((__bridge CFDictionaryRef)@{}, NULL); + }); +} + +static void DSCloudrequestPerfCounters(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + if (replyBlock) + replyBlock((__bridge CFDictionaryRef)@{}, NULL); +} + +static void DSCloudflush(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + @autoreleasepool { + HANDLE_NO_NETWORK(replyBlock); + + [deviceNetwork MDNCloudFlush:^(NSDictionary *returnedValues, NSError *error) { + dispatch_async(deviceNetwork.flushQueue, ^{ + dispatch_async(processQueue, ^{ + replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error); + }); + }); + }]; + } +} + +static void DSCloudcounters(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) +{ + if (replyBlock) + replyBlock((__bridge CFDictionaryRef)@{}, NULL); +} + +@interface ServiceDelegate : NSObject +@end + +@implementation ServiceDelegate + +- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { + newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(DeviceSimulatorProtocol)]; + + DeviceSimulator *exportedObject = [DeviceSimulator new]; + exportedObject.conn = newConnection; + newConnection.exportedObject = exportedObject; + + [newConnection resume]; + + return YES; +} + +@end + +void +boot_securityd(NSXPCListenerEndpoint *network) +{ + secLogDisable(); + securityd_init((__bridge CFURLRef)[NSURL URLWithString:deviceHomeDir]); + + NSXPCConnection *connection = [[NSXPCConnection alloc] initWithListenerEndpoint:network]; + connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MultiDeviceNetworkingProtocol)]; + [connection resume]; + + deviceNetwork = [[MDNetwork alloc] initWithConnection:connection]; + +} + +/* + * Make sure each of th peers don't trample on each's others state + */ + +@interface SOSCachedNotification (override) +@end + +@implementation SOSCachedNotification (override) ++ (NSString *)swizzled_notificationName:(const char *)notificationName +{ + return [NSString stringWithFormat:@"%@-%@", + [SOSCachedNotification swizzled_notificationName:notificationName], deviceInstance]; +} + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Method orignal = class_getClassMethod(self, @selector(notificationName:)); + Method swizzled = class_getClassMethod(self, @selector(swizzled_notificationName:)); + method_exchangeImplementations(orignal, swizzled); + }); +} +@end + + +int main(int argc, const char *argv[]) +{ + struct sigaction action; + memset(&action, 0, sizeof(action)); + + deviceInstance = [[NSXPCListener _UUID] UUIDString]; + + NSURL *tempPath = [[NSFileManager defaultManager] temporaryDirectory]; + deviceHomeDir = [[tempPath path] stringByAppendingPathComponent:deviceInstance]; + + [[NSFileManager defaultManager] createDirectoryAtPath:deviceHomeDir + withIntermediateDirectories:NO + attributes:NULL + error:NULL]; + + MDNTransport.put = DSCloudPut; + MDNTransport.updateKeys = DSCloudUpdateKeys; + MDNTransport.getDeviceID = DSCloudGetDeviceID; + MDNTransport.get = DSCloudGet; + MDNTransport.getAll = DSCloudGetAll; + MDNTransport.synchronize = DSCloudsynchronize; + MDNTransport.synchronizeAndWait = DSCloudsynchronizeAndWait; + MDNTransport.clearAll = DSCloudclearAll; + MDNTransport.removeObjectForKey = DSCloudRemoveObjectForKey; + MDNTransport.hasPendingKey = DSCloudhasPendingKey; + MDNTransport.requestSyncWithPeers = DSCloudrequestSyncWithPeers; + MDNTransport.hasPeerSyncPending = DSCloudhasPeerSyncPending; + MDNTransport.requestEnsurePeerRegistration = DSCloudrequestEnsurePeerRegistration; + MDNTransport.requestPerfCounters = DSCloudrequestPerfCounters; + MDNTransport.flush = DSCloudflush; + MDNTransport.itemsChangedBlock = CFBridgingRetain(^CFArrayRef(CFDictionaryRef values) { + // default change block doesn't handle messages, keep em + return CFBridgingRetain(@[]); + }); + MDNTransport.removeKeys = DSCloudremoveKeys; + MDNTransport.counters = DSCloudcounters; + + SOSCloudTransportSetDefaultTransport(&MDNTransport); + + // Create the delegate for the service. + ServiceDelegate *delegate = [ServiceDelegate new]; + signal(SIGPIPE, SIG_IGN); + + // Set up the one NSXPCListener for this service. It will handle all incoming connections. + NSXPCListener *listener = [NSXPCListener serviceListener]; + listener.delegate = delegate; + + // Resuming the serviceListener starts this service. This method does not return. + [listener resume]; + return 0; +} diff --git a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorProtocol.h b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorProtocol.h new file mode 100644 index 00000000..77e27677 --- /dev/null +++ b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorProtocol.h @@ -0,0 +1,44 @@ +// +// DeviceSimulatorProtocol.h +// DeviceSimulator +// + +#import +#import + +@protocol DeviceSimulatorProtocol + +- (void)setDevice:(NSString *)name + version:(NSString *)version + model:(NSString *)model + testInstance:(NSString *)testUUID + network:(NSXPCListenerEndpoint *)network + complete:(void(^)(BOOL success))complete; + +// Local Keychain +- (void)secItemAdd:(NSDictionary *)input complete:(void (^)(OSStatus, NSDictionary *))reply; +- (void)secItemCopyMatching:(NSDictionary *)input complete:(void (^)(OSStatus, NSArray*))replyreply; + +// SOS trust +- (void)setupSOSCircle:(NSString *)username password:(NSString *)password complete:(void (^)(bool success, NSError *error))complete; +- (void)sosCircleStatus:(void(^)(SOSCCStatus status, NSError *error))complete; +- (void)sosCircleStatusNonCached:(void(^)(SOSCCStatus status, NSError *error))complete; +- (void)sosViewStatus:(NSString *) view withCompletion: (void(^)(SOSViewResultCode status, NSError *error))complete; +- (void)sosICKStatus: (void(^)(bool status))complete; +- (void)sosCachedViewBitmask: (void(^)(uint64_t bitmask))complete; +- (void)sosPeerID:(void(^)(NSString *peerID))complete; +- (void)sosRequestToJoin:(void(^)(bool success, NSString *peerID, NSError *error))complete; +- (void)sosLeaveCircle: (void(^)(bool success, NSError *error))complete; +- (void)sosApprovePeer:(NSString *)peerID complete:(void(^)(BOOL success, NSError *error))complete; + +// SOS syncing +- (void)sosWaitForInitialSync:(void(^)(bool success, NSError *error))complete; +- (void)sosEnableAllViews:(void(^)(BOOL success, NSError *error))complete; + +// Diagnostics +- (void)diagnosticsLeaks:(void(^)(bool success, NSString *outout, NSError *error))complete; +- (void)diagnosticsCPUUsage:(void(^)(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error))complete; +- (void)diagnosticsDiskUsage:(void(^)(bool success, uint64_t usage, NSError *error))complete; + +@end + diff --git a/MultiDeviceSimulator/DeviceSimulator/Info.plist b/MultiDeviceSimulator/DeviceSimulator/Info.plist new file mode 100644 index 00000000..612cb515 --- /dev/null +++ b/MultiDeviceSimulator/DeviceSimulator/Info.plist @@ -0,0 +1,33 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + DeviceSimulator + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + XPCService + + ServiceType + Application + _MultipleInstances + + JoinExistingSession + + + + diff --git a/MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist b/MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.h b/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.h new file mode 100644 index 00000000..65847325 --- /dev/null +++ b/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.h @@ -0,0 +1,24 @@ +// +// MultiDeviceNetworking.h +// Security +// + +#import +#import + +@interface MDNCounters : NSObject +//- (NSDictionary *)summary; +@end + +@interface MultiDeviceNetworking : NSObject +- (instancetype)init; +- (NSXPCListenerEndpoint *)endpoint; +- (void)dumpKVSState; +- (void)dumpCounters; +- (void)disconnectAll; + +- (void)setTestExpectation:(XCTestExpectation *)expectation forKey:(NSString *)key; +- (void)fulfill:(NSString *)key; +- (void)clearTestExpectations; + +@end diff --git a/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.m b/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.m new file mode 100644 index 00000000..d660f6af --- /dev/null +++ b/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.m @@ -0,0 +1,295 @@ +// +// MultiDeviceNetworking.m +// Security +// + +#import "MultiDeviceNetworking.h" +#import "MultiDeviceNetworkingProtocol.h" + +@interface MDNCounters () +@property (assign) unsigned long kvsSyncAndWait; +@property (assign) unsigned long kvsFlush; +@property (assign) unsigned long kvsSend; +@property (assign) unsigned long kvsRecv; +@property (assign) unsigned long kvsRecvAll; +@property (strong) NSMutableDictionary *kvsKeys; + +- (void)addCountToKey:(NSString *)key; +@end + + +@interface MDNConnection : NSObject +@property (weak) MultiDeviceNetworking *network; +@property NSXPCConnection *inConnection; +@property NSXPCConnection *outConnection; +@property MDNCounters *counters; +@end + +@interface MultiDeviceNetworking () +@property NSXPCListener *networkListener; +@property NSMutableDictionary *kvs; +@property NSMutableArray *connections; +@property dispatch_queue_t serialQueue; +@property NSMutableDictionary *expectations; +@end + +@implementation MDNCounters + +- (instancetype)init { + if ((self = [super init]) == NULL) { + return nil; + } + self.kvsKeys = [NSMutableDictionary dictionary]; + return self; +} + +- (NSDictionary *)summary{ + NSDictionary *kvsKeys = @{}; + @synchronized(self.kvsKeys) { + kvsKeys = [self.kvsKeys copy]; + } + return @{ + @"kvsSyncAndWait" : @(self.kvsSyncAndWait), + @"kvsFlush" : @(self.kvsFlush), + @"kvsSend" : @(self.kvsSend), + @"kvsRecv" : @(self.kvsRecv), + @"kvsRecvAll" : @(self.kvsRecvAll), + @"kvsKeys" : kvsKeys, + }; +} +- (NSString *)description +{ + return [NSString stringWithFormat:@"", [self summary]]; +} +- (void)addCountToKey:(NSString *)key +{ + @synchronized(self.kvsKeys) { + NSNumber *number = self.kvsKeys[key]; + self.kvsKeys[key] = @([number longValue] + 1); + } +} + +@end + +@implementation MultiDeviceNetworking + +- (instancetype)init +{ + self = [super init]; + if (self) { + self.networkListener = [NSXPCListener anonymousListener]; + self.networkListener.delegate = self; + [self.networkListener resume]; + self.kvs = [[NSMutableDictionary alloc] init]; + self.connections = [NSMutableArray array]; + self.serialQueue = dispatch_queue_create("MultiDeviceNetworking.flushQueue", NULL); + self.expectations = [NSMutableDictionary dictionary]; + } + return self; +} + +- (NSXPCListenerEndpoint *)endpoint +{ + return [self.networkListener endpoint]; +} + +- (void)dumpKVSState +{ + @synchronized(self.kvs) { + puts("KVS STATE"); + [self.kvs enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull __unused stop) { + puts([[NSString stringWithFormat:@"%@ - %@", key, obj] UTF8String]); + }]; + } +} + +- (void)dumpCounters +{ + @synchronized(self.connections) { + puts("Network counters:"); + for (MDNConnection *conn in self.connections) { + puts([[NSString stringWithFormat:@"%@", conn.counters] UTF8String]); + } + } +} + + +- (void)disconnectAll +{ + @synchronized(self.connections) { + for (MDNConnection *conn in self.connections) { + [conn.inConnection invalidate]; + [conn.outConnection invalidate]; + } + self.connections = [NSMutableArray array]; + } +} + +- (void)setTestExpectation:(XCTestExpectation *)expectation forKey:(NSString *)key +{ + self.expectations[key] = expectation; +} + +- (void)clearTestExpectations +{ + self.expectations = [NSMutableDictionary dictionary]; +} + +- (void)fulfill:(NSString *)key +{ + [self.expectations[key] fulfill]; +} + + + +//MARK: - setup listener + +- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection +{ + newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MultiDeviceNetworkingProtocol)]; + + MDNConnection *conn = [[MDNConnection alloc] init]; + conn.network = self; + conn.inConnection = newConnection; + newConnection.exportedObject = conn; + + [self.connections addObject:conn]; + [newConnection resume]; + + return YES; +} + +@end + + +//MARK: - KVS fun + +@implementation MDNConnection + +- (instancetype)init +{ + if ((self = [super init]) == nil) + return nil; + _counters = [[MDNCounters alloc] init]; + return self; +} + +- (void)MDNRegisterCallback:(NSXPCListenerEndpoint *)callback complete:(MDNComplete)complete +{ + self.outConnection = [[NSXPCConnection alloc] initWithListenerEndpoint:callback]; + self.outConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MultiDeviceNetworkingCallbackProtocol)]; + + __typeof(self) weakSelf = self; + self.outConnection.invalidationHandler = ^{ + __typeof(self) strongSelf = weakSelf; + strongSelf.outConnection = nil; + }; + + + [self.outConnection resume]; + complete(NULL, NULL); +} + +- (void)MDNCloudPut:(NSDictionary *)values complete:(MDNComplete)complete { + MultiDeviceNetworking *network = self.network; + @synchronized(network.kvs) { + [network.kvs setValuesForKeysWithDictionary:values]; + } + /* interact with test expections so that tests can check that something happned in KVS */ + [network fulfill:@"Network"]; + for (NSString *key in values.allKeys) { + NSString *dataSummary = @""; + id value = values[key]; + if ([value isKindOfClass:[NSString class]]) { + dataSummary = [NSString stringWithFormat:@" = string[%ld]", [(NSString *)value length]]; + } else if ([value isKindOfClass:[NSData class]]) { + NSUInteger length = [(NSData *)value length]; + NSData *subdata = [(NSData *)value subdataWithRange:NSMakeRange(0, MIN(length, 4))]; + dataSummary = [NSString stringWithFormat:@" = data[%lu][%@]", (unsigned long)length, subdata]; + } else { + dataSummary = [NSString stringWithFormat:@" = other(%@)", [value description]]; + } + NSLog(@"KVS key update: %@%@", key, dataSummary); + [network fulfill:key]; + [self.counters addCountToKey:key]; + } + + + self.counters.kvsSend++; + for (MDNConnection *conn in network.connections) { + if (conn == self || conn.outConnection == NULL) { + continue; + } + conn.counters.kvsRecv++; + [[conn.outConnection remoteObjectProxy] MDNCItemsChanged:values complete:^(NSDictionary *returnedValues, NSError *error) { + ; + }]; + } + complete(@{}, NULL); +} + +- (void)MDNCloudsynchronizeAndWait:(NSDictionary *)values complete:(MDNComplete)complete { + MultiDeviceNetworking *network = self.network; + NSDictionary *kvsCopy = NULL; + @synchronized(network.kvs) { + kvsCopy = [network.kvs copy]; + } + self.counters.kvsSyncAndWait++; + [[self.outConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + NSLog(@"foo: %@", error); + //abort(); + }] MDNCItemsChanged:kvsCopy complete:^(NSDictionary *returnedValues, NSError *error) { + }]; + dispatch_async(network.serialQueue, ^{ + complete(@{}, NULL); + }); +} + +- (void)MDNCloudGet:(NSArray *)keys complete:(MDNComplete)complete{ + MultiDeviceNetworking *network = self.network; + NSLog(@"asking for: %@", keys); + self.counters.kvsRecv++; + NSMutableDictionary *reply = [NSMutableDictionary dictionary]; + @synchronized(network.kvs) { + for (id key in keys) { + reply[key] = network.kvs[key]; + } + } + complete(reply, NULL); +} + +- (void)MDNCloudGetAll:(MDNComplete)complete +{ + MultiDeviceNetworking *network = self.network; + NSDictionary *kvsCopy = NULL; + self.counters.kvsRecvAll++; + @synchronized(network.kvs) { + kvsCopy = [network.kvs copy]; + } + complete(kvsCopy, NULL); +} + +- (void)MDNCloudRemoveKeys:(NSArray *)keys complete:(MDNComplete)complete +{ + MultiDeviceNetworking *network = self.network; + @synchronized(network.kvs) { + if (keys) { + for (NSString *key in keys) { + network.kvs[key] = NULL; + } + } else { + network.kvs = [NSMutableDictionary dictionary]; + } + } + complete(NULL, NULL); +} + +- (void)MDNCloudFlush:(MDNComplete)complete +{ + self.counters.kvsFlush++; + dispatch_async(self.network.serialQueue, ^{ + complete(@{}, NULL); + }); +} + +@end diff --git a/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworkingProtocol.h b/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworkingProtocol.h new file mode 100644 index 00000000..167d5c49 --- /dev/null +++ b/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworkingProtocol.h @@ -0,0 +1,26 @@ +// +// DeviceSimulatorProtocol.h +// DeviceSimulator +// + +#import + +typedef void (^MDNComplete)(NSDictionary * returnedValues, NSError *error); + +@protocol MultiDeviceNetworkingCallbackProtocol +- (void)MDNCItemsChanged:(NSDictionary *)values complete:(MDNComplete)complete; +@end + +@protocol MultiDeviceNetworkingProtocol + +- (void)MDNRegisterCallback:(NSXPCListenerEndpoint *)callback complete:(MDNComplete)complete; +- (void)MDNCloudPut:(NSDictionary *)values complete:(MDNComplete)complete; +- (void)MDNCloudsynchronizeAndWait:(NSDictionary *)values complete:(MDNComplete)complete; +- (void)MDNCloudGet:(NSArray *)keys complete:(MDNComplete)complete; +- (void)MDNCloudGetAll:(MDNComplete)complete; +- (void)MDNCloudRemoveKeys:(NSArray *)keys complete:(MDNComplete)complete; +- (void)MDNCloudFlush:(MDNComplete)complete; + +@end + + diff --git a/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceSimulatorTests.m b/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceSimulatorTests.m new file mode 100644 index 00000000..c64cd1f6 --- /dev/null +++ b/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceSimulatorTests.m @@ -0,0 +1,547 @@ +// +// MultiDeviceSimulatorTests.m +// MultiDeviceSimulatorTests +// +// + +#import +#import +#import +#import + +#import "DeviceSimulatorProtocol.h" +#import "MultiDeviceNetworking.h" +#import + +@interface MDDevice : NSObject +@property NSXPCConnection *connection; +@property NSString *name; +- (instancetype)initWithConnection:(NSXPCConnection *)connection; +@end + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wprotocol" +@implementation MDDevice + +- (instancetype)initWithConnection:(NSXPCConnection *)connection +{ + self = [super init]; + if (self) { + self.connection = connection; + } + return self; +} + +/* Oh, ObjC, you are my friend */ +- (void)forwardInvocation:(NSInvocation *)invocation +{ + struct objc_method_description desc = protocol_getMethodDescription(@protocol(DeviceSimulatorProtocol), [invocation selector], true, true); + if (desc.name == NULL) { + [super forwardInvocation:invocation]; + } else { + __block bool dooooooEeeeetExclamationPoint = true; + NSLog(@"forwarding to [%@]: %s", self.name, sel_getName(desc.name)); + id object = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + NSLog(@"peer failed with: %@", error); + dooooooEeeeetExclamationPoint = false; + //abort(); + }]; + if(dooooooEeeeetExclamationPoint) { + [invocation invokeWithTarget:object]; + } + } +} +@end +#pragma clang diagnostic pop + + +@interface MultiDeviceSimulatorTests : XCTestCase +@property NSMutableDictionary *connections; +@property MultiDeviceNetworking *network; +@property MDDevice *masterDevice; +@property NSMutableArray *minionDevices; +@end + +static NSString *testInstanceUUID; + +@implementation MultiDeviceSimulatorTests + ++ (void)setUp +{ + testInstanceUUID = [[NSUUID UUID] UUIDString]; +} + +- (void)setUp +{ + signal(SIGPIPE, SIG_IGN); + self.connections = [NSMutableDictionary dictionary]; + self.network = [[MultiDeviceNetworking alloc] init]; + + self.minionDevices = [NSMutableArray array]; +} + +- (void)tearDown +{ + __block uint64_t totalUserUsec = 0, totalSysUsec = 0, totalDiskUsage = 0; + NSMutableDictionary *result = [NSMutableDictionary dictionary]; + + for (NSString *name in self.connections) { + MDDevice *device = self.connections[name]; + NSLog(@"device: %@", name); + [device diagnosticsCPUUsage:^(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error) { + NSLog(@"cpu %@: %d: u:%llu s:%llu", device.name, success, (unsigned long long)user_usec, (unsigned long long)sys_usec); + totalUserUsec += user_usec; + totalSysUsec += sys_usec; + result[[NSString stringWithFormat:@"cpu-%@", name]] = @{ @"user_usec" : @(user_usec), @"system_usec" : @(sys_usec)}; + }]; + [device diagnosticsDiskUsage:^(bool success, uint64_t usage, NSError *error) { + NSLog(@"disk %@: %d: %llu", device.name, success, (unsigned long long)usage); + totalDiskUsage += usage; + result[[NSString stringWithFormat:@"disk-%@", name]] = @{ @"usage" : @(usage) }; + }]; + } + + for(MDDevice *dev in self.minionDevices) { + [dev sosLeaveCircle:^(bool success, NSError *error) { + ; + }]; + } + [self.masterDevice sosLeaveCircle:^(bool success, NSError *error) { + ; + }]; + + self.minionDevices = NULL; + self.masterDevice = NULL; + + result[@"cpu-total"] = @{ @"user_usec" : @(totalUserUsec), @"system_usec" : @(totalSysUsec)}; + result[@"disk-total"] = @{ @"disk" : @(totalDiskUsage) }; + + NSLog(@"Total cpu: u:%llu s:%llu", (unsigned long long)totalUserUsec, (unsigned long long)totalSysUsec); + NSLog(@"Total disk: %llu", (unsigned long long)totalDiskUsage); + + /* XXX check for leaks in all devices */ + for (NSString *name in self.connections) { + MDDevice *device = self.connections[name]; + [device.connection invalidate]; + } + self.connections = NULL; + [self.network dumpKVSState]; + [self.network dumpCounters]; + [self.network disconnectAll]; + [self.network clearTestExpectations]; + self.network = NULL; + + NSData * jsonData = [NSJSONSerialization dataWithJSONObject:result options:0 error:NULL]; + + [jsonData writeToFile:[NSString stringWithFormat:@"/tmp/test-result-%@", [self name]] atomically:NO]; + +} + +- (void)setupMasterDevice +{ + self.masterDevice = [self device:@"ipad" model:@"iPad" version:@"15E143a"]; + + [self.masterDevice setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + }]; + + [self.masterDevice sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error); + }]; +} + +//MARK: - Device logic + +- (MDDevice *)device:(NSString *)name model:(NSString *)model version:(NSString *)version { + MDDevice *device = self.connections[name]; + if (device != NULL) { + return NULL; + } + + NSXPCConnection *conn = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.Security.DeviceSimulator"]; + conn.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(DeviceSimulatorProtocol)]; + [conn _setUUID:[NSUUID UUID]]; // select a random instance + [conn resume]; + + device = [[MDDevice alloc] initWithConnection:conn]; + device.name = name; + + self.connections[name] = device; + + [device setDevice:name + version:version + model:model + testInstance:testInstanceUUID + network:[self.network endpoint] + complete:^(BOOL success) { + if (!success) { + abort(); + } + }]; + return device; +} + +- (bool)addDeviceToCircle: (MDDevice *) dev { + __block bool added = false; + __block NSString *devPeerID = NULL; + __block NSError *localErr = nil; + + [dev setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + added = success; + }]; + + if(added) { + [dev sosRequestToJoin:^(bool success, NSString *peerID, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + XCTAssertNotEqual(peerID, NULL, "Expected to find peerID for peer2"); + devPeerID = peerID; + added &= success; + }]; + } + + if(added) { + __block bool done = false; + for(int tries=0; tries < 5; tries++) { + sleep(2); + + [self.masterDevice sosApprovePeer:devPeerID complete:^(BOOL success, NSError *error) { + localErr = [error copy]; + if(success) { + localErr = nil; + done = true; + } + }]; + if(done) break; + } + added &= done; + } + XCTAssert(added, "Expect success (for approve of %@): %@", devPeerID, localErr); + return added; +} + +- (void)addKeychainItems:(unsigned long)items toDevice:(MDDevice *)device +{ + NSDictionary *addItem = @{ + (__bridge id)kSecClass :(__bridge id)kSecClassInternetPassword, + (__bridge id)kSecValueData : [@"foo" dataUsingEncoding:NSUTF8StringEncoding], + (__bridge id)kSecAttrAccessGroup: @"com.apple.cfnetwork", + (__bridge id)kSecAttrSyncViewHint: @"PCS-MasterKey", + (__bridge id)kSecAttrDescription: @"delete me if found", + (__bridge id)kSecAttrServer: @"server", + (__bridge id)kSecAttrAccount: @"account", + (__bridge id)kSecAttrSynchronizable: @YES, + (__bridge id)kSecAttrPath: @"/path", + (__bridge id)kSecAttrIsInvisible: @YES, + }; + + [device secItemAdd:addItem complete:^void(OSStatus status, NSDictionary *result) { + NSLog(@"Result string was dev1: %d %@", (int)status, result); + XCTAssertEqual(status, 0, "Expect success"); + }]; + +} + +- (void)runSigninWithAdditionalDevices:(unsigned)additionalDeviceCount keychainItems:(unsigned long)items { + + for (unsigned n = 0; n < additionalDeviceCount; n++) { + MDDevice *dev = [self device:[NSString stringWithFormat:@"mac-%u", n] model:@"Mac Pro" version:@"17E121"]; + if(dev) { + [self addDeviceToCircle: dev]; + [self.minionDevices addObject:dev]; + } + } + + if (items) { + [self addKeychainItems:items toDevice:self.masterDevice]; + } +} + + +- (void)testPref3Devices { + [self setupMasterDevice]; + + [self measureBlock:^{ + [self runSigninWithAdditionalDevices:2 keychainItems:0]; + }]; +} + +#if 0 /* disabled because of 10min time limit in bats (for now) */ + +- (void)testPref3Devices1 { + [self setupMasterDevice]; + [self runSigninWithAdditionalDevices:2 keychainItems:1]; + sleep(60); +} + +- (void)testPref3Devices10 { + [self setupMasterDevice]; + [self runSigninWithAdditionalDevices:2 keychainItems:10]; + sleep(60); +} + +- (void)testPref3Devices100 { + [self setupMasterDevice]; + [self runSigninWithAdditionalDevices:2 keychainItems:100]; + sleep(60); +} + +- (void)testPref3Devices1000 { + [self setupMasterDevice]; + [self runSigninWithAdditionalDevices:2 keychainItems:1000]; + sleep(60); + sleep(1); +} + +- (void)testPref6Devices { + [self setupMasterDevice]; + + [self measureBlock:^{ + [self runSigninWithAdditionalDevices:5 keychainItems:0]; + }]; +} + +- (void) testDevices6Retired { + [self setupMasterDevice]; + + [self measureBlock:^{ + [self runSigninWithAdditionalDevices:5 keychainItems:0]; + }]; + +} +#endif + +- (void)test2Device { + + NSLog(@"create devices"); + MDDevice *dev1 = [self device:@"ipad" model:@"iPad" version:@"15E143a"]; + MDDevice *dev2 = [self device:@"mac" model:@"Mac Pro" version:@"17E121"]; + + /* + * using PCS-MasterKey for direct syncing during inital sync + */ + + NSDictionary *addItem = @{ + (__bridge id)kSecClass :(__bridge id)kSecClassInternetPassword, + (__bridge id)kSecValueData : [@"foo" dataUsingEncoding:NSUTF8StringEncoding], + (__bridge id)kSecAttrAccessGroup: @"com.apple.cfnetwork", + (__bridge id)kSecAttrSyncViewHint: @"PCS-MasterKey", + (__bridge id)kSecAttrDescription: @"delete me if found", + (__bridge id)kSecAttrServer: @"server", + (__bridge id)kSecAttrAccount: @"account", + (__bridge id)kSecAttrSynchronizable: @YES, + (__bridge id)kSecAttrPath: @"/path", + (__bridge id)kSecAttrIsInvisible: @YES, + }; + + NSDictionary *findItem = @{ + (__bridge id)kSecClass :(__bridge id)kSecClassInternetPassword, + (__bridge id)kSecAttrAccessGroup: @"com.apple.cfnetwork", + (__bridge id)kSecAttrServer: @"server", + (__bridge id)kSecAttrAccount: @"account", + (__bridge id)kSecAttrSynchronizable: @YES, + }; + + [dev1 secItemAdd:addItem complete:^void(OSStatus status, NSDictionary *result) { + NSLog(@"Result string was dev1: %d %@", (int)status, result); + XCTAssertEqual(status, 0, "Expect success"); + }]; + [dev1 secItemCopyMatching:findItem complete:^(OSStatus status, NSArray *result) { + NSLog(@"Result string was dev1: %d %@", (int)status, result); + XCTAssertEqual(status, 0, "Expect success"); + }]; + + /* + * Setup and validate device 1 + */ + + XCTestExpectation *expection = [self expectationWithDescription:@"expect to create circle"]; + [dev1 setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + [expection fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + + [dev1 sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error); + }]; + [dev2 sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCError, @"expected to be in error: %@", error); + }]; + + /* + * Setup and validate device 2 + */ + + expection = [self expectationWithDescription:@"expect to create circle"]; + [dev2 setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + [expection fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + + [dev1 sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error); + }]; + [dev2 sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCNotInCircle, @"expected to be NOT in circle: %@", error); + }]; + + NSLog(@"Update all views (dev1)"); + expection = [self expectationWithDescription:@"expect circle update"]; + expection.assertForOverFulfill = false; + [self.network setTestExpectation:expection forKey:@"oak"]; + + expection.assertForOverFulfill = false; + [dev1 sosEnableAllViews:^(BOOL success, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + }]; + + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + [self.network clearTestExpectations]; + + __block NSString *peerID1 = NULL; + [dev1 sosPeerID:^(NSString *peerID) { + XCTAssertNotEqual(peerID, NULL, @"expected to find a peerID for peer1"); + peerID1 = peerID; + }]; + + [dev2 sosPeerID:^(NSString *peerID) { + XCTAssertEqual(peerID, NULL, @"expected to NOT find peerID for peer2"); + }]; + + [dev1 sosPeerID:^(NSString *peerID) { + XCTAssertNotEqual(peerID, NULL, @"expected to find a peerID for peer1"); + XCTAssertEqualObjects(peerID1, peerID, "dev1 changed ?"); + }]; + + /* + * Validate second device can request to join + */ + + expection = [self expectationWithDescription:@"expect circle update"]; + expection.assertForOverFulfill = false; + [self.network setTestExpectation:expection forKey:@"oak"]; + + __block NSString *peerID2 = NULL; + [dev2 sosRequestToJoin:^(bool success, NSString *peerID, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + XCTAssertNotEqual(peerID, NULL, @"expected to find peerID for peer2"); + peerID2 = peerID; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + [self.network clearTestExpectations]; + + /* + * Check that device 2 can't self join + */ + + expection = [self expectationWithDescription:@"expect device 2 can't self join"]; + [dev2 sosApprovePeer:peerID2 complete:^(BOOL success, NSError *error) { + XCTAssert(!success, "Expect failure: %@", error); + [expection fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + + [dev2 sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCRequestPending, @"expected to be pending request: %@", error); + }]; + + [dev1 sosPeerID:^(NSString *peerID) { + XCTAssertNotEqual(peerID, NULL, @"expected to find a peerID for peer1"); + XCTAssertEqualObjects(peerID1, peerID, "dev1 changed ?"); + }]; + + /* + * Approve device 2 and enable all views + */ + + NSLog(@"approve"); + expection = [self expectationWithDescription:@"expect circle update"]; + expection.assertForOverFulfill = false; + [self.network setTestExpectation:expection forKey:@"oak"]; + + [dev1 sosApprovePeer:peerID2 complete:^(BOOL success, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + }]; + [self waitForExpectationsWithTimeout:60.0 handler:nil]; + [self.network clearTestExpectations]; + + + /* + * Validate device 2 made it into circle and have a peerID + */ + + [dev1 sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error); + }]; + [dev2 sosCircleStatus:^void(SOSCCStatus status, NSError *error) { + XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error); + }]; + + [dev2 sosPeerID:^(NSString *peerID) { + XCTAssertNotEqual(peerID, NULL, @"expected to find a peerID for peer2"); + peerID2 = peerID; + //XCTAssertEqualObject(peerID1, peerID2, "expect peerID to be different"); + }]; + + /* + * Enable view for syncing + */ + + NSString *netID1toID2 = [NSString stringWithFormat:@"ak|%@:%@", peerID1, peerID2]; + NSString *netID2toID1 = [NSString stringWithFormat:@"ak|%@:%@", peerID2, peerID1]; + + expection = [self expectationWithDescription:@"expect traffic from 1->2"]; + expection.assertForOverFulfill = false; + [self.network setTestExpectation:expection forKey:netID1toID2]; + + expection = [self expectationWithDescription:@"expect traffic from 2->1"]; + expection.assertForOverFulfill = false; + [self.network setTestExpectation:expection forKey:netID2toID1]; + + expection = [self expectationWithDescription:@"expect circle update"]; + expection.assertForOverFulfill = false; + [self.network setTestExpectation:expection forKey:@"oak"]; + + /* + * Perform initial sync + */ + + NSLog(@"initial sync"); + expection = [self expectationWithDescription:@"perform initial sync"]; + [dev2 sosWaitForInitialSync:^(bool success, NSError *error) { + XCTAssert(success, "Expect success for syncing: %@", error); + [expection fulfill]; + }]; + + /* + * + */ + + NSLog(@"Update all views (dev2)"); + [dev2 sosEnableAllViews:^(BOOL success, NSError *error) { + XCTAssert(success, "Expect success: %@", error); + }]; + + [self waitForExpectationsWithTimeout:60.0 handler:nil]; + [self.network clearTestExpectations]; + + /* + * check syncing did its thing + */ + NSLog(@"SecItemCopyMatching"); + [dev1 secItemCopyMatching:findItem complete:^(OSStatus status, NSArray *result) { + NSLog(@"Result string was dev1: %d %@", (int)status, result); + XCTAssertEqual(status, 0, "Expect success"); + }]; + + [dev2 secItemCopyMatching:findItem complete:^(OSStatus status, NSArray *result) { + NSLog(@"Result string was dev2: %d %@", (int)status, result); + XCTAssertEqual(status, 0, "Expect success"); + }]; + + NSLog(@"done"); +} + +@end diff --git a/OSX/Breadcrumb/SecBreadcrumb.c b/OSX/Breadcrumb/SecBreadcrumb.c index 13caa20f..067c93c5 100644 --- a/OSX/Breadcrumb/SecBreadcrumb.c +++ b/OSX/Breadcrumb/SecBreadcrumb.c @@ -37,15 +37,15 @@ #define CFReleaseNull(CF) ({ __typeof__(CF) *const _pcf = &(CF), _cf = *_pcf; (_cf ? (*_pcf) = ((__typeof__(CF))0), (CFRelease(_cf), ((__typeof__(CF))0)) : _cf); }) -static const int kKeySize = CCAES_KEY_SIZE_128; -static const int kSaltSize = 20; -static const int kIterations = 5000; -static const CFIndex tagLen = 16; -static const CFIndex ivLen = 16; -static const uint8_t BCversion1 = 1; -static const uint8_t BCversion2 = 2; -static const ssize_t paddingSize = 256; -static const ssize_t maxSize = 1024; +#define kBCKeySize CCAES_KEY_SIZE_128 +#define kBCSaltSize 20 +#define kBCIterations 5000 +#define BCTagLen 16 +#define BCIVLen 16 +#define BCversion1 1 +#define BCversion2 2 +#define BCPaddingSize 256 +#define BCMaxSize 1024 Boolean SecBreadcrumbCreateFromPassword(CFStringRef inPassword, @@ -55,8 +55,7 @@ SecBreadcrumbCreateFromPassword(CFStringRef inPassword, { const struct ccmode_ecb *ecb = ccaes_ecb_encrypt_mode(); const struct ccmode_gcm *gcm = ccaes_gcm_encrypt_mode(); - const struct ccdigest_info *di = ccsha256_di(); - uint8_t iv[ivLen]; + uint8_t iv[BCIVLen]; CFMutableDataRef key, npw; CFDataRef pw; @@ -69,18 +68,18 @@ SecBreadcrumbCreateFromPassword(CFStringRef inPassword, if (key == NULL) return false; - CFDataSetLength(key, kKeySize + kSaltSize + 4); + CFDataSetLength(key, kBCKeySize + kBCSaltSize + 4); if (SecRandomCopyBytes(kSecRandomDefault, CFDataGetLength(key) - 4, CFDataGetMutableBytePtr(key)) != 0) { CFReleaseNull(key); return false; } - if (SecRandomCopyBytes(kSecRandomDefault, ivLen, iv) != 0) { + if (SecRandomCopyBytes(kSecRandomDefault, BCIVLen, iv) != 0) { CFReleaseNull(key); return false; } - uint32_t size = htonl(kIterations); - memcpy(CFDataGetMutableBytePtr(key) + kKeySize + kSaltSize, &size, sizeof(size)); + uint32_t size = htonl(kBCIterations); + memcpy(CFDataGetMutableBytePtr(key) + kBCKeySize + kBCSaltSize, &size, sizeof(size)); /* * Create data for password @@ -94,14 +93,14 @@ SecBreadcrumbCreateFromPassword(CFStringRef inPassword, const CFIndex passwordLength = CFDataGetLength(pw); - if (passwordLength > maxSize) { + if (passwordLength > BCMaxSize) { CFReleaseNull(pw); CFReleaseNull(key); return false; } - CFIndex paddedSize = passwordLength + paddingSize - (passwordLength % paddingSize); - const CFIndex outLength = 1 + ivLen + 4 + paddedSize + tagLen; + CFIndex paddedSize = passwordLength + BCPaddingSize - (passwordLength % BCPaddingSize); + const CFIndex outLength = 1 + BCIVLen + 4 + paddedSize + BCTagLen; npw = CFDataCreateMutable(NULL, outLength); if (npw == NULL) { @@ -111,36 +110,37 @@ SecBreadcrumbCreateFromPassword(CFStringRef inPassword, } CFDataSetLength(npw, outLength); - memset(CFDataGetMutableBytePtr(npw), 0, outLength); + cc_clear(outLength, CFDataGetMutableBytePtr(npw)); CFDataGetMutableBytePtr(npw)[0] = BCversion2; - memcpy(CFDataGetMutableBytePtr(npw) + 1, iv, ivLen); + memcpy(CFDataGetMutableBytePtr(npw) + 1, iv, BCIVLen); size = htonl(passwordLength); - memcpy(CFDataGetMutableBytePtr(npw) + 1 + ivLen, &size, sizeof(size)); - memcpy(CFDataGetMutableBytePtr(npw) + 1 + ivLen + 4, CFDataGetBytePtr(pw), passwordLength); + memcpy(CFDataGetMutableBytePtr(npw) + 1 + BCIVLen, &size, sizeof(size)); + memcpy(CFDataGetMutableBytePtr(npw) + 1 + BCIVLen + 4, CFDataGetBytePtr(pw), passwordLength); /* * Now create a GCM encrypted password using the random key */ ccgcm_ctx_decl(gcm->size, ctx); - ccgcm_init(gcm, ctx, kKeySize, CFDataGetMutableBytePtr(key)); - ccgcm_set_iv(gcm, ctx, ivLen, iv); + ccgcm_init(gcm, ctx, kBCKeySize, CFDataGetMutableBytePtr(key)); + ccgcm_set_iv(gcm, ctx, BCIVLen, iv); ccgcm_gmac(gcm, ctx, 1, CFDataGetMutableBytePtr(npw)); - ccgcm_update(gcm, ctx, outLength - tagLen - ivLen - 1, CFDataGetMutableBytePtr(npw) + 1 + ivLen, CFDataGetMutableBytePtr(npw) + 1 + ivLen); - ccgcm_finalize(gcm, ctx, tagLen, CFDataGetMutableBytePtr(npw) + outLength - tagLen); + ccgcm_update(gcm, ctx, outLength - BCTagLen - BCIVLen - 1, CFDataGetMutableBytePtr(npw) + 1 + BCIVLen, CFDataGetMutableBytePtr(npw) + 1 + BCIVLen); + ccgcm_finalize(gcm, ctx, BCTagLen, CFDataGetMutableBytePtr(npw) + outLength - BCTagLen); ccgcm_ctx_clear(gcm->size, ctx); /* * Wrapping key is PBKDF2(sha256) over password */ - if (di->output_size < kKeySize) abort(); - - uint8_t rawkey[di->output_size]; - + const struct ccdigest_info *di = ccsha256_di(); + uint8_t rawkey[CCSHA256_OUTPUT_SIZE]; + _Static_assert(sizeof(rawkey) >= kBCKeySize, "keysize changed w/o updating digest"); + if (sizeof(rawkey) != di->output_size) abort(); + if (ccpbkdf2_hmac(di, CFDataGetLength(pw), CFDataGetBytePtr(pw), - kSaltSize, CFDataGetMutableBytePtr(key) + kKeySize, - kIterations, + kBCSaltSize, CFDataGetMutableBytePtr(key) + kBCKeySize, + kBCIterations, sizeof(rawkey), rawkey) != 0) abort(); @@ -149,7 +149,7 @@ SecBreadcrumbCreateFromPassword(CFStringRef inPassword, */ ccecb_ctx_decl(ccecb_context_size(ecb), ecbkey); - ccecb_init(ecb, ecbkey, kKeySize, rawkey); + ccecb_init(ecb, ecbkey, kBCKeySize, rawkey); ccecb_update(ecb, ecbkey, 1, CFDataGetMutableBytePtr(key), CFDataGetMutableBytePtr(key)); ccecb_ctx_clear(ccecb_context_size(ecb), ecbkey); @@ -157,7 +157,7 @@ SecBreadcrumbCreateFromPassword(CFStringRef inPassword, * */ - memset(rawkey, 0, sizeof(rawkey)); + cc_clear(sizeof(rawkey), rawkey); CFReleaseNull(pw); *outBreadcrumb = npw; @@ -175,7 +175,6 @@ SecBreadcrumbCopyPassword(CFStringRef inPassword, CFErrorRef *outError) { const struct ccmode_ecb *ecb = ccaes_ecb_decrypt_mode(); - const struct ccdigest_info *di = ccsha256_di(); CFMutableDataRef gcmkey, oldpw; CFIndex outLength; CFDataRef pw; @@ -185,19 +184,19 @@ SecBreadcrumbCopyPassword(CFStringRef inPassword, if (outError) *outError = NULL; - if (CFDataGetLength(inEncryptedKey) < kKeySize + kSaltSize + 4) { + if (CFDataGetLength(inEncryptedKey) < kBCKeySize + kBCSaltSize + 4) { return false; } if (CFDataGetBytePtr(inBreadcrumb)[0] == BCversion1) { - if (CFDataGetLength(inBreadcrumb) < 1 + 4 + paddingSize + tagLen) + if (CFDataGetLength(inBreadcrumb) < 1 + 4 + BCPaddingSize + BCTagLen) return false; - outLength = CFDataGetLength(inBreadcrumb) - 1 - tagLen; + outLength = CFDataGetLength(inBreadcrumb) - 1 - BCTagLen; } else if (CFDataGetBytePtr(inBreadcrumb)[0] == BCversion2) { - if (CFDataGetLength(inBreadcrumb) < 1 + ivLen + 4 + paddingSize + tagLen) + if (CFDataGetLength(inBreadcrumb) < 1 + BCIVLen + 4 + BCPaddingSize + BCTagLen) return false; - outLength = CFDataGetLength(inBreadcrumb) - 1 - ivLen - tagLen; + outLength = CFDataGetLength(inBreadcrumb) - 1 - BCIVLen - BCTagLen; } else { return false; } @@ -234,15 +233,16 @@ SecBreadcrumbCopyPassword(CFStringRef inPassword, * Wrapping key is HMAC(sha256) over password */ - if (di->output_size < kKeySize) abort(); - - uint8_t rawkey[di->output_size]; - - memcpy(&size, CFDataGetMutableBytePtr(gcmkey) + kKeySize + kSaltSize, sizeof(size)); + const struct ccdigest_info *di = ccsha256_di(); + uint8_t rawkey[CCSHA256_OUTPUT_SIZE]; + _Static_assert(sizeof(rawkey) >= kBCKeySize, "keysize changed w/o updating digest"); + if (sizeof(rawkey) != di->output_size) abort(); + + memcpy(&size, CFDataGetMutableBytePtr(gcmkey) + kBCKeySize + kBCSaltSize, sizeof(size)); size = ntohl(size); if (ccpbkdf2_hmac(di, CFDataGetLength(pw), CFDataGetBytePtr(pw), - kSaltSize, CFDataGetMutableBytePtr(gcmkey) + kKeySize, + kBCSaltSize, CFDataGetMutableBytePtr(gcmkey) + kBCKeySize, size, sizeof(rawkey), rawkey) != 0) abort(); @@ -254,21 +254,21 @@ SecBreadcrumbCopyPassword(CFStringRef inPassword, */ ccecb_ctx_decl(ccecb_context_size(ecb), ecbkey); - ccecb_init(ecb, ecbkey, kKeySize, rawkey); + ccecb_init(ecb, ecbkey, kBCKeySize, rawkey); ccecb_update(ecb, ecbkey, 1, CFDataGetMutableBytePtr(gcmkey), CFDataGetMutableBytePtr(gcmkey)); ccecb_ctx_clear(ccecb_context_size(ecb), ecbkey); /* * GCM unwrap */ - uint8_t tag[tagLen]; + uint8_t tag[BCTagLen]; if (CFDataGetBytePtr(inBreadcrumb)[0] == BCversion1) { - memcpy(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + outLength, tagLen); + memcpy(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + outLength, BCTagLen); - ccgcm_one_shot_legacy(ccaes_gcm_decrypt_mode(), kKeySize, CFDataGetMutableBytePtr(gcmkey), 0, NULL, 1, CFDataGetBytePtr(inBreadcrumb), - outLength, CFDataGetBytePtr(inBreadcrumb) + 1, CFDataGetMutableBytePtr(oldpw), tagLen, tag); - if (memcmp(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + outLength, tagLen) != 0) { + ccgcm_one_shot_legacy(ccaes_gcm_decrypt_mode(), kBCKeySize, CFDataGetMutableBytePtr(gcmkey), 0, NULL, 1, CFDataGetBytePtr(inBreadcrumb), + outLength, CFDataGetBytePtr(inBreadcrumb) + 1, CFDataGetMutableBytePtr(oldpw), BCTagLen, tag); + if (memcmp(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + outLength, BCTagLen) != 0) { CFReleaseNull(oldpw); CFReleaseNull(gcmkey); return false; @@ -277,13 +277,13 @@ SecBreadcrumbCopyPassword(CFStringRef inPassword, } else { const uint8_t *iv = CFDataGetBytePtr(inBreadcrumb) + 1; int res; - memcpy(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + ivLen + outLength, tagLen); + memcpy(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + BCIVLen + outLength, BCTagLen); - res = ccgcm_one_shot(ccaes_gcm_decrypt_mode(), kKeySize, CFDataGetMutableBytePtr(gcmkey), - ivLen, iv, + res = ccgcm_one_shot(ccaes_gcm_decrypt_mode(), kBCKeySize, CFDataGetMutableBytePtr(gcmkey), + BCIVLen, iv, 1, CFDataGetBytePtr(inBreadcrumb), - outLength, CFDataGetBytePtr(inBreadcrumb) + 1 + ivLen, CFDataGetMutableBytePtr(oldpw), - tagLen, tag); + outLength, CFDataGetBytePtr(inBreadcrumb) + 1 + BCIVLen, CFDataGetMutableBytePtr(oldpw), + BCTagLen, tag); if (res) { CFReleaseNull(gcmkey); CFReleaseNull(oldpw); @@ -319,11 +319,14 @@ SecBreadcrumbCreateNewEncryptedKey(CFStringRef oldPassword, const struct ccmode_ecb *enc = ccaes_ecb_encrypt_mode(); const struct ccmode_ecb *dec = ccaes_ecb_decrypt_mode(); const struct ccdigest_info *di = ccsha256_di(); - CFMutableDataRef newEncryptedKey; + uint8_t rawkey[CCSHA256_OUTPUT_SIZE]; CFDataRef newpw = NULL, oldpw = NULL; - uint8_t rawkey[di->output_size]; - - if (CFDataGetLength(encryptedKey) < kKeySize + kSaltSize + 4) { + CFMutableDataRef newEncryptedKey; + + _Static_assert(sizeof(rawkey) >= kBCKeySize, "keysize changed w/o updating digest"); + if (sizeof(rawkey) != di->output_size) abort(); + + if (CFDataGetLength(encryptedKey) < kBCKeySize + kBCSaltSize + 4) { return NULL; } @@ -345,19 +348,17 @@ SecBreadcrumbCreateNewEncryptedKey(CFStringRef oldPassword, return false; } - if (di->output_size < kKeySize) abort(); - /* * Unwrap with new key */ uint32_t iter; - memcpy(&iter, CFDataGetMutableBytePtr(newEncryptedKey) + kKeySize + kSaltSize, sizeof(iter)); + memcpy(&iter, CFDataGetMutableBytePtr(newEncryptedKey) + kBCKeySize + kBCSaltSize, sizeof(iter)); iter = ntohl(iter); if (ccpbkdf2_hmac(di, CFDataGetLength(oldpw), CFDataGetBytePtr(oldpw), - kSaltSize, CFDataGetMutableBytePtr(newEncryptedKey) + kKeySize, + kBCSaltSize, CFDataGetMutableBytePtr(newEncryptedKey) + kBCKeySize, iter, sizeof(rawkey), rawkey) != 0) abort(); @@ -366,18 +367,18 @@ SecBreadcrumbCreateNewEncryptedKey(CFStringRef oldPassword, ccecb_ctx_decl(dec->size, deckey); - ccecb_init(dec, deckey, kKeySize, rawkey); + ccecb_init(dec, deckey, kBCKeySize, rawkey); ccecb_update(dec, deckey, 1, CFDataGetMutableBytePtr(newEncryptedKey), CFDataGetMutableBytePtr(newEncryptedKey)); ccecb_ctx_clear(ccecb_context_size(dec), deckey); - memset(rawkey, 0, sizeof(rawkey)); - + cc_clear(sizeof(rawkey), rawkey); + /* * Re-wrap with new key */ if (ccpbkdf2_hmac(di, CFDataGetLength(newpw), CFDataGetBytePtr(newpw), - kSaltSize, CFDataGetMutableBytePtr(newEncryptedKey) + kKeySize, + kBCSaltSize, CFDataGetMutableBytePtr(newEncryptedKey) + kBCKeySize, iter, sizeof(rawkey), rawkey) != 0) abort(); @@ -386,11 +387,11 @@ SecBreadcrumbCreateNewEncryptedKey(CFStringRef oldPassword, ccecb_ctx_decl(enc->size, enckey); - ccecb_init(enc, enckey, kKeySize, rawkey); + ccecb_init(enc, enckey, kBCKeySize, rawkey); ccecb_update(enc, enckey, 1, CFDataGetMutableBytePtr(newEncryptedKey), CFDataGetMutableBytePtr(newEncryptedKey)); ccecb_ctx_clear(ccecb_context_size(enc), enckey); - memset(rawkey, 0, sizeof(rawkey)); + cc_clear(sizeof(rawkey), rawkey); return newEncryptedKey; } diff --git a/OSX/Keychain Circle Notification/KNAppDelegate.m b/OSX/Keychain Circle Notification/KNAppDelegate.m index c8995b94..e9782142 100644 --- a/OSX/Keychain Circle Notification/KNAppDelegate.m +++ b/OSX/Keychain Circle Notification/KNAppDelegate.m @@ -550,6 +550,7 @@ static void PSKeychainSyncIsUsingICDP(void) secnotice("kcn", "About to post #%d/%lu (%@): %@", postCount, noteCenter.deliveredNotifications.count, applicant.idString, note); [appropriateNotificationCenter() deliverNotification:note]; + [self.viewedIds addObject:applicant.idString]; postCount++; } diff --git a/OSX/Keychain/KDAppDelegate.m b/OSX/Keychain/KDAppDelegate.m index 58a2ff4d..710d5fd6 100644 --- a/OSX/Keychain/KDAppDelegate.m +++ b/OSX/Keychain/KDAppDelegate.m @@ -85,11 +85,11 @@ -(void)setCheckbox { if (self.circle.isInCircle) { - [self.enableKeychainSyncing setState:NSOnState]; + [self.enableKeychainSyncing setState:NSControlStateValueOn]; } else if (self.circle.isOutOfCircle) { - [self.enableKeychainSyncing setState:NSOffState]; + [self.enableKeychainSyncing setState:NSControlStateValueOff]; } else { - [self.enableKeychainSyncing setState:NSMixedState]; + [self.enableKeychainSyncing setState:NSControlStateValueMixed]; } } diff --git a/OSX/Keychain/KDSecCircle.m b/OSX/Keychain/KDSecCircle.m index f5b8d448..66e36e7c 100644 --- a/OSX/Keychain/KDSecCircle.m +++ b/OSX/Keychain/KDSecCircle.m @@ -57,6 +57,8 @@ { // XXX: assert not on main_queue CFErrorRef err = NULL; + + SOSCCValidateUserPublic(NULL); // requires the account queue - makes the rest of this wait for fresh info. This used to happen in SOSCCThisDeviceIsInCircle(below) before we made it use cached info. SOSCCStatus newRawStatus = SOSCCThisDeviceIsInCircle(&err); NSArray *peerInfos = (__bridge NSArray *) SOSCCCopyApplicantPeerInfo(&err); NSMutableArray *newApplicants = [[NSMutableArray alloc] initWithCapacity:peerInfos.count]; diff --git a/OSX/authd/authdb.c b/OSX/authd/authdb.c index df25c569..49967d0e 100644 --- a/OSX/authd/authdb.c +++ b/OSX/authd/authdb.c @@ -23,7 +23,7 @@ AUTHD_DEFINE_LOG #define AUTH_STR(x) #x #define AUTH_STRINGIFY(x) AUTH_STR(x) -#define AUTHDB_VERSION 1 +#define AUTHDB_VERSION 2 #define AUTHDB_VERSION_STRING AUTH_STRINGIFY(AUTHDB_VERSION) #define AUTHDB_BUSY_DELAY 1 @@ -105,7 +105,16 @@ static const char * const authdb_upgrade_sql[] = { "value TEXT NOT NULL" ");" "CREATE INDEX b_r_id ON buttons(r_id);" - "INSERT INTO config VALUES('version', "AUTHDB_VERSION_STRING");" + "INSERT INTO config VALUES('version', '1');" , + + // version 2 of the database + "CREATE TABLE rules_history (" + "timestamp DATETIME DEFAULT CURRENT_TIMESTAMP," + "rule TEXT NOT NULL," + "version INTEGER NOT NULL," + "source TEXT NOT NULL," + "operation INTEGER NOT NULL" + ");" }; static sqlite3 * _create_handle(authdb_t db); @@ -134,7 +143,8 @@ struct _db_upgrade_stages { }; static struct _db_upgrade_stages auth_upgrade_script[] = { - { .pre = -1, .main = 0, .post = -1 } // Create version AUTHDB_VERSION databse. + { .pre = -1, .main = 0, .post = -1 }, // Create version AUTHDB_VERSION databse. + { .pre = -1, .main = 1, .post = -1} }; static int32_t _db_run_script(authdb_connection_t dbconn, int number) @@ -174,7 +184,7 @@ static int32_t _db_upgrade_from_version(authdb_connection_t dbconn, int32_t vers return s3e; } -static void _db_load_data(authdb_connection_t dbconn, auth_items_t config) +static CFDictionaryRef _copy_plist(auth_items_t config, CFAbsoluteTime *outTs) { CFURLRef authURL = NULL; CFPropertyListRef plist = NULL; @@ -184,34 +194,96 @@ static void _db_load_data(authdb_connection_t dbconn, auth_items_t config) CFTypeRef value = NULL; CFAbsoluteTime ts = 0; CFAbsoluteTime old_ts = 0; - Boolean ok; - + Boolean ok; authURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(AUTHDB_DATA), kCFURLPOSIXPathStyle, false); require_action(authURL != NULL, done, os_log_error(AUTHD_LOG, "authdb: file not found %{public}s", AUTHDB_DATA)); - - ok = CFURLCopyResourcePropertyForKey(authURL, kCFURLContentModificationDateKey, &value, &err); + + ok = CFURLCopyResourcePropertyForKey(authURL, kCFURLContentModificationDateKey, &value, &err); require_action(ok && value != NULL, done, os_log_error(AUTHD_LOG, "authdb: failed to get modification date: %{public}@", err)); if (CFGetTypeID(value) == CFDateGetTypeID()) { ts = CFDateGetAbsoluteTime(value); + if (outTs) { + *outTs = ts; + } } - old_ts = auth_items_get_double(config, "data_ts"); - - // SEED: BUG: Fast User Switching Not Working - // After Mavericks => Yosemite upgrade install, the new Yosemite rule "system.login.fus" was missing. - // Somehow (probably during install) ts < old_ts, even though that should never happen. - // Solution: always import plist and update db when time stamps don't match. - // After a successful import, old_ts = ts below. - if (ts != old_ts) { + if (config) { + old_ts = auth_items_get_double(config, "data_ts"); + } + + // SEED: BUG: Fast User Switching Not Working + // After Mavericks => Yosemite upgrade install, the new Yosemite rule "system.login.fus" was missing. + // Somehow (probably during install) ts < old_ts, even though that should never happen. + // Solution: always import plist and update db when time stamps don't match. + // After a successful import, old_ts = ts below. + if (!config || (ts != old_ts)) { os_log_debug(AUTHD_LOG, "authdb: %{public}s modified old=%f, new=%f", AUTHDB_DATA, old_ts, ts); CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, authURL, &data, NULL, NULL, (SInt32*)&rc); require_noerr_action(rc, done, os_log_error(AUTHD_LOG, "authdb: failed to load %{public}s", AUTHDB_DATA)); - + plist = CFPropertyListCreateWithData(kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL, &err); require_action(err == NULL, done, os_log_error(AUTHD_LOG, "authdb: failed to read plist: %{public}@", err)); - - if (authdb_import_plist(dbconn, plist, true)) { + } + +done: + CFReleaseSafe(authURL); + CFReleaseSafe(value); + CFReleaseSafe(err); + CFReleaseSafe(data); + + return plist; +} + +static void _repair_broken_kofn_right(authdb_connection_t dbconn, const char *right, CFDictionaryRef plist) +{ + if (!right || !dbconn) { + return; + } + + CFDictionaryRef localPlist = plist; + if (!localPlist) { + localPlist = _copy_plist(NULL, NULL); + } + + // import the broken right + os_log(AUTHD_LOG, "Repairing broken right %{public}s", right); + authdb_import_plist(dbconn, localPlist, FALSE, right); + + if (!plist && localPlist) { + CFRelease(localPlist); + } +} + +static void _repair_all_kofns(authdb_connection_t dbconn, auth_items_t config) +{ + // we want plist to be returned always and not only when never + CFDictionaryRef plist = _copy_plist(NULL, NULL); + + if (!plist) { + os_log_error(AUTHD_LOG, "authdb: unable to repair kofns"); + return; + } + + authdb_step(dbconn, "SELECT name FROM rules WHERE (rules.kofn > 0) AND (id NOT IN (SELECT r_id FROM delegates_map WHERE r_id = id))", + NULL, ^bool(auth_items_t data) { + const char *name = auth_items_get_string(data, "name"); + if (name) { + _repair_broken_kofn_right(dbconn, name, plist); + } + return false; + }); + + CFRelease(plist); +} + +static void _db_load_data(authdb_connection_t dbconn, auth_items_t config) +{ + CFAbsoluteTime ts = 0; + CFDictionaryRef plist = _copy_plist(config, &ts); + + if (plist) { + if (authdb_import_plist(dbconn, plist, true, NULL)) { os_log_debug(AUTHD_LOG, "authdb: updating data_ts"); auth_items_t update = auth_items_create(); auth_items_set_double(update, "data_ts", ts); @@ -219,13 +291,7 @@ static void _db_load_data(authdb_connection_t dbconn, auth_items_t config) CFReleaseSafe(update); } } - -done: - CFReleaseSafe(value); - CFReleaseSafe(authURL); CFReleaseSafe(plist); - CFReleaseSafe(err); - CFReleaseSafe(data); } static bool _truncate_db(authdb_connection_t dbconn) @@ -531,6 +597,7 @@ bool authdb_maintenance(authdb_connection_t dbconn) _db_load_data(dbconn, config); + _repair_all_kofns(dbconn, config); done: CFReleaseSafe(config); os_log_debug(AUTHD_LOG, "authdb: finished maintenance"); @@ -859,7 +926,7 @@ done: } static void -_import_rules(authdb_connection_t dbconn, CFMutableArrayRef rules, bool version_check, CFAbsoluteTime now) +_import_rules(authdb_connection_t dbconn, CFMutableArrayRef rules, bool version_check, CFAbsoluteTime now, const char *nameFilter) { CFMutableArrayRef notcommited = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFIndex count = CFArrayGetCount(rules); @@ -867,6 +934,11 @@ _import_rules(authdb_connection_t dbconn, CFMutableArrayRef rules, bool version_ for (CFIndex i = 0; i < count; i++) { rule_t rule = (rule_t)CFArrayGetValueAtIndex(rules, i); + if (nameFilter && (strcmp(nameFilter, rule_get_name(rule)) != 0)) { + // current rule name does not match the requested filter + continue; + } + bool update = false; if (version_check) { if (rule_get_id(rule) != 0) { // rule already exists see if we need to update @@ -922,7 +994,7 @@ _import_rules(authdb_connection_t dbconn, CFMutableArrayRef rules, bool version_ } bool -authdb_import_plist(authdb_connection_t dbconn, CFDictionaryRef plist, bool version_check) +authdb_import_plist(authdb_connection_t dbconn, CFDictionaryRef plist, bool version_check, const char *name) { bool result = false; @@ -955,10 +1027,10 @@ authdb_import_plist(authdb_connection_t dbconn, CFDictionaryRef plist, bool vers if (!count) break; - _import_rules(dbconn, rules, version_check, now); + _import_rules(dbconn, rules, version_check, now, name); } - _import_rules(dbconn, rights, version_check, now); + _import_rules(dbconn, rights, version_check, now, name); if (CFArrayGetCount(rights) == 0) { result = true; diff --git a/OSX/authd/authdb.h b/OSX/authd/authdb.h index 6e5f6b64..5c31c62a 100644 --- a/OSX/authd/authdb.h +++ b/OSX/authd/authdb.h @@ -44,7 +44,7 @@ int32_t authdb_exec(authdb_connection_t, const char *); AUTH_NONNULL_ALL bool authdb_transaction(authdb_connection_t, AuthDBTransactionType, bool (^t)(void)); -AUTH_NONNULL1 AUTH_NONNULL2 AUTH_NONNULL3 +AUTH_NONNULL1 AUTH_NONNULL2 bool authdb_step(authdb_connection_t, const char * sql, void (^bind_stmt)(sqlite3_stmt* stmt), authdb_iterator_t iter); AUTH_NONNULL_ALL @@ -56,9 +56,9 @@ int32_t authdb_set_key_value(authdb_connection_t, const char * table, auth_items AUTH_NONNULL_ALL void authdb_checkpoint(authdb_connection_t); -AUTH_NONNULL_ALL -bool authdb_import_plist(authdb_connection_t,CFDictionaryRef,bool); - +AUTH_NONNULL1 AUTH_NONNULL2 +bool authdb_import_plist(authdb_connection_t, CFDictionaryRef, bool, const char * name); + #pragma mark - #pragma mark authdb_connection_t diff --git a/OSX/authd/authitems.c b/OSX/authd/authitems.c index 0468eaf7..463884e2 100644 --- a/OSX/authd/authitems.c +++ b/OSX/authd/authitems.c @@ -23,8 +23,6 @@ struct _auth_item_s { AuthorizationItem data; uint32_t type; size_t bufLen; - - CFStringRef cfKey; }; static const char * @@ -43,21 +41,6 @@ auth_item_get_string(auth_item_t item) return item->data.value; } -static CFStringRef -auth_item_get_cf_key(auth_item_t item) -{ - if (!item->cfKey) { - item->cfKey = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, item->data.name, kCFStringEncodingUTF8, kCFAllocatorNull); - } - return item->cfKey; -} - -static AuthorizationItem * -auth_item_get_auth_item(auth_item_t item) -{ - return &item->data; -} - static xpc_object_t auth_item_copy_auth_item_xpc(auth_item_t item) { @@ -90,9 +73,7 @@ static void _auth_item_finalize(CFTypeRef value) { auth_item_t item = (auth_item_t)value; - - CFReleaseNull(item->cfKey); - + if (item->data.name) { free((void*)item->data.name); /* cannot set item->data.name to NULL because item->data.name is non-nullable public API (rdar://problem/32235322) @@ -362,6 +343,16 @@ _auth_items_equal(CFTypeRef value1, CFTypeRef value2) return CFEqual(items1->dictionary, items2->dictionary); } +static void +auth_items_add_item(auth_items_t items, auth_item_t item) +{ + CFStringRef cfName = CFStringCreateWithCString(kCFAllocatorDefault, item->data.name, kCFStringEncodingUTF8); + if (cfName) { + CFDictionarySetValue(items->dictionary, cfName, item); + CFRelease(cfName); + } +} + static CFStringRef _auth_items_copy_description(CFTypeRef value) { @@ -430,8 +421,8 @@ _auth_items_parse_xpc(auth_items_t items, const xpc_object_t data) auth_item_t item = auth_item_create_with_xpc(value); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } return true; @@ -474,36 +465,6 @@ auth_items_get_count(auth_items_t items) return (size_t)CFDictionaryGetCount(items->dictionary); } -AuthorizationItemSet * -auth_items_get_item_set(auth_items_t items) -{ - uint32_t count = (uint32_t)CFDictionaryGetCount(items->dictionary); - if (count) { - size_t size = count * sizeof(AuthorizationItem); - if (items->set.items == NULL) { - items->set.items = calloc(1u, size); - require(items->set.items != NULL, done); - } else { - if (count > items->set.count) { - items->set.items = realloc(items->set.items, size); - require_action(items->set.items != NULL, done, items->set.count = 0); - } - } - items->set.count = count; - CFTypeRef keys[count], values[count]; - CFDictionaryGetKeysAndValues(items->dictionary, keys, values); - for (uint32_t i = 0; i < count; i++) { - auth_item_t item = (auth_item_t)values[i]; - items->set.items[i] = *auth_item_get_auth_item(item); - } - } else { - items->set.count = 0; - } - -done: - return &items->set; -} - xpc_object_t auth_items_export_xpc(auth_items_t items) { @@ -584,8 +545,8 @@ auth_items_set_key(auth_items_t items, const char *key) if (!item) { item = auth_item_create(AI_TYPE_RIGHT, key, NULL, 0, 0); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } } @@ -654,7 +615,7 @@ auth_items_copy(auth_items_t items, auth_items_t src) } CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull); auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup); - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); + if (item) auth_items_add_item(items, item); CFReleaseSafe(lookup); return true; }); @@ -667,8 +628,7 @@ auth_items_content_copy(auth_items_t items, auth_items_t src) CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull); auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup); auth_item_t new_item = auth_item_create(item->type, item->data.name, item->data.value, item->data.valueLength, item->data.flags); - if (new_item) - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(new_item), new_item); + if (new_item) auth_items_add_item(items, new_item); CFReleaseSafe(lookup); CFReleaseSafe(new_item); return true; @@ -687,8 +647,11 @@ auth_items_copy_with_flags(auth_items_t items, auth_items_t src, uint32_t flags) auth_items_iterate(src, ^bool(const char *key) { if (auth_items_check_flags(src, key, flags)) { CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull); + if (CFDictionaryContainsKey(items->dictionary, lookup)) { + CFDictionaryRemoveValue(items->dictionary, lookup); // we do not want to have preserved unretained key + } auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup); - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); + if (item) auth_items_add_item(items, item); CFReleaseSafe(lookup); } return true; @@ -704,10 +667,11 @@ auth_items_content_copy_with_flags(auth_items_t items, auth_items_t src, uint32_ CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull); auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup); auth_item_t new_item = auth_item_create(item->type, item->data.name, item->data.value, item->data.valueLength, item->data.flags); - if (new_item) - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(new_item), new_item); + if (new_item) { + auth_items_add_item(items, new_item); + CFRelease(new_item); + } CFReleaseSafe(lookup); - CFReleaseSafe(new_item); } return true; }); @@ -755,8 +719,8 @@ auth_items_set_string(auth_items_t items, const char *key, const char *value) } else { item = auth_item_create(AI_TYPE_STRING, key, value, valLen, 0); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } } @@ -791,8 +755,8 @@ auth_items_set_data(auth_items_t items, const char *key, const void *value, size } else { item = auth_item_create(AI_TYPE_DATA, key, value, len, 0); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } } @@ -848,8 +812,8 @@ auth_items_set_bool(auth_items_t items, const char *key, bool value) } else { item = auth_item_create(AI_TYPE_BOOL, key, &value, sizeof(bool), 0); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } } @@ -888,8 +852,8 @@ auth_items_set_int(auth_items_t items, const char *key, int32_t value) } else { item = auth_item_create(AI_TYPE_INT, key, &value, sizeof(int32_t), 0); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } } @@ -928,8 +892,8 @@ auth_items_set_uint(auth_items_t items, const char *key, uint32_t value) } else { item = auth_item_create(AI_TYPE_UINT, key, &value, sizeof(uint32_t), 0); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } } @@ -968,8 +932,8 @@ auth_items_set_int64(auth_items_t items, const char *key, int64_t value) } else { item = auth_item_create(AI_TYPE_INT64, key, &value, sizeof(int64_t), 0); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } } @@ -1008,8 +972,8 @@ auth_items_set_uint64(auth_items_t items, const char *key, uint64_t value) } else { item = auth_item_create(AI_TYPE_UINT64, key, &value, sizeof(uint64_t), 0); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } } @@ -1047,8 +1011,8 @@ void auth_items_set_double(auth_items_t items, const char *key, double value) } else { item = auth_item_create(AI_TYPE_DOUBLE, key, &value, sizeof(double), 0); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } } @@ -1101,8 +1065,8 @@ void auth_items_set_value(auth_items_t items, const char *key, uint32_t type, ui { auth_item_t item = auth_item_create(type, key, value, len, flags); if (item) { - CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item); - CFReleaseSafe(item); + auth_items_add_item(items, item); + CFRelease(item); } } @@ -1226,23 +1190,18 @@ static auth_item_t _find_right_item(auth_rights_t rights, const char * key) { auth_item_t item = NULL; - CFStringRef lookup = NULL; require(key != NULL, done); - - lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull); - require(lookup != NULL, done); - + CFIndex count = CFArrayGetCount(rights->array); for (CFIndex i = 0; i < count; i++) { auth_item_t tmp = (auth_item_t)CFArrayGetValueAtIndex(rights->array, i); - if (tmp && CFEqual(auth_item_get_cf_key(tmp), lookup)) { + if (tmp && strcmp(tmp->data.name, key) == 0) { item = tmp; break; } } done: - CFReleaseSafe(lookup); return item; } @@ -1299,17 +1258,15 @@ bool auth_rights_exist(auth_rights_t rights, const char *key) void auth_rights_remove(auth_rights_t rights, const char *key) { - CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull); CFIndex count = CFArrayGetCount(rights->array); for (CFIndex i = 0; i < count; i++) { auth_item_t item = (auth_item_t)CFArrayGetValueAtIndex(rights->array, i); - if (CFEqual(auth_item_get_cf_key(item), lookup)) { + if (item && strcmp(item->data.name, key) == 0) { CFArrayRemoveValueAtIndex(rights->array, i); i--; count--; } } - CFReleaseSafe(lookup); } void auth_rights_clear(auth_rights_t rights) diff --git a/OSX/authd/authitems.h b/OSX/authd/authitems.h index 48bd82df..57319a5a 100644 --- a/OSX/authd/authitems.h +++ b/OSX/authd/authitems.h @@ -46,9 +46,6 @@ auth_items_t auth_items_create_copy(auth_items_t); AUTH_WARN_RESULT AUTH_NONNULL_ALL size_t auth_items_get_count(auth_items_t); -AUTH_WARN_RESULT AUTH_NONNULL_ALL -AuthorizationItemSet * auth_items_get_item_set(auth_items_t); - AUTH_WARN_RESULT AUTH_NONNULL_ALL xpc_object_t auth_items_export_xpc(auth_items_t); diff --git a/OSX/authd/authorization.plist b/OSX/authd/authorization.plist index 179b0d5d..e9ec5393 100644 --- a/OSX/authd/authorization.plist +++ b/OSX/authd/authorization.plist @@ -892,13 +892,13 @@ See remaining rules for examples. loginwindow:login builtin:login-begin builtin:reset-password,privileged + loginwindow:FDESupport,privileged builtin:forward-login,privileged builtin:auto-login,privileged builtin:authenticate,privileged PKINITMechanism:auth,privileged builtin:login-success loginwindow:success - loginwindow:FDESupport,privileged HomeDirMechanism:login,privileged HomeDirMechanism:status MCXMechanism:login @@ -906,7 +906,7 @@ See remaining rules for examples. loginwindow:done version - 6 + 7 system.login.fus @@ -1219,7 +1219,7 @@ See remaining rules for examples. class user comment - Used by AuthorizationExecuteWithPrivileges(...). + Used by AuthorizationExecuteWithPrivileges(...). AuthorizationExecuteWithPrivileges() is used by programs requesting to run a tool as root (e.g., some installers). group @@ -1504,7 +1504,7 @@ See remaining rules for examples. rule rule authenticate-session-owner - + com.apple.security.sudo class @@ -1516,7 +1516,7 @@ See remaining rules for examples. entitled authenticate-session-owner - + system.preferences.continuity class @@ -1556,6 +1556,45 @@ See remaining rules for examples. version 1 + com.apple.app-sandbox.create-symlink + + comment + Authorize an app-sandboxed application to install a symlink into /usr/local/bin. + class + rule + rule + authenticate-admin-nonshared + shared + + timeout + 60 + + com.apple.app-sandbox.set-attributes + + comment + Authorize an app-sandboxed application to change permissions on a privileged file. + class + rule + rule + authenticate-admin-nonshared + shared + + timeout + 60 + + com.apple.app-sandbox.replace-file + + comment + Authorize an app-sandboxed application to save (overwrite) a file in a privileged location. + class + rule + rule + authenticate-admin-nonshared + shared + + timeout + 60 + rules @@ -1621,7 +1660,7 @@ See remaining rules for examples. version 1 - + authenticate-admin class @@ -1653,8 +1692,8 @@ See remaining rules for examples. class user comment - Like the default rule, but - credentials remain valid for only 30 seconds after they've + Like the default rule, but + credentials remain valid for only 30 seconds after they've been obtained. An acquired credential is shared by all clients. group @@ -1788,8 +1827,8 @@ See remaining rules for examples. class user comment - Default rule. - Credentials remain valid for 5 minutes after they've been obtained. + Default rule. + Credentials remain valid for 5 minutes after they've been obtained. An acquired credential is shared by all clients. group @@ -2129,7 +2168,7 @@ See remaining rules for examples. timeout 36000 - + diff --git a/OSX/authd/authtoken.c b/OSX/authd/authtoken.c index 995be9d4..f7ed85b4 100644 --- a/OSX/authd/authtoken.c +++ b/OSX/authd/authtoken.c @@ -394,6 +394,10 @@ auth_token_credentials_iterate(auth_token_t auth, credential_iterator_t iter) dispatch_sync(auth->dispatch_queue, ^{ CFIndex count = CFSetGetCount(auth->credentials); + if (count > 128) { // Variable Length Arrays; AuthD + // auth_token usually contains 0 or 1 credential + count = 128; + } CFTypeRef values[count]; CFSetGetValues(auth->credentials, values); for (CFIndex i = 0; i < count; i++) { @@ -416,27 +420,6 @@ auth_token_set_right(auth_token_t auth, credential_t right) }); } -bool -auth_token_rights_iterate(auth_token_t auth, credential_iterator_t iter) -{ - __block bool result = false; - - dispatch_sync(auth->dispatch_queue, ^{ - CFIndex count = CFSetGetCount(auth->authorized_rights); - CFTypeRef values[count]; - CFSetGetValues(auth->authorized_rights, values); - for (CFIndex i = 0; i < count; i++) { - credential_t right = (credential_t)values[i]; - result = iter(right); - if (!result) { - break; - } - } - }); - - return result; -} - CFTypeRef auth_token_copy_entitlement_value(auth_token_t auth, const char * entitlement) { diff --git a/OSX/authd/authtoken.h b/OSX/authd/authtoken.h index d4b9db58..0ea9990d 100644 --- a/OSX/authd/authtoken.h +++ b/OSX/authd/authtoken.h @@ -75,9 +75,6 @@ bool auth_token_credentials_iterate(auth_token_t, credential_iterator_t iter); AUTH_NONNULL_ALL void auth_token_set_right(auth_token_t,credential_t); -AUTH_NONNULL_ALL -bool auth_token_rights_iterate(auth_token_t, credential_iterator_t iter); - AUTH_NONNULL_ALL CFTypeRef auth_token_copy_entitlement_value(auth_token_t, const char * entitlement); diff --git a/OSX/authd/com.apple.authd.sb b/OSX/authd/com.apple.authd.sb index c4f89fb5..88415cfc 100644 --- a/OSX/authd/com.apple.authd.sb +++ b/OSX/authd/com.apple.authd.sb @@ -14,6 +14,9 @@ (literal "/private/var/db/mds/system/mds.lock") (subpath (param "TMP_DIR"))) +(allow network-outbound + (literal "/private/var/run/systemkeychaincheck.socket")) + (allow mach-lookup (global-name "com.apple.CoreAuthentication.agent.libxpc") (global-name "com.apple.CoreAuthentication.daemon.libxpc") diff --git a/OSX/authd/engine.c b/OSX/authd/engine.c index 848a0b8f..e9f009b0 100644 --- a/OSX/authd/engine.c +++ b/OSX/authd/engine.c @@ -41,6 +41,8 @@ static OSStatus _evaluate_rule(engine_t, rule_t, bool *); static bool _preevaluate_class_rule(engine_t engine, rule_t rule); static bool _preevaluate_rule(engine_t engine, rule_t rule); +static uint64_t global_engine_count; + enum { kEngineHintsFlagTemporary = (1 << 30) }; @@ -84,6 +86,8 @@ struct _engine_s { rule_t authenticateRule; bool dismissed; + + uint64_t engine_index; }; static void @@ -179,6 +183,7 @@ engine_create(connection_t conn, auth_token_t auth) engine->mechanism_agents = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + engine->engine_index = global_engine_count++; done: return engine; } @@ -267,7 +272,7 @@ _set_localization_hints(authdb_connection_t dbconn, auth_items_t hints, rule_t r static void _set_session_hints(engine_t engine, rule_t rule) { - os_log_debug(AUTHD_LOG, "engine: ** prepare agent hints for rule %{public}s", rule_get_name(rule)); + os_log_debug(AUTHD_LOG, "engine %lld: ** prepare agent hints for rule %{public}s", engine->engine_index, rule_get_name(rule)); if (_evaluate_user_credential_for_rule(engine, engine->sessionCredential, rule, true, true, NULL) == errAuthorizationSuccess) { const char * tmp = credential_get_name(engine->sessionCredential); if (tmp != NULL) { @@ -293,7 +298,7 @@ _evaluate_credential_for_rule(engine_t engine, credential_t cred, rule_t rule, b if (credential_is_right(cred) && credential_get_valid(cred) && _compare_string(engine->currentRightName, credential_get_name(cred))) { if (!ignoreShared) { if (!rule_get_shared(rule) && credential_get_shared(cred)) { - os_log_error(AUTHD_LOG, "engine: - shared right %{public}s (does NOT satisfy rule)", credential_get_name(cred)); + os_log_error(AUTHD_LOG, "Shared right %{public}s (does NOT satisfy rule) (engine %lld)", credential_get_name(cred), engine->engine_index); if (reason) { *reason = unknownReason; } return errAuthorizationDenied; } @@ -313,47 +318,47 @@ static OSStatus _evaluate_user_credential_for_rule(engine_t engine, credential_t cred, rule_t rule, bool ignoreShared, bool sessionOwner, enum Reason * reason) { const char * cred_label = sessionOwner ? "session owner" : "credential"; - os_log(AUTHD_LOG, "engine: - validating %{public}s%{public}s %{public}s (%i) for %{public}s", credential_get_shared(cred) ? "shared " : "", + os_log(AUTHD_LOG, "Validating %{public}s%{public}s %{public}s (%i) for %{public}s (engine %lld)", credential_get_shared(cred) ? "shared " : "", cred_label, credential_get_name(cred), credential_get_uid(cred), - rule_get_name(rule)); + rule_get_name(rule), + engine->engine_index); if (rule_get_class(rule) != RC_USER) { - os_log(AUTHD_LOG, "engine: - invalid rule class %i (denied)", rule_get_class(rule)); + os_log(AUTHD_LOG, "Invalid rule class %i (engine %lld)", rule_get_class(rule), engine->engine_index); return errAuthorizationDenied; } if (credential_get_valid(cred) != true) { - os_log(AUTHD_LOG, "engine: - %{public}s %i invalid (does NOT satisfy rule)", cred_label, credential_get_uid(cred)); + os_log(AUTHD_LOG, "%{public}s %i invalid (does NOT satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), engine->engine_index); if (reason) { *reason = invalidPassphrase; } return errAuthorizationDenied; } if (engine->now - credential_get_creation_time(cred) > rule_get_timeout(rule)) { - os_log(AUTHD_LOG, "engine: - %{public}s %i expired '%f > %lli' (does NOT satisfy rule)", cred_label, credential_get_uid(cred), - (engine->now - credential_get_creation_time(cred)), rule_get_timeout(rule)); + os_log(AUTHD_LOG, "%{public}s %i expired '%f > %lli' (does NOT satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), + (engine->now - credential_get_creation_time(cred)), rule_get_timeout(rule), engine->engine_index); if (reason) { *reason = unknownReason; } return errAuthorizationDenied; } - if (!ignoreShared) { if (!rule_get_shared(rule) && credential_get_shared(cred)) { - os_log(AUTHD_LOG, "engine: - shared %{public}s %i (does NOT satisfy rule)", cred_label, credential_get_uid(cred)); + os_log(AUTHD_LOG, "Shared %{public}s %i (does NOT satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), engine->engine_index); if (reason) { *reason = unknownReason; } return errAuthorizationDenied; } } if (credential_get_uid(cred) == 0) { - os_log(AUTHD_LOG, "engine: - %{public}s %i has uid 0 (does satisfy rule)", cred_label, credential_get_uid(cred)); + os_log(AUTHD_LOG, "%{public}s %i has uid 0 (does satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), engine->engine_index); return errAuthorizationSuccess; } if (rule_get_session_owner(rule)) { if (credential_get_uid(cred) == session_get_uid(auth_token_get_session(engine->auth))) { - os_log(AUTHD_LOG, "engine: - %{public}s %i is session owner (does satisfy rule)", cred_label, credential_get_uid(cred)); + os_log(AUTHD_LOG, "%{public}s %i is session owner (does satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), engine->engine_index); return errAuthorizationSuccess; } } @@ -373,7 +378,7 @@ _evaluate_user_credential_for_rule(engine_t engine, credential_t cred, rule_t ru } if (credential_check_membership(cred, rule_get_group(rule))) { - os_log(AUTHD_LOG, "engine: - %{public}s %i is member of group %{public}s (does satisfy rule)", cred_label, credential_get_uid(cred), rule_get_group(rule)); + os_log(AUTHD_LOG, "%{public}s %i is member of group %{public}s (does satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), rule_get_group(rule), engine->engine_index); return errAuthorizationSuccess; } else { if (reason) { *reason = userNotInGroup; } @@ -383,7 +388,7 @@ _evaluate_user_credential_for_rule(engine_t engine, credential_t cred, rule_t ru if (reason) { *reason = unacceptableUser; } } - os_log(AUTHD_LOG, "engine: - %{public}s %i (does NOT satisfy rule), reason %d", cred_label, credential_get_uid(cred), reason ? *reason : -1); + os_log(AUTHD_LOG, "%{public}s %i (does NOT satisfy rule), reason %d (engine %lld)", cred_label, credential_get_uid(cred), reason ? *reason : -1, engine->engine_index); return errAuthorizationDenied; } @@ -433,9 +438,11 @@ _extract_password_from_la(engine_t engine) CFDataRef passdata = LACopyCredential(engine->la_context, kLACredentialTypeExtractablePasscode, NULL); if (passdata) { if (CFDataGetBytePtr(passdata)) { + os_log_debug(AUTHD_LOG, "engine %lld: LA credentials retrieved", engine->engine_index); auth_items_set_data(engine->context, kAuthorizationEnvironmentPassword, CFDataGetBytePtr(passdata), CFDataGetLength(passdata)); } else { const char *empty_pass = "\0"; // authd code is unable to process empty strings so passing empty string as terminator only + os_log_debug(AUTHD_LOG, "engine %lld: LA credentials empty", engine->engine_index); auth_items_set_data(engine->context, kAuthorizationEnvironmentPassword, empty_pass, 1); } CFRelease(passdata); @@ -468,6 +475,7 @@ _evaluate_mechanisms(engine_t engine, CFArrayRef mechanisms) CFMutableDictionaryRef options = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(options, key, value); la_result = LACopyResultOfPolicyEvaluation(engine->la_context, kLAPolicyDeviceOwnerAuthentication, options, NULL); + os_log_debug(AUTHD_LOG, "engine %lld: Retrieve LA evaluate result: %d", engine->engine_index, la_result != NULL); CFReleaseSafe(options); } CFReleaseSafe(key); @@ -478,7 +486,7 @@ _evaluate_mechanisms(engine_t engine, CFArrayRef mechanisms) mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(mechanisms, i); if (mechanism_get_type(mech)) { - os_log_debug(AUTHD_LOG, "engine: running builtin mechanism %{public}s (%li of %li)", mechanism_get_string(mech), i+1, count); + os_log_debug(AUTHD_LOG, "engine %lld: running builtin mechanism %{public}s (%li of %li)", engine->engine_index, mechanism_get_string(mech), i+1, count); result = _evaluate_builtin_mechanism(engine, mech); } else { bool shoud_run_agent = true; // evaluate comes from sheet -> we may not want to run standard SecurityAgent or authhost @@ -487,7 +495,7 @@ _evaluate_mechanisms(engine_t engine, CFArrayRef mechanisms) if (strcmp(mechanism_get_string(mech), "builtin:authenticate") == 0) { // set the UID the same way as SecurityAgent would if (auth_items_exist(engine->context, "sheet-uid")) { - os_log_debug(AUTHD_LOG, "engine: setting sheet UID %d to the context", auth_items_get_uint(engine->context, "sheet-uid")); + os_log_debug(AUTHD_LOG, "engine %lld: setting sheet UID %d to the context", engine->engine_index, auth_items_get_uint(engine->context, "sheet-uid")); auth_items_set_uint(engine->context, "uid", auth_items_get_uint(engine->context, "sheet-uid")); } @@ -496,10 +504,10 @@ _evaluate_mechanisms(engine_t engine, CFArrayRef mechanisms) // otherwise we need to check la_result if (auth_items_exist(engine->context, AGENT_CONTEXT_AP_PAM_SERVICE_NAME) || auth_items_exist(engine->context, kAuthorizationEnvironmentPassword)) { // do not try to get credentials as it has been already passed by sheet - os_log(AUTHD_LOG, "engine: ignoring builtin sheet authenticate"); + os_log_debug(AUTHD_LOG, "engine %lld: ignoring builtin sheet authenticate", engine->engine_index); } else { // sheet itself did the authenticate the user - os_log(AUTHD_LOG, "engine: running builtin sheet authenticate"); + os_log_debug(AUTHD_LOG, "engine %lld: running builtin sheet authenticate", engine->engine_index); sheet_evaluation = true; if (!la_result || TKGetSmartcardSetting(kTKEnforceSmartcard) != 0) { result = kAuthorizationResultDeny; // no la_result => evaluate did not pass for sheet method. Enforced smartcard => no way to use sheet based evaluation @@ -508,21 +516,21 @@ _evaluate_mechanisms(engine_t engine, CFArrayRef mechanisms) shoud_run_agent = false; // SecurityAgent should not be run for builtin:authenticate } else if (strcmp(mechanism_get_string(mech), "builtin:authenticate,privileged") == 0) { if (sheet_evaluation) { - os_log(AUTHD_LOG, "engine: running builtin sheet privileged authenticate"); + os_log_debug(AUTHD_LOG, "engine %lld: running builtin sheet privileged authenticate", engine->engine_index); shoud_run_agent = false; if (!la_result || TKGetSmartcardSetting(kTKEnforceSmartcard) != 0) { // should not get here under normal circumstances but we need to handle this case as well result = kAuthorizationResultDeny; // no la_result => evaluate did not pass. Enforced smartcard => no way to use sheet based evaluation } } else { // should_run_agent has to be set to true because we want authorizationhost to verify the credentials - os_log(AUTHD_LOG, "engine: running sheet privileged authenticate"); + os_log_debug(AUTHD_LOG, "engine %lld: running sheet privileged authenticate", engine->engine_index); } } } if (shoud_run_agent) { agent_t agent = _get_agent(engine, mech, true, i == 0); - require_action(agent != NULL, done, result = kAuthorizationResultUndefined; os_log_error(AUTHD_LOG, "engine: error creating mechanism agent")); + require_action(agent != NULL, done, result = kAuthorizationResultUndefined; os_log_error(AUTHD_LOG, "Error creating mechanism agent (engine %lld)", engine->engine_index)); // check if any agent has been interrupted (it necessary if interrupt will come during creation) CFIndex j; @@ -534,7 +542,7 @@ _evaluate_mechanisms(engine_t engine, CFArrayRef mechanisms) } } if (j < i) { - os_log(AUTHD_LOG, "engine: mechanisms interrupted"); + os_log(AUTHD_LOG, "engine %lld: mechanisms interrupted", engine->engine_index); char * buf = NULL; asprintf(&buf, "evaluation interrupted by %s; restarting evaluation there", mechanism_get_string(agent_get_mechanism(agent1))); ccaudit_log_mechanism(ccaudit, engine->currentRightName, mechanism_get_string(agent_get_mechanism(agent1)), kAuthorizationResultAllow, buf); @@ -552,7 +560,7 @@ _evaluate_mechanisms(engine_t engine, CFArrayRef mechanisms) continue; } - os_log(AUTHD_LOG, "engine: running mechanism %{public}s (%li of %li)", mechanism_get_string(agent_get_mechanism(agent)), i+1, count); + os_log(AUTHD_LOG, "engine %lld: running mechanism %{public}s (%li of %li)", engine->engine_index, mechanism_get_string(agent_get_mechanism(agent)), i+1, count); result = agent_run(agent, hints, context, engine->immutable_hints); @@ -584,7 +592,7 @@ _evaluate_mechanisms(engine_t engine, CFArrayRef mechanisms) } if (interrupted) { - os_log(AUTHD_LOG, "engine: mechanisms interrupted"); + os_log_info(AUTHD_LOG, "Mechanisms interrupted (engine %lld)", engine->engine_index); enum Reason reason = worldChanged; auth_items_set_data(hints, AGENT_HINT_RETRY_REASON, &reason, sizeof(reason)); result = kAuthorizationResultAllow; @@ -635,7 +643,7 @@ done: return errAuthorizationInternal; default: { - os_log_error(AUTHD_LOG, "engine: unexpected error result"); + os_log_error(AUTHD_LOG, "Evaluate - unexpected result %llu (engine %lld)", result, engine->engine_index); return errAuthorizationInternal; } } @@ -646,7 +654,7 @@ _evaluate_authentication(engine_t engine, rule_t rule) { OSStatus status = errAuthorizationDenied; ccaudit_t ccaudit = ccaudit_create(engine->proc, engine->auth, AUE_ssauthint); - os_log_debug(AUTHD_LOG, "engine: evaluate authentication"); + os_log_debug(AUTHD_LOG, "engine %lld: evaluate authentication", engine->engine_index); _set_rule_hints(engine->hints, rule); _set_session_hints(engine, rule); @@ -654,13 +662,13 @@ _evaluate_authentication(engine_t engine, rule_t rule) if (!(CFArrayGetCount(mechanisms) > 0)) { mechanisms = rule_get_mechanisms(engine->authenticateRule); } - require_action(CFArrayGetCount(mechanisms) > 0, done, os_log_debug(AUTHD_LOG, "engine: error no mechanisms found")); + require_action(CFArrayGetCount(mechanisms) > 0, done, os_log_debug(AUTHD_LOG, "engine %lld: error - no mechanisms found", engine->engine_index)); int64_t ruleTries = rule_get_tries(rule); if (engine->la_context) { ruleTries = 1; - os_log_debug(AUTHD_LOG, "Sheet authentication in progress, one try is enough"); + os_log_debug(AUTHD_LOG, "engine %lld: sheet authentication in progress, one try is enough", engine->engine_index); } for (engine->tries = 0; engine->tries < ruleTries; engine->tries++) { @@ -669,7 +677,7 @@ _evaluate_authentication(engine_t engine, rule_t rule) auth_items_set_int(engine->hints, AGENT_HINT_TRIES, engine->tries); status = _evaluate_mechanisms(engine, mechanisms); - os_log_debug(AUTHD_LOG, "engine: evaluate mechanisms result %d", (int)status); + os_log_debug(AUTHD_LOG, "engine %lld: evaluate mechanisms result %d", engine->engine_index, (int)status); // successfully ran mechanisms to obtain credential if (status == errAuthorizationSuccess) { @@ -680,7 +688,7 @@ _evaluate_authentication(engine_t engine, rule_t rule) if (auth_items_exist(engine->context, "uid")) { newCred = credential_create(auth_items_get_uint(engine->context, "uid")); } else { - os_log_error(AUTHD_LOG, "engine: mechanism failed to return a valid uid"); + os_log_info(AUTHD_LOG, "Mechanism failed to return a valid uid (engine %lld)", engine->engine_index); if (engine->la_context) { // sheet failed so remove sheet reference and next time, standard dialog will be displayed CFReleaseNull(engine->la_context); @@ -710,23 +718,23 @@ _evaluate_authentication(engine_t engine, rule_t rule) session_t session = auth_token_get_session(engine->auth); if (credential_get_uid(newCred) == session_get_uid(session)) { - os_log_debug(AUTHD_LOG, "engine: authenticated as the session owner"); + os_log_debug(AUTHD_LOG, "engine %lld: authenticated as the session owner", engine->engine_index); session_set_attributes(auth_token_get_session(engine->auth), AU_SESSION_FLAG_HAS_AUTHENTICATED); } break; } else { - os_log_error(AUTHD_LOG, "engine: user credential for rule failed (%d)", (int)status); + os_log_error(AUTHD_LOG, "User credential for rule failed (%d) (engine %lld)", (int)status, engine->engine_index); } CFReleaseSafe(newCred); } } else if (status == errAuthorizationCanceled || status == errAuthorizationInternal) { - os_log_error(AUTHD_LOG, "engine: evaluate cancelled or failed %d", (int)status); + os_log_error(AUTHD_LOG, "Evaluate cancelled or failed %d (engine %lld)", (int)status, engine->engine_index); break; } else if (status == errAuthorizationDenied) { - os_log_error(AUTHD_LOG, "engine: evaluate denied"); + os_log_error(AUTHD_LOG, "Evaluate denied (engine %lld)", engine->engine_index); engine->reason = invalidPassphrase; } } @@ -753,7 +761,7 @@ _check_entitlement_for_rule(engine_t engine, rule_t rule) if (rule_check_flags(rule, RuleFlagEntitledAndGroup)) { if (auth_token_has_entitlement_for_right(engine->auth, engine->currentRightName)) { if (credential_check_membership(auth_token_get_credential(engine->auth), rule_get_group(rule))) { - os_log_debug(AUTHD_LOG, "engine: creator of authorization has entitlement for right %{public}s and is member of group '%{public}s'", engine->currentRightName, rule_get_group(rule)); + os_log_info(AUTHD_LOG, "Creator of authorization has entitlement for right %{public}s and is member of group '%{public}s' (engine %lld)", engine->currentRightName, rule_get_group(rule), engine->engine_index); entitled = true; goto done; } @@ -765,7 +773,7 @@ _check_entitlement_for_rule(engine_t engine, rule_t rule) value = auth_token_copy_entitlement_value(engine->auth, "com.apple.networking.vpn.configuration"); if (value) { if (credential_check_membership(auth_token_get_credential(engine->auth), rule_get_group(rule))) { - os_log_debug(AUTHD_LOG, "engine: creator of authorization has VPN entitlement and is member of group '%{public}s'", rule_get_group(rule)); + os_log_info(AUTHD_LOG, "Creator of authorization has VPN entitlement and is member of group '%{public}s' (engine %lld)", rule_get_group(rule), engine->engine_index); entitled = true; goto done; } @@ -787,7 +795,7 @@ _evaluate_class_user(engine_t engine, rule_t rule) } if (rule_get_allow_root(rule) && auth_token_get_uid(engine->auth) == 0) { - os_log_debug(AUTHD_LOG, "engine: creator of authorization has uid == 0 granting right %{public}s", engine->currentRightName); + os_log_info(AUTHD_LOG, "Creator of authorization has uid == 0, granting right %{public}s (engine %lld)", engine->currentRightName, engine->engine_index); return errAuthorizationSuccess; } @@ -844,7 +852,7 @@ _evaluate_class_user(engine_t engine, rule_t rule) // Finally - we didn't find a credential. Obtain a new credential if our flags let us do so. if (!(engine->flags & kAuthorizationFlagExtendRights)) { - os_log_error(AUTHD_LOG, "engine: authorization denied (kAuthorizationFlagExtendRights not set)"); + os_log_error(AUTHD_LOG, "Fatal: authorization denied (kAuthorizationFlagExtendRights not set) (engine %lld)", engine->engine_index); return errAuthorizationDenied; } @@ -855,17 +863,17 @@ _evaluate_class_user(engine_t engine, rule_t rule) if (!engine->preauthorizing) { if (!(engine->flags & kAuthorizationFlagInteractionAllowed)) { - os_log_error(AUTHD_LOG, "engine: Interaction not allowed (kAuthorizationFlagInteractionAllowed not set)"); + os_log_error(AUTHD_LOG, "Fatal: interaction not allowed (kAuthorizationFlagInteractionAllowed not set) (engine %lld)", engine->engine_index); return errAuthorizationInteractionNotAllowed; } if (!(session_get_attributes(auth_token_get_session(engine->auth)) & AU_SESSION_FLAG_HAS_GRAPHIC_ACCESS)) { - os_log_error(AUTHD_LOG, "engine: Interaction not allowed (session has no ui access)"); + os_log_error(AUTHD_LOG, "Fatal: interaction not allowed (session has no ui access) (engine %lld)", engine->engine_index); return errAuthorizationInteractionNotAllowed; } if (server_in_dark_wake()) { - os_log_error(AUTHD_LOG, "engine: authorization denied (DW)"); + os_log_error(AUTHD_LOG, "Fatal: authorization denied (DW) (engine %lld)", engine->engine_index); return errAuthorizationDenied; } } @@ -882,7 +890,7 @@ _evaluate_class_rule(engine_t engine, rule_t rule, bool *save_pwd) uint32_t total = (uint32_t)rule_get_delegates_count(rule); __block uint32_t success_count = 0; __block uint32_t count = 0; - os_log_debug(AUTHD_LOG, "engine: ** rule %{public}s has %u delegates kofn = %lli",rule_get_name(rule), total, kofn); + os_log_debug(AUTHD_LOG, "engine %lld: ** rule %{public}s has %u delegates kofn = %lli", engine->engine_index, rule_get_name(rule), total, kofn); rule_delegates_iterator(rule, ^bool(rule_t delegate) { count++; @@ -891,7 +899,7 @@ _evaluate_class_rule(engine_t engine, rule_t rule, bool *save_pwd) return false; } - os_log_debug(AUTHD_LOG, "engine: * evaluate rule %{public}s (%i)", rule_get_name(delegate), count); + os_log_debug(AUTHD_LOG, "engine %lld: * evaluate rule %{public}s (%i)", engine->engine_index, rule_get_name(delegate), count); status = _evaluate_rule(engine, delegate, save_pwd); // if status is cancel/internal error abort @@ -902,7 +910,7 @@ _evaluate_class_rule(engine_t engine, rule_t rule, bool *save_pwd) if (kofn != 0) { // if remaining is less than required abort if ((total - count) < (kofn - success_count)) { - os_log_debug(AUTHD_LOG, "engine: rule evaluation remaining: %i, required: %lli", (total - count), (kofn - success_count)); + os_log_debug(AUTHD_LOG, "engine %lld: rule evaluation remaining: %i, required: %lli", engine->engine_index, (total - count), (kofn - success_count)); return false; } return true; @@ -920,7 +928,7 @@ _evaluate_class_rule(engine_t engine, rule_t rule, bool *save_pwd) static bool _preevaluate_class_rule(engine_t engine, rule_t rule) { - os_log_debug(AUTHD_LOG, "engine: _preevaluate_class_rule %{public}s", rule_get_name(rule)); + os_log_debug(AUTHD_LOG, "engine %lld: _preevaluate_class_rule %{public}s", engine->engine_index, rule_get_name(rule)); __block bool password_only = false; rule_delegates_iterator(rule, ^bool(rule_t delegate) { @@ -940,7 +948,7 @@ _evaluate_class_mechanism(engine_t engine, rule_t rule) OSStatus status = errAuthorizationDenied; CFArrayRef mechanisms = NULL; - require_action(rule_get_mechanisms_count(rule) > 0, done, status = errAuthorizationSuccess; os_log_error(AUTHD_LOG, "engine: no mechanisms specified")); + require_action(rule_get_mechanisms_count(rule) > 0, done, status = errAuthorizationSuccess; os_log_error(AUTHD_LOG, "Fatal: no mechanisms specified (engine %lld)", engine->engine_index)); mechanisms = rule_get_mechanisms(rule); @@ -948,7 +956,7 @@ _evaluate_class_mechanism(engine_t engine, rule_t rule) CFIndex count = CFArrayGetCount(mechanisms); for (CFIndex i = 0; i < count; i++) { if (!mechanism_is_privileged((mechanism_t)CFArrayGetValueAtIndex(mechanisms, i))) { - os_log_error(AUTHD_LOG, "engine: authorization denied (in DW)"); + os_log_error(AUTHD_LOG, "Fatal: authorization denied (in DW) (engine %lld)", engine->engine_index); goto done; } } @@ -961,14 +969,14 @@ _evaluate_class_mechanism(engine_t engine, rule_t rule) auth_items_set_int(engine->hints, AGENT_HINT_TRIES, engine->tries); status = _evaluate_mechanisms(engine, mechanisms); - os_log_debug(AUTHD_LOG, "engine: evaluate mechanisms result %d", (int)status); + os_log_debug(AUTHD_LOG, "engine %lld: evaluate mechanisms result %d", engine->engine_index, (int)status); if (status == errAuthorizationSuccess) { credential_t newCred = NULL; if (auth_items_exist(engine->context, "uid")) { newCred = credential_create(auth_items_get_uint(engine->context, "uid")); } else { - os_log(AUTHD_LOG, "engine: mechanism did not return a uid"); + os_log_info(AUTHD_LOG, "Mechanism did not return a uid (engine %lld)", engine->engine_index); } if (newCred) { @@ -1018,7 +1026,7 @@ _evaluate_rule(engine_t engine, rule_t rule, bool *save_pwd) { if (rule_check_flags(rule, RuleFlagEntitled)) { if (auth_token_has_entitlement_for_right(engine->auth, engine->currentRightName)) { - os_log_debug(AUTHD_LOG, "engine: rule allow, creator of authorization has entitlement for right %{public}s", engine->currentRightName); + os_log_debug(AUTHD_LOG, "engine %lld: rule allow, creator of authorization has entitlement for right %{public}s", engine->engine_index, engine->currentRightName); return errAuthorizationSuccess; } } @@ -1027,10 +1035,10 @@ _evaluate_rule(engine_t engine, rule_t rule, bool *save_pwd) if (engine->la_context || rule_check_flags(rule, RuleFlagRequireAppleSigned)) { if (!auth_token_apple_signed(engine->auth)) { #ifdef NDEBUG - os_log_error(AUTHD_LOG, "engine: rule deny, creator of authorization is not signed by Apple"); + os_log_error(AUTHD_LOG, "Rule deny, creator of authorization is not signed by Apple (engine %lld)", engine->engine_index); return errAuthorizationDenied; #else - os_log_debug(AUTHD_LOG, "engine: in release mode, this rule would be denied because creator of authorization is not signed by Apple"); + os_log_debug(AUTHD_LOG, "engine %lld: in release mode, this rule would be denied because creator of authorization is not signed by Apple", engine->engine_index); #endif } } @@ -1040,9 +1048,9 @@ _evaluate_rule(engine_t engine, rule_t rule, bool *save_pwd) CFTypeRef extract_password_entitlement = auth_token_copy_entitlement_value(engine->auth, "com.apple.authorization.extract-password"); if (extract_password_entitlement && (CFGetTypeID(extract_password_entitlement) == CFBooleanGetTypeID()) && extract_password_entitlement == kCFBooleanTrue) { *save_pwd = TRUE; - os_log_debug(AUTHD_LOG, "engine: authorization allowed to extract password"); + os_log_debug(AUTHD_LOG, "engine %lld: authorization allowed to extract password", engine->engine_index); } else { - os_log_debug(AUTHD_LOG, "engine: authorization NOT allowed to extract password"); + os_log_debug(AUTHD_LOG, "engine %lld: authorization NOT allowed to extract password", engine->engine_index); } CFReleaseSafe(extract_password_entitlement); } @@ -1054,10 +1062,10 @@ _evaluate_rule(engine_t engine, rule_t rule, bool *save_pwd) switch (rule_get_class(rule)) { case RC_ALLOW: - os_log(AUTHD_LOG, "engine: rule set to allow"); + os_log(AUTHD_LOG, "Rule set to allow (engine %lld)", engine->engine_index); return errAuthorizationSuccess; case RC_DENY: - os_log(AUTHD_LOG, "engine: rule set to deny"); + os_log(AUTHD_LOG, "Rule set to deny (engine %lld)", engine->engine_index); return errAuthorizationDenied; case RC_USER: return _evaluate_class_user(engine, rule); @@ -1066,7 +1074,7 @@ _evaluate_rule(engine_t engine, rule_t rule, bool *save_pwd) case RC_MECHANISM: return _evaluate_class_mechanism(engine, rule); default: - os_log_error(AUTHD_LOG, "engine: invalid class for rule or rule not found: %{public}s", rule_get_name(rule)); + os_log_error(AUTHD_LOG, "Invalid class for rule or rule not found: %{public}s (engine %lld)", rule_get_name(rule), engine->engine_index); return errAuthorizationInternal; } } @@ -1075,7 +1083,7 @@ _evaluate_rule(engine_t engine, rule_t rule, bool *save_pwd) static bool _preevaluate_rule(engine_t engine, rule_t rule) { - os_log_debug(AUTHD_LOG, "engine: _preevaluate_rule %{public}s", rule_get_name(rule)); + os_log_debug(AUTHD_LOG, "engine %lld: _preevaluate_rule %{public}s", engine->engine_index, rule_get_name(rule)); switch (rule_get_class(rule)) { case RC_ALLOW: @@ -1140,7 +1148,7 @@ done: r = rule_create_with_string("", dbconn); if (rule_get_id(r) == 0) { CFReleaseNull(r); - os_log_error(AUTHD_LOG, "engine: default rule lookup error (missing), using builtin defaults"); + os_log_error(AUTHD_LOG, "Default rule lookup error (missing), using builtin defaults (engine %lld)", engine->engine_index); r = rule_create_default(); } } @@ -1152,7 +1160,7 @@ static void _parse_environment(engine_t engine, auth_items_t environment) require(environment != NULL, done); #if DEBUG - os_log_debug(AUTHD_LOG, "engine: Dumping Environment: %@", environment); + os_log_debug(AUTHD_LOG, "engine %lld: Dumping Environment: %@", engine->engine_index, environment); #endif // Check if a credential was passed into the environment and we were asked to extend the rights @@ -1163,17 +1171,17 @@ static void _parse_environment(engine_t engine, auth_items_t environment) require(password_was_used == true, done); bool shared = auth_items_exist(environment, kAuthorizationEnvironmentShared); - require_action(user != NULL, done, os_log_debug(AUTHD_LOG, "engine: user not used password")); + require_action(user != NULL, done, os_log_debug(AUTHD_LOG, "engine %lld: user not used password", engine->engine_index)); struct passwd *pw = getpwnam(user); - require_action(pw != NULL, done, os_log_error(AUTHD_LOG, "engine: user not found %{public}s", user)); + require_action(pw != NULL, done, os_log_error(AUTHD_LOG, "User not found %{public}s (engine %lld)", user, engine->engine_index)); int checkpw_status = checkpw_internal(pw, pass ? pass : ""); - require_action(checkpw_status == CHECKPW_SUCCESS, done, os_log_error(AUTHD_LOG, "engine: checkpw() returned %d; failed to authenticate user %{public}s (uid %u).", checkpw_status, pw->pw_name, pw->pw_uid)); + require_action(checkpw_status == CHECKPW_SUCCESS, done, os_log_error(AUTHD_LOG, "engine %lld: checkpw() returned %d; failed to authenticate user %{public}s (uid %u).", engine->engine_index, checkpw_status, pw->pw_name, pw->pw_uid)); credential_t cred = credential_create(pw->pw_uid); if (credential_get_valid(cred)) { - os_log(AUTHD_LOG, "engine: checkpw() succeeded, creating credential for user %{public}s", user); + os_log_info(AUTHD_LOG, "checkpw() succeeded, creating credential for user %{public}s (engine %lld)", user, engine->engine_index); _engine_set_credential(engine, cred, shared); auth_items_set_string(engine->context, kAuthorizationEnvironmentUsername, user); @@ -1191,13 +1199,13 @@ static bool _verify_sandbox(engine_t engine, const char * right) { pid_t pid = process_get_pid(engine->proc); if (sandbox_check(pid, "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, right)) { - os_log_error(AUTHD_LOG, "Sandbox denied authorizing right '%{public}s' by client '%{public}s' [%d]", right, process_get_code_url(engine->proc), pid); + os_log_error(AUTHD_LOG, "Sandbox denied authorizing right '%{public}s' by client '%{public}s' [%d] (engine %lld)", right, process_get_code_url(engine->proc), pid, engine->engine_index); return false; } pid = auth_token_get_pid(engine->auth); if (auth_token_get_sandboxed(engine->auth) && sandbox_check_by_audit_token(auth_token_get_audit_info(engine->auth)->opaqueToken, "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, right)) { - os_log_error(AUTHD_LOG, "Sandbox denied authorizing right '%{public}s' for authorization created by '%{public}s' [%d]", right, auth_token_get_code_url(engine->auth), pid); + os_log_error(AUTHD_LOG, "Sandbox denied authorizing right '%{public}s' for authorization created by '%{public}s' [%d] (engine %lld)", right, auth_token_get_code_url(engine->auth), pid, engine->engine_index); return false; } @@ -1209,16 +1217,16 @@ static bool _verify_sandbox(engine_t engine, const char * right) OSStatus engine_preauthorize(engine_t engine, auth_items_t credentials) { - os_log(AUTHD_LOG, "engine: preauthorizing"); + os_log(AUTHD_LOG, "engine %lld: preauthorizing", engine->engine_index); OSStatus status = errAuthorizationDenied; bool save_password = false; CFTypeRef extract_password_entitlement = auth_token_copy_entitlement_value(engine->auth, "com.apple.authorization.extract-password"); if (extract_password_entitlement && (CFGetTypeID(extract_password_entitlement) == CFBooleanGetTypeID()) && extract_password_entitlement == kCFBooleanTrue) { save_password = true; - os_log_debug(AUTHD_LOG, "engine: authorization allowed to extract password"); + os_log_debug(AUTHD_LOG, "engine %lld: authorization allowed to extract password", engine->engine_index); } else { - os_log_debug(AUTHD_LOG, "engine: authorization NOT allowed to extract password"); + os_log_debug(AUTHD_LOG, "engine %lld: authorization NOT allowed to extract password", engine->engine_index); } CFReleaseSafe(extract_password_entitlement); @@ -1257,7 +1265,7 @@ OSStatus engine_preauthorize(engine_t engine, auth_items_t credentials) } auth_items_t decrypted_items = auth_items_create(); - require_action(decrypted_items != NULL, done, os_log_error(AUTHD_LOG, "engine: unable to create items")); + require_action(decrypted_items != NULL, done, os_log_error(AUTHD_LOG, "Unable to create items (engine %lld)", engine->engine_index)); auth_items_content_copy(decrypted_items, auth_token_get_context(engine->auth)); auth_items_decrypt(decrypted_items, auth_token_get_encryption_key(engine->auth)); auth_items_copy(engine->context, decrypted_items); @@ -1272,20 +1280,20 @@ OSStatus engine_preauthorize(engine_t engine, auth_items_t credentials) status = _evaluate_rule(engine, rule, &save_password); switch (status) { case errAuthorizationSuccess: - os_log(AUTHD_LOG, "Succeeded preauthorizing client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d)", + os_log(AUTHD_LOG, "Succeeded preauthorizing client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (engine %lld)", process_get_code_url(engine->proc), process_get_pid(engine->proc), - auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth)); + auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), engine->engine_index); status = errAuthorizationSuccess; break; case errAuthorizationDenied: case errAuthorizationInteractionNotAllowed: case errAuthorizationCanceled: - os_log(AUTHD_LOG, "Failed to preauthorize client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%i)", + os_log(AUTHD_LOG, "Failed to preauthorize client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%i) (engine %lld)", process_get_code_url(engine->proc), process_get_pid(engine->proc), - auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status); + auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status, engine->engine_index); break; default: - os_log_error(AUTHD_LOG, "engine: preauthorize returned %d => returning errAuthorizationInternal", (int)status); + os_log_error(AUTHD_LOG, "Preauthorize returned %d => returning errAuthorizationInternal (engine %lld)", (int)status, engine->engine_index); status = errAuthorizationInternal; break; } @@ -1293,11 +1301,11 @@ OSStatus engine_preauthorize(engine_t engine, auth_items_t credentials) CFReleaseSafe(rule); if (engine->dismissed) { - os_log_error(AUTHD_LOG, "engine: engine dismissed"); + os_log_error(AUTHD_LOG, "Engine dismissed (engine %lld)", engine->engine_index); status = errAuthorizationDenied; } - os_log_debug(AUTHD_LOG, "engine: preauthorize result: %d", (int)status); + os_log_debug(AUTHD_LOG, "engine %lld: preauthorize result: %d", engine->engine_index, (int)status); _cf_set_iterate(engine->credentials, ^bool(CFTypeRef value) { credential_t cred = (credential_t)value; @@ -1311,9 +1319,9 @@ OSStatus engine_preauthorize(engine_t engine, auth_items_t credentials) session_set_credential(session, cred); } if (credential_is_right(cred)) { - os_log(AUTHD_LOG, "engine: adding least privileged %{public}scredential %{public}s to authorization", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred)); + os_log(AUTHD_LOG, "engine %lld: adding least privileged %{public}scredential %{public}s to authorization", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred)); } else { - os_log(AUTHD_LOG, "engine: adding %{public}scredential %{public}s (%i) to authorization", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred)); + os_log(AUTHD_LOG, "engine %lld: adding %{public}scredential %{public}s (%i) to authorization", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred)); } return true; }); @@ -1325,15 +1333,15 @@ OSStatus engine_preauthorize(engine_t engine, auth_items_t credentials) if ((status == errAuthorizationSuccess) || (status == errAuthorizationCanceled)) { auth_items_t encrypted_items = auth_items_create(); - require_action(encrypted_items != NULL, done, os_log_error(AUTHD_LOG, "engine: unable to create items")); + require_action(encrypted_items != NULL, done, os_log_error(AUTHD_LOG, "Unable to create items (engine %lld)", engine->engine_index)); auth_items_content_copy_with_flags(encrypted_items, engine->context, kAuthorizationContextFlagExtractable); #if DEBUG - os_log_debug(AUTHD_LOG, "engine: ********** Dumping preauthorized context for encryption **********"); + os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping preauthorized context for encryption **********", engine->engine_index); os_log_debug(AUTHD_LOG, "%@", encrypted_items); #endif auth_items_encrypt(encrypted_items, auth_token_get_encryption_key(engine->auth)); auth_items_copy_with_flags(auth_token_get_context(engine->auth), encrypted_items, kAuthorizationContextFlagExtractable); - os_log_debug(AUTHD_LOG, "engine: encrypted preauthorization context data"); + os_log_debug(AUTHD_LOG, "engine %lld: encrypted preauthorization context data", engine->engine_index); CFReleaseSafe(encrypted_items); } @@ -1350,7 +1358,7 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en __block OSStatus status = errAuthorizationSuccess; __block bool save_password = false; __block bool password_only = false; - + CFIndex rights_count = auth_rights_get_count(rights); ccaudit_t ccaudit = NULL; require(rights != NULL, done); @@ -1359,13 +1367,33 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en if (auth_rights_get_count(rights) > 0) { ccaudit_log(ccaudit, "begin evaluation", NULL, 0); } - + + if (rights_count) { + __block CFMutableArrayRef rights_list = NULL; + rights_list = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + auth_rights_iterate(rights, ^bool(const char *key) { + if (!key) + return true; + + CFStringRef tmp = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8); + if (tmp) { + CFArrayAppendValue(rights_list, tmp); + CFRelease(tmp); + } else { + os_log_error(AUTHD_LOG, "Unable to get details for right %{public}s", key); + } + return true; + }); + + os_log_info(AUTHD_LOG, "Process %{public}s (PID %d) evaluates %ld rights (engine %lld): %{public}@", process_get_code_url(engine->proc), process_get_pid(engine->proc), (long)rights_count, engine->engine_index, rights_list); + CFReleaseNull(rights_list); + } + if (!auth_token_apple_signed(engine->auth)) { #ifdef NDEBUG - flags &= ~kAuthorizationFlagIgnorePasswordOnly; flags &= ~kAuthorizationFlagSheet; #else - os_log_debug(AUTHD_LOG, "engine: in release mode, extra flags would be ommited as creator is not signed by Apple"); + os_log_debug(AUTHD_LOG, "engine %lld: in release mode, extra flags would be ommited as creator is not signed by Apple", engine->engine_index); #endif } @@ -1376,9 +1404,9 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en auth_items_copy(engine->hints, environment); } - // First restore all context values from the AuthorizationRef + // Restore all context values from the AuthorizationRef auth_items_t decrypted_items = auth_items_create(); - require_action(decrypted_items != NULL, done, os_log_error(AUTHD_LOG, "engine: enable to create items")); + require_action(decrypted_items != NULL, done, os_log_error(AUTHD_LOG, "Unable to create items (engine %lld)", engine->engine_index)); auth_items_content_copy(decrypted_items, auth_token_get_context(engine->auth)); auth_items_decrypt(decrypted_items, auth_token_get_encryption_key(engine->auth)); auth_items_copy(engine->context, decrypted_items); @@ -1388,9 +1416,9 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en CFTypeRef extract_password_entitlement = auth_token_copy_entitlement_value(engine->auth, "com.apple.authorization.extract-password"); if (extract_password_entitlement && (CFGetTypeID(extract_password_entitlement) == CFBooleanGetTypeID()) && extract_password_entitlement == kCFBooleanTrue) { save_password = true; - os_log_debug(AUTHD_LOG, "engine: authorization allowed to extract password"); + os_log_debug(AUTHD_LOG, "engine %lld: authorization allowed to extract password", engine->engine_index); } else { - os_log_debug(AUTHD_LOG, "engine: authorization NOT allowed to extract password"); + os_log_debug(AUTHD_LOG, "engine %lld: authorization NOT allowed to extract password", engine->engine_index); } CFReleaseSafe(extract_password_entitlement); @@ -1400,14 +1428,14 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en } // Try to use/update fresh context values from the environment - require_action(environment, done, os_log_debug(AUTHD_LOG, "engine: Missing environment for sheet authorization"); status = errAuthorizationDenied); + require_action(environment, done, os_log_error(AUTHD_LOG, "Missing environment for sheet authorization (engine %lld)", engine->engine_index); status = errAuthorizationDenied); const char *user = auth_items_get_string(environment, kAuthorizationEnvironmentUsername); - require_action(user, done, os_log_debug(AUTHD_LOG, "engine: Missing username"); status = errAuthorizationDenied); + require_action(user, done, os_log_error(AUTHD_LOG, "Missing username (engine %lld)", engine->engine_index); status = errAuthorizationDenied); auth_items_set_string(engine->context, kAuthorizationEnvironmentUsername, user); struct passwd *pwd = getpwnam(user); - require_action(pwd, done, os_log_debug(AUTHD_LOG, "engine: Invalid username %s", user); status = errAuthorizationDenied); + require_action(pwd, done, os_log_error(AUTHD_LOG, "Invalid username %s (engine %lld)", user, engine->engine_index); status = errAuthorizationDenied); auth_items_set_uint(engine->context, "sheet-uid", pwd->pw_uid); // move sheet-specific items from hints to context @@ -1449,7 +1477,7 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en auth_rights_iterate(rights, ^bool(const char *key) { if (!key) return true; - os_log_debug(AUTHD_LOG, "engine: checking if rule %{public}s contains password-only item", key); + os_log_debug(AUTHD_LOG, "engine %lld: checking if rule %{public}s contains password-only item", engine->engine_index, key); rule_t rule = _find_rule(engine, dbconn, key); @@ -1463,11 +1491,11 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en }); authdb_connection_release(&dbconn); // release db handle } else { - os_log_info(AUTHD_LOG, "engine: password-only ignored"); + os_log_info(AUTHD_LOG, "Password-only flag ignored (engine %lld)", engine->engine_index); } if (password_only) { - os_log_debug(AUTHD_LOG, "engine: password-only item found, forcing SecurityAgent to use password-only UI"); + os_log_debug(AUTHD_LOG, "engine %lld: password-only item found, forcing SecurityAgent to use password-only UI", engine->engine_index); auth_items_set_bool(engine->immutable_hints, AGENT_HINT_PASSWORD_ONLY, true); } @@ -1483,13 +1511,13 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en authdb_connection_t dbconn = authdb_connection_acquire(server_get_database()); // get db handle - os_log_debug(AUTHD_LOG, "engine: evaluate right %{public}s", key); + os_log_debug(AUTHD_LOG, "engine %lld: evaluate right %{public}s", engine->engine_index, key); rule_t rule = _find_rule(engine, dbconn, key); const char * rule_name = rule_get_name(rule); if (rule_name && (strcasecmp(rule_name, "") == 0)) { rule_name = "default (not defined)"; } - os_log_debug(AUTHD_LOG, "engine: using rule %{public}s", rule_name); + os_log_debug(AUTHD_LOG, "engine %lld: using rule %{public}s", engine->engine_index, rule_name); // only need the hints & mechanisms if we are going to show ui if (engine->flags & kAuthorizationFlagInteractionAllowed) { @@ -1520,25 +1548,27 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en auth_rights_set_flags(engine->grantedRights, engine->currentRightName, kAuthorizationFlagPreAuthorize); } - os_log(AUTHD_LOG, "Succeeded authorizing right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d)", + os_log(AUTHD_LOG, "Succeeded authorizing right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (engine %lld)", key, process_get_code_url(engine->proc), process_get_pid(engine->proc), - auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth)); + auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), engine->engine_index); break; case errAuthorizationDenied: case errAuthorizationInteractionNotAllowed: case errAuthorizationCanceled: if (engine->flags & kAuthorizationFlagInteractionAllowed) { - os_log(AUTHD_LOG, "Failed to authorize right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%i)", + os_log(AUTHD_LOG, "Failed to authorize right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%i) (engine %lld)", key, process_get_code_url(engine->proc), process_get_pid(engine->proc), - auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status); + auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status, + engine->engine_index); } else { - os_log_debug(AUTHD_LOG, "Failed to authorize right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%d)", + os_log_debug(AUTHD_LOG, "Failed to authorize right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%d) (engine %lld)", key, process_get_code_url(engine->proc), process_get_pid(engine->proc), - auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status); + auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status, + engine->engine_index); } break; default: - os_log_error(AUTHD_LOG, "engine: evaluate returned %d returning errAuthorizationInternal", (int)status); + os_log_error(AUTHD_LOG, "Evaluate returned %d, returning errAuthorizationInternal (engine %lld)", (int)status, engine->engine_index); status = errAuthorizationInternal; break; } @@ -1559,7 +1589,7 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en }); if (password_only) { - os_log_debug(AUTHD_LOG, "engine: removing password-only flag"); + os_log_debug(AUTHD_LOG, "engine %lld: removing password-only flag", engine->engine_index); auth_items_remove(engine->immutable_hints, AGENT_HINT_PASSWORD_ONLY); } @@ -1568,11 +1598,11 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en } if (engine->dismissed) { - os_log_error(AUTHD_LOG, "engine: dismissed"); + os_log_error(AUTHD_LOG, "Dismissed (engine %lld)", engine->engine_index); status = errAuthorizationDenied; } - os_log_debug(AUTHD_LOG, "engine: authorize result: %d", (int)status); + os_log_debug(AUTHD_LOG, "engine %lld: authorize result: %d", engine->engine_index, (int)status); if (engine->flags & kAuthorizationFlagSheet) { engine->preauthorizing = false; @@ -1591,9 +1621,9 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en session_set_credential(session, cred); } if (credential_is_right(cred)) { - os_log_debug(AUTHD_LOG, "engine: adding least privileged %{public}scredential %{public}s to authorization", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred)); + os_log_debug(AUTHD_LOG, "engine %lld: adding least privileged %{public}scredential %{public}s to authorization", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred)); } else { - os_log_debug(AUTHD_LOG, "engine: adding %{public}scredential %{public}s (%i) to authorization", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred)); + os_log_debug(AUTHD_LOG, "engine %lld: adding %{public}scredential %{public}s (%i) to authorization", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred)); } return true; }); @@ -1605,16 +1635,16 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en if ((status == errAuthorizationSuccess) || (status == errAuthorizationCanceled)) { auth_items_t encrypted_items = auth_items_create(); - require_action(encrypted_items != NULL, done, os_log_error(AUTHD_LOG, "engine: unable to create items")); + require_action(encrypted_items != NULL, done, os_log_error(AUTHD_LOG, "Unable to create items (engine %lld)", engine->engine_index)); auth_items_content_copy_with_flags(encrypted_items, engine->context, kAuthorizationContextFlagExtractable); #if DEBUG - os_log_debug(AUTHD_LOG,"engine: ********** Dumping context for encryption **********"); + os_log_debug(AUTHD_LOG,"engine %lld: ********** Dumping context for encryption **********", engine->engine_index); os_log_debug(AUTHD_LOG, "%@", encrypted_items); #endif auth_items_encrypt(encrypted_items, auth_token_get_encryption_key(engine->auth)); auth_items_copy_with_flags(auth_token_get_context(engine->auth), encrypted_items, kAuthorizationContextFlagExtractable); - os_log_debug(AUTHD_LOG, "engine: encrypted authorization context data"); - CFReleaseSafe(encrypted_items); + os_log_debug(AUTHD_LOG, "engine %lld: encrypted authorization context data", engine->engine_index); + CFReleaseSafe(encrypted_items); } if (auth_rights_get_count(rights) > 0) { @@ -1622,21 +1652,21 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en } #if DEBUG - os_log_debug(AUTHD_LOG, "engine: ********** Dumping auth->credentials **********"); + os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping auth->credentials **********", engine->engine_index); auth_token_credentials_iterate(engine->auth, ^bool(credential_t cred) { os_log_debug(AUTHD_LOG, "%@", cred); return true; }); - os_log_debug(AUTHD_LOG, "engine: ********** Dumping session->credentials **********"); + os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping session->credentials **********", engine->engine_index); session_credentials_iterate(auth_token_get_session(engine->auth), ^bool(credential_t cred) { os_log_debug(AUTHD_LOG, "%@", cred); return true; }); - os_log_debug(AUTHD_LOG, "engine: ********** Dumping engine->context **********"); + os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping engine->context **********", engine->engine_index); os_log_debug(AUTHD_LOG, "%@", engine->context); - os_log_debug(AUTHD_LOG, "engine: ********** Dumping auth->context **********"); + os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping auth->context **********", engine->engine_index); os_log_debug(AUTHD_LOG, "%@", engine->auth); - os_log_debug(AUTHD_LOG, "engine: ********** Dumping granted rights **********"); + os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping granted rights **********", engine->engine_index); os_log_debug(AUTHD_LOG, "%@", engine->grantedRights); #endif @@ -1704,7 +1734,7 @@ OSStatus engine_verify_modification(engine_t engine, rule_t rule, bool remove, b size_t len = strlen(right); require(len != 0, done); - require_action(right[len-1] != '.', done, os_log_error(AUTHD_LOG, "engine: not allowed to set wild card rules")); + require_action(right[len-1] != '.', done, os_log_error(AUTHD_LOG, "Not allowed to set wild card rules (engine %lld)", engine->engine_index)); if (strncasecmp(right, kConfigRight, strlen(kConfigRight)) == 0) { // special handling of meta right change: @@ -1736,7 +1766,7 @@ OSStatus engine_verify_modification(engine_t engine, rule_t rule, bool remove, b status = engine_authorize(engine, checkRight, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights); done: - os_log_debug(AUTHD_LOG, "engine: authorizing %{public}s for db modification: %d", right, (int)status); + os_log_debug(AUTHD_LOG, "engine %lld: authorizing %{public}s for db modification: %d", engine->engine_index, right, (int)status); CFReleaseSafe(checkRight); return status; } @@ -1744,7 +1774,7 @@ done: void _engine_set_credential(engine_t engine, credential_t cred, bool shared) { - os_log_debug(AUTHD_LOG, "engine: adding %{public}scredential %{public}s (%i) to engine shared: %i", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred), shared); + os_log_debug(AUTHD_LOG, "engine %lld: adding %{public}scredential %{public}s (%i) to engine shared: %i", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred), shared); CFSetSetValue(engine->credentials, cred); if (shared) { credential_t sharedCred = credential_create_with_credential(cred, true); @@ -1769,7 +1799,7 @@ void engine_destroy_agents(engine_t engine) engine->dismissed = true; _cf_dictionary_iterate(engine->mechanism_agents, ^bool(CFTypeRef key __attribute__((__unused__)), CFTypeRef value) { - os_log_debug(AUTHD_LOG, "engine: Destroying %{public}s", mechanism_get_string((mechanism_t)key)); + os_log_debug(AUTHD_LOG, "engine %lld: Destroying %{public}s", engine->engine_index, mechanism_get_string((mechanism_t)key)); agent_t agent = (agent_t)value; agent_destroy(agent); @@ -1792,13 +1822,13 @@ CFTypeRef engine_copy_context(engine_t engine, auth_items_t source) process_t proc = connection_get_process(engine->conn); if (!proc) { - os_log_error(AUTHD_LOG, "engine: No client process"); + os_log_error(AUTHD_LOG, "No client process (engine %lld)", engine->engine_index); return retval; } uid_t client_uid = process_get_uid(proc); if (!client_uid) { - os_log_error(AUTHD_LOG, "engine: No client UID"); + os_log_error(AUTHD_LOG, "No client UID (engine %lld)", engine->engine_index); return retval; } @@ -1807,7 +1837,7 @@ CFTypeRef engine_copy_context(engine_t engine, auth_items_t source) if (data) { CFDataRef externalized = CFDataCreate(kCFAllocatorDefault, data, dataLen); if (externalized) { - os_log_debug(AUTHD_LOG, "engine: Going to get LA context for UID %d", client_uid); + os_log_debug(AUTHD_LOG, "engine %lld: going to get LA context for UID %d", engine->engine_index, client_uid); retval = LACreateNewContextWithACMContextInSession(client_uid, externalized, NULL); CFRelease(externalized); } @@ -1826,11 +1856,11 @@ bool engine_acquire_sheet_data(engine_t engine) CFReleaseSafe(engine->la_context); engine->la_context = engine_copy_context(engine, engine->hints); if (engine->la_context) { - os_log_debug(AUTHD_LOG, "engine: Sheet user UID %d", uid); + os_log_debug(AUTHD_LOG, "engine %lld: Sheet UID %d", engine->engine_index, uid); return true; } else { // this is not real failure as no LA context in authorization context is very valid scenario - os_log_debug(AUTHD_LOG, "engine: Failed to get LA context"); + os_log_debug(AUTHD_LOG, "engine %lld: Failed to get LA context", engine->engine_index); } return false; } diff --git a/OSX/authd/rule.c b/OSX/authd/rule.c index b084b72a..a706b4d3 100644 --- a/OSX/authd/rule.c +++ b/OSX/authd/rule.c @@ -11,6 +11,7 @@ #include #include #include "server.h" +#include AUTHD_DEFINE_LOG @@ -747,6 +748,7 @@ bool rule_sql_commit(rule_t rule, authdb_connection_t dbconn, CFAbsoluteTime modified, process_t proc) { bool result = false; + __block bool insert = false; // type and class required else rule is name only? RuleClass rule_class = rule_get_class(rule); require(rule_get_type(rule) != 0, done); @@ -792,6 +794,7 @@ rule_sql_commit(rule_t rule, authdb_connection_t dbconn, CFAbsoluteTime modified if (rule_get_id(rule)) { update = _sql_update(rule, dbconn); } else { + insert = true; if (proc) { const char * ident = process_get_identifier(proc); if (ident) { @@ -824,12 +827,14 @@ rule_sql_commit(rule_t rule, authdb_connection_t dbconn, CFAbsoluteTime modified done: if (!result) { os_log_debug(AUTHD_LOG, "rule: commit, failed for %{public}s (%llu)", rule_get_name(rule), rule_get_id(rule)); + } else { + rule_log_manipulation(dbconn, rule, insert ? rule_insert : rule_update, proc); } return result; } bool -rule_sql_remove(rule_t rule, authdb_connection_t dbconn) +rule_sql_remove(rule_t rule, authdb_connection_t dbconn, process_t proc) { bool result = false; int64_t id = rule_get_id(rule); @@ -844,7 +849,12 @@ rule_sql_remove(rule_t rule, authdb_connection_t dbconn) ^(sqlite3_stmt *stmt) { sqlite3_bind_int64(stmt, 1, id); }, NULL); -done: + + if (result) { + rule_log_manipulation(dbconn, rule, rule_delete, proc); + } + +done: return result; } @@ -1246,3 +1256,25 @@ SecRequirementRef rule_get_requirement(rule_t rule) return rule->requirement; } + +void +rule_log_manipulation(authdb_connection_t dbconn, rule_t rule, RuleOperation operation, process_t source) +{ + authdb_step(dbconn, "INSERT INTO rules_history (rule, source, operation, version) VALUES (?,?,?,?)", ^(sqlite3_stmt *stmt) { + char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; + if (source) { + pid_t pid = process_get_pid(source); + if (!proc_pidpath(pid, pathbuf, sizeof(pathbuf))) { + os_log_error(AUTHD_LOG, "Failed to get path for pid %d", pid); + snprintf(pathbuf, sizeof(pathbuf), "Unknown process with PID %d", pid); + } + } else { + strncpy(pathbuf, "authd", sizeof(pathbuf)); + } + + sqlite3_bind_text(stmt, 1, rule_get_name(rule), -1, NULL); + sqlite3_bind_text(stmt, 2, pathbuf, -1, NULL); + sqlite3_bind_int(stmt, 3, operation); + sqlite3_bind_int64(stmt, 4, rule_get_version(rule)); + }, NULL); +} diff --git a/OSX/authd/rule.h b/OSX/authd/rule.h index f5d00723..098087d5 100644 --- a/OSX/authd/rule.h +++ b/OSX/authd/rule.h @@ -41,6 +41,12 @@ enum { }; typedef uint32_t RuleFlags; +typedef enum { + rule_insert, + rule_update, + rule_delete, +} RuleOperation; + AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED rule_t rule_create_default(void); @@ -75,7 +81,7 @@ AUTH_NONNULL1 AUTH_NONNULL2 bool rule_sql_commit(rule_t,authdb_connection_t,CFAbsoluteTime,process_t); AUTH_NONNULL_ALL -bool rule_sql_remove(rule_t,authdb_connection_t); +bool rule_sql_remove(rule_t,authdb_connection_t,process_t); AUTH_NONNULL_ALL CFMutableDictionaryRef rule_copy_to_cfobject(rule_t,authdb_connection_t); @@ -146,6 +152,9 @@ CFDataRef rule_get_requirement_data(rule_t); AUTH_NONNULL_ALL SecRequirementRef rule_get_requirement(rule_t); +AUTH_NONNULL1 AUTH_NONNULL2 +void rule_log_manipulation(authdb_connection_t dbconn, rule_t rule, RuleOperation operation, process_t source); + #if defined(__cplusplus) } #endif diff --git a/OSX/authd/server.c b/OSX/authd/server.c index 2d46808f..903c51c8 100644 --- a/OSX/authd/server.c +++ b/OSX/authd/server.c @@ -1148,7 +1148,7 @@ authorization_right_remove(connection_t conn, xpc_object_t message, xpc_object_t } if (rule_get_id(rule) != 0) { - rule_sql_remove(rule, dbconn); + rule_sql_remove(rule, dbconn, proc); } done: diff --git a/OSX/authd/session.c b/OSX/authd/session.c index d631e74a..83d548e8 100644 --- a/OSX/authd/session.c +++ b/OSX/authd/session.c @@ -196,6 +196,11 @@ session_credentials_iterate(session_t session, credential_iterator_t iter) dispatch_sync(session->dispatch_queue, ^{ CFIndex count = CFSetGetCount(session->credentials); + if (count > 128) { // Variable Length Arrays; AuthD + // session usually contains 0 or 1 credential + count = 128; + } + CFTypeRef values[count]; CFSetGetValues(session->credentials, values); for (CFIndex i = 0; i < count; i++) { diff --git a/OSX/config/security_framework_macos.xcconfig b/OSX/config/security_framework_macos.xcconfig index 2dff3356..1fb5b36f 100644 --- a/OSX/config/security_framework_macos.xcconfig +++ b/OSX/config/security_framework_macos.xcconfig @@ -17,7 +17,7 @@ INFOPLIST_FILE = OSX/lib/Info-Security.plist INSTALL_PATH = $(SYSTEM_LIBRARY_DIR)/Frameworks -OTHER_LDFLAGS = -laks -lCrashReporterClient -Wl,-upward_framework,Foundation +OTHER_LDFLAGS = -laks -lCrashReporterClient -Wl,-upward_framework,Foundation -Wl,-no_inits SECTORDER_FLAGS = -order_file_statistics APPLY_RULES_IN_COPY_FILES = NO @@ -32,3 +32,5 @@ OTHER_TAPI_FLAGS_USR_LIB_HEADERS = -extra-private-header $(PROJECT_DIR)/OSX/util OTHER_TAPI_FLAGS_HACKS = -exclude-public-header $(BUILT_PRODUCTS_DIR)/Security.framework/Versions/A/Headers/AuthorizationPlugin.h -extra-public-header $(PROJECT_DIR)/OSX/macos_tapi_hacks.h -D SECURITY_PROJECT_TAPI_HACKS=1 OTHER_TAPI_FLAGS = $(inherited) $(OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK) -I$(PROJECT_DIR)/header_symlinks/ $(OTHER_TAPI_FLAGS_TRUST) $(OTHER_TAPI_FLAGS_USR_LIB_HEADERS) $(OTHER_TAPI_FLAGS_HACKS) + +IS_ZIPPERED = YES diff --git a/OSX/lib/en.lproj/authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings b/OSX/lib/en.lproj/authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings index 3e047aa1..6ef38307 100644 --- a/OSX/lib/en.lproj/authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings +++ b/OSX/lib/en.lproj/authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings @@ -108,7 +108,7 @@ "system.preferences" = "Touch ID to Modify Your System Settings."; -"com.apple.SoftwareUpdate.modify-settings" = "Touch ID to Unlock the App Store preferences."; +"com.apple.SoftwareUpdate.modify-settings" = "Touch ID to Unlock the Software Update preferences."; "com.apple.uninstalld.uninstall" = "Touch ID to Delete an Application."; @@ -124,7 +124,7 @@ "com.apple.server.admin.streaming" = "Touch ID to Modify the QuickTime Streaming Server Settings."; -"system.preferences.softwareupdate" = "Touch ID to Unlock the App Store preferences."; +"system.preferences.softwareupdate" = "Touch ID to Unlock the Software Update preferences."; "system.keychain.modify" = "Touch ID to Modify the System Keychain."; @@ -158,3 +158,10 @@ "com.apple.security.sudo" = "Touch ID to Execute a command as administrator."; +"com.apple.configurationprofiles.userprofile.trustcert" = "Touch ID to Trust a Certificate from a User Configuration Profile."; + +"com.apple.app-sandbox.create-symlink" = "Touch ID to Install a Symlink into /usr/local/bin."; + +"com.apple.app-sandbox.set-attributes" = "Touch ID to Change the Permissions of a Privileged File."; + +"com.apple.app-sandbox.replace-file" = "Touch ID to Save a File in a Privileged Location."; diff --git a/OSX/lib/en.lproj/authorization.prompts.strings b/OSX/lib/en.lproj/authorization.prompts.strings index 17260277..0253a7c5 100644 --- a/OSX/lib/en.lproj/authorization.prompts.strings +++ b/OSX/lib/en.lproj/authorization.prompts.strings @@ -108,7 +108,7 @@ "system.preferences" = "__APPNAME__ is trying to modify your system settings."; -"com.apple.SoftwareUpdate.modify-settings" = "__APPNAME__ is trying to unlock the App Store preferences."; +"com.apple.SoftwareUpdate.modify-settings" = "__APPNAME__ is trying to unlock the Software Update preferences."; "com.apple.uninstalld.uninstall" = "__APPNAME__ is trying to delete an application."; @@ -124,7 +124,7 @@ "com.apple.server.admin.streaming" = "__APPNAME__ is trying to modify the QuickTime Streaming Server settings."; -"system.preferences.softwareupdate" = "__APPNAME__ is trying to unlock the App Store preferences."; +"system.preferences.softwareupdate" = "__APPNAME__ is trying to unlock the Software Update preferences."; "system.keychain.modify" = "__APPNAME__ is trying to modify the system keychain."; @@ -161,3 +161,9 @@ "com.apple.security.sudo" = "__APPNAME__ is trying to execute a command as administrator."; "com.apple.configurationprofiles.userprofile.trustcert" = "__APPNAME__ is trying to trust a certificate from a user configuration profile."; + +"com.apple.app-sandbox.create-symlink" = "__APPNAME__ wants to install a symlink into /usr/local/bin."; + +"com.apple.app-sandbox.set-attributes" = "__APPNAME__ wants to change permissions of a privileged file."; + +"com.apple.app-sandbox.replace-file" = "__APPNAME__ wants to save a file in a privileged location."; diff --git a/OSX/lib/framework.sb b/OSX/lib/framework.sb index 7fa76f2d..40425564 100644 --- a/OSX/lib/framework.sb +++ b/OSX/lib/framework.sb @@ -5,3 +5,7 @@ (allow mach-lookup (global-name "com.apple.CoreAuthentication.agent.libxpc")) ;; allow clients to communicate with ctkd (allow mach-lookup (global-name "com.apple.ctkd.token-client")) + +;; On internal builds, allow clients to read the AMFITrustedKeys NVRAM variable +(with-filter (system-attribute apple-internal) + (allow nvram-get (nvram-variable "AMFITrustedKeys"))) diff --git a/OSX/libsecurity_apple_csp/lib/opensshCoding.cpp b/OSX/libsecurity_apple_csp/lib/opensshCoding.cpp index 126e3a80..5a42320c 100644 --- a/OSX/libsecurity_apple_csp/lib/opensshCoding.cpp +++ b/OSX/libsecurity_apple_csp/lib/opensshCoding.cpp @@ -111,10 +111,15 @@ static CSSM_RETURN appendBigNum2( return CSSMERR_CSP_INTERNAL_ERROR; } int numBytes = BN_num_bytes(bn); - unsigned char buf[numBytes]; + unsigned char *buf = (unsigned char*)malloc(numBytes); + if (buf == NULL) { + dprintf("appendBigNum: Cannot allocate a temp BN buffer\n"); + return CSSMERR_CSSM_MEMORY_ERROR; + } int moved = BN_bn2bin(bn, buf); if(moved != numBytes) { dprintf("appendBigNum: BN_bn2bin() screwup\n"); + free(buf); return CSSMERR_CSP_INTERNAL_ERROR; } bool appendZero = false; @@ -131,6 +136,7 @@ static CSSM_RETURN appendBigNum2( } CFDataAppendBytes(cfOut, buf, numBytes); memset(buf, 0, numBytes); + free(buf); return CSSM_OK; } diff --git a/OSX/libsecurity_apple_csp/lib/opensshWrap.cpp b/OSX/libsecurity_apple_csp/lib/opensshWrap.cpp index 988943b2..11895ac4 100644 --- a/OSX/libsecurity_apple_csp/lib/opensshWrap.cpp +++ b/OSX/libsecurity_apple_csp/lib/opensshWrap.cpp @@ -402,7 +402,12 @@ CSSM_RETURN encodeOpenSSHv1PrivKey( /* encrypt it */ ptextLen = CFDataGetLength(ptext); - unsigned char ctext[ptextLen]; + unsigned char *ctext = (unsigned char*)malloc(ptextLen); + if(ctext == NULL) { + ourRtn = CSSMERR_CSSM_MEMORY_ERROR; + goto errOut; + } + unsigned ctextLen; ourRtn = ssh1DES3Crypt(cipherSpec, true, (unsigned char *)CFDataGetBytePtr(ptext), (unsigned)ptextLen, @@ -420,6 +425,7 @@ errOut: CFReleaseNull(cfOut); cleanup: /* it would be proper to zero out ptext here, but we can't do that to a CFData */ + free(ctext); CFRelease(ptext); return ourRtn; } diff --git a/OSX/libsecurity_apple_x509_tp/lib/tpPolicies.cpp b/OSX/libsecurity_apple_x509_tp/lib/tpPolicies.cpp index cdedecc7..786c21f1 100644 --- a/OSX/libsecurity_apple_x509_tp/lib/tpPolicies.cpp +++ b/OSX/libsecurity_apple_x509_tp/lib/tpPolicies.cpp @@ -167,9 +167,6 @@ const CSSM_OID CSSMOID_PIV_AUTH = {PIV_AUTH_OID_LEN, (uint8 *)OID_PIV_AUTH}; static const uint8 OID_PIV_AUTH_2048[] = {PIV_AUTH_2048_OID}; const CSSM_OID CSSMOID_PIV_AUTH_2048 = {PIV_AUTH_2048_OID_LEN, (uint8 *)OID_PIV_AUTH_2048}; -static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup, - const CSSM_DATA *fieldOpts, // optional Common Name - const iSignCertInfo *certInfo); /* * Setup a single iSignExtenInfo. Called once per known extension * per cert. @@ -1990,7 +1987,7 @@ static CSSM_RETURN tp_verifyMacAppStoreReceiptOpts( if (!isCertInfo->basicConstraints.present) { - tpPolicyError("tp_verifyAppleIDSharingOpts: no basicConstraints in intermediate"); + tpPolicyError("tp_verifyMacAppStoreReceiptOpts: no basicConstraints in intermediate"); if (tpCert->addStatusCode(CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS)) return CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS; } @@ -2037,177 +2034,6 @@ bool certificatePoliciesContainsOID(const CE_CertPolicies *certPolicies, const C return false; } - -/* - * Verify Apple ID Sharing options. - * - * -- Do basic cert validation (OCSP-based certs) - * -- Validate that the cert is an Apple ID sharing cert: - * has a custom extension: OID: Apple ID Sharing Certificate ( 1 2 840 113635 100 4 7 ) - * (CSSMOID_APPLE_EXTENSION_APPLEID_SHARING) - * EKU should have both client and server authentication - * chains to the "Apple Application Integration Certification Authority" intermediate - * -- optionally has a client-specified common name, which is the Apple ID account's UUID. - - * -- Must have one intermediate cert ("Apple Application Integration Certification Authority") - * -- intermediate must have basic constraints with path length 0 - * -- intermediate has CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE extension (OID 1 2 840 113635 100 6 2 3) - OR APPLE_EXTENSION_AAI_INTERMEDIATE_2 - */ - -static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup, - const CSSM_DATA *fieldOpts, // optional Common Name - const iSignCertInfo *certInfo) // all certs, size certGroup.numCerts() -{ - unsigned numCerts = certGroup.numCerts(); - const iSignCertInfo *isCertInfo; - TPCertInfo *tpCert; - // const CE_BasicConstraints *bc; // currently unused - CE_ExtendedKeyUsage *eku; - CSSM_RETURN crtn = CSSM_OK; - unsigned int serverNameLen = 0; - const char *serverName = NULL; - - // The CSSM_APPLE_TP_SMIME_OPTIONS pointer is optional as is everything in it. - if (fieldOpts && fieldOpts->Data) - { - CSSM_APPLE_TP_SSL_OPTIONS *sslOpts = (CSSM_APPLE_TP_SSL_OPTIONS *)fieldOpts->Data; - switch (sslOpts->Version) - { - case CSSM_APPLE_TP_SSL_OPTS_VERSION: - if (fieldOpts->Length != sizeof(CSSM_APPLE_TP_SSL_OPTIONS)) - return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS; - break; - /* handle backwards compatibility here if necessary */ - default: - return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS; - } - serverNameLen = sslOpts->ServerNameLen; - serverName = sslOpts->ServerName; - } - - //------------------------------------------------------------------------ - - if (numCerts != 3) - { - if (!certGroup.isAllowedError(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH)) - { - tpPolicyError("tp_verifyAppleIDSharingOpts: numCerts %u", numCerts); - return CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH; - } - else - if (numCerts < 3) - { - /* this error allowed, but no intermediate...check leaf */ - goto checkLeaf; - } - } - - /* verify intermediate cert */ - isCertInfo = &certInfo[1]; - tpCert = certGroup.certAtIndex(1); - - if (!isCertInfo->basicConstraints.present) - { - tpPolicyError("tp_verifyAppleIDSharingOpts: no basicConstraints in intermediate"); - if (tpCert->addStatusCode(CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS)) - return CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS; - } - -checkLeaf: - - /* verify leaf cert */ - isCertInfo = &certInfo[0]; - tpCert = certGroup.certAtIndex(0); - - /* host name check is optional */ - if (serverNameLen != 0) - { - if (serverName == NULL) - return CSSMERR_TP_INVALID_POINTER; - - /* convert caller's hostname string to lower case */ - char *hostName = (char *)certGroup.alloc().malloc(serverNameLen); - memmove(hostName, serverName, serverNameLen); - tpToLower(hostName, serverNameLen); - - /* Check common name... */ - - bool fieldFound; - CSSM_BOOL match = tpCompareSubjectName(*tpCert, SN_CommonName, false, hostName, - serverNameLen, fieldFound); - - certGroup.alloc().free(hostName); - if (!match && tpCert->addStatusCode(CSSMERR_APPLETP_HOSTNAME_MISMATCH)) - return CSSMERR_APPLETP_HOSTNAME_MISMATCH; - } - - if (certInfo->certificatePolicies.present) - { - const CE_CertPolicies *certPolicies = - &isCertInfo->certificatePolicies.extnData->certPolicies; - if (!certificatePoliciesContainsOID(certPolicies, &CSSMOID_APPLEID_SHARING_CERT_POLICY)) - if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION)) - return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION; - } - else - if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION)) - return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION; - - if (!isCertInfo->extendKeyUsage.present) - { - tpPolicyError("tp_verifyAppleIDSharingOpts: no extendedKeyUse in leaf"); - if (tpCert->addStatusCode(CSSMERR_APPLETP_CS_NO_EXTENDED_KEY_USAGE)) - return crtn ? crtn : CSSMERR_APPLETP_CS_NO_EXTENDED_KEY_USAGE; - - /* have to skip remainder */ - return CSSM_OK; - } - - // Check that certificate can do Client and Server Authentication (EKU) - eku = &isCertInfo->extendKeyUsage.extnData->extendedKeyUsage; - assert(eku != NULL); - if(eku->numPurposes != 2) - { - tpPolicyError("tp_verifyAppleIDSharingOpts: bad eku->numPurposes (%lu)", - (unsigned long)eku->numPurposes); - if (tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE)) - { - if (crtn == CSSM_OK) - crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE; - } - return crtn; - } - bool canDoClientAuth = false, canDoServerAuth = false, ekuError = false; - for (int ix=0;ix<2;ix++) - { - if (tpCompareOids(&eku->purposes[ix], &CSSMOID_ClientAuth)) - canDoClientAuth = true; - else - if (tpCompareOids(&eku->purposes[ix], &CSSMOID_ServerAuth)) - canDoServerAuth = true; - else - { - ekuError = true; - break; - } - } - - if (!(canDoClientAuth && canDoServerAuth)) - ekuError = true; - if (ekuError) - { - tpPolicyError("tp_verifyAppleIDSharingOpts: bad EKU in leaf"); - if (tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE)) - { - if (crtn == CSSM_OK) - crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE; - } - } - - return crtn; -} - /* * Verify Time Stamping (RFC3161) policy options. * @@ -3325,8 +3151,11 @@ CSSM_RETURN tp_policyVerify( policyError = tp_verifyMacAppStoreReceiptOpts(*certGroup, policyFieldData, certInfo); break; case kTP_AppleIDSharing: - policyError = tp_verifyAppleIDSharingOpts(*certGroup, policyFieldData, certInfo); - break; + /* As of macOS 10.12, this code path should be unused. Until we can remove this + * module entirely, ensure that no Apple ID evaluations take this path. [10119995] */ + tpPolicyError("tp_policyVerify: unexpected attempt to use legacy kTP_AppleIDSharing"); + policyFail = CSSM_TRUE; + abort(); case kTP_TimeStamping: policyError = tp_verifyTimeStampingOpts(*certGroup, policyFieldData, certInfo); break; diff --git a/OSX/libsecurity_asn1/lib/SecAsn1Types.h b/OSX/libsecurity_asn1/lib/SecAsn1Types.h index 9cb362b9..76616d62 100644 --- a/OSX/libsecurity_asn1/lib/SecAsn1Types.h +++ b/OSX/libsecurity_asn1/lib/SecAsn1Types.h @@ -48,9 +48,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR -/* @@@ We need something that tells us which platform we are building - for that let's us distinguish if we are doing an emulator build. */ +#if !TARGET_OS_OSX typedef struct { size_t Length; diff --git a/OSX/libsecurity_asn1/lib/X509Templates.h b/OSX/libsecurity_asn1/lib/X509Templates.h index c4532d14..3822844f 100644 --- a/OSX/libsecurity_asn1/lib/X509Templates.h +++ b/OSX/libsecurity_asn1/lib/X509Templates.h @@ -84,6 +84,9 @@ typedef struct { extern const SecAsn1Template kSecAsn1CertExtensionTemplate[]; extern const SecAsn1Template kSecAsn1SequenceOfCertExtensionTemplate[]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + /* * X.509 certificate object (the unsigned form) * @@ -192,6 +195,8 @@ typedef struct { extern const SecAsn1Template kSecAsn1SignedCertOrCRLTemplate[]; +#pragma clang diagnostic pop + #ifdef __cplusplus } #endif diff --git a/OSX/libsecurity_asn1/lib/ocspTemplates.h b/OSX/libsecurity_asn1/lib/ocspTemplates.h index 2af1efc3..1d338e9e 100644 --- a/OSX/libsecurity_asn1/lib/ocspTemplates.h +++ b/OSX/libsecurity_asn1/lib/ocspTemplates.h @@ -33,6 +33,9 @@ extern "C" { #endif +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + // MARK: ----- OCSP Request ----- /* @@ -330,6 +333,8 @@ typedef struct { extern const SecAsn1Template kSecAsn1OCSPDReplyTemplate[]; extern const SecAsn1Template kSecAsn1OCSPDRepliesTemplate[]; +#pragma clang diagnostic pop + #ifdef __cplusplus } #endif diff --git a/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h b/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h index baed6963..8700bda6 100644 --- a/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h +++ b/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h @@ -255,7 +255,7 @@ typedef struct AuthorizationCallbacks { userful for kSecUseAuthenticationContext for SecItem calls. Caller is responsible for outValue release */ OSStatus (*GetLAContext)(AuthorizationEngineRef inEngine, - CFTypeRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13, __PHONE_NA); + CFTypeRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_NA); /* Available only on systems with callback version 2 or higher @@ -265,14 +265,14 @@ typedef struct AuthorizationCallbacks { Caller is responsible for outValue release */ OSStatus (*GetTokenIdentities)(AuthorizationEngineRef inEngine, CFTypeRef context, - CFArrayRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13, __PHONE_NA); + CFArrayRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_NA); /* Available only on systems with callback version 3 or higher Constructs TKTokenWatcher object. Caller is responsible for outValue release */ OSStatus (*GetTKTokenWatcher)(AuthorizationEngineRef inEngine, - CFTypeRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __PHONE_NA); + CFTypeRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_NA); } AuthorizationCallbacks; diff --git a/OSX/libsecurity_cdsa_plugin/lib/CSPsession.cpp b/OSX/libsecurity_cdsa_plugin/lib/CSPsession.cpp index a66e068d..c138fb5a 100644 --- a/OSX/libsecurity_cdsa_plugin/lib/CSPsession.cpp +++ b/OSX/libsecurity_cdsa_plugin/lib/CSPsession.cpp @@ -742,7 +742,11 @@ void CSPFullPluginSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle, // make data to be encrypted unsigned bytesInKey = encryptingKey->KeyHeader.LogicalKeySizeInBits / 8; - u_int8_t buffer[bytesInKey]; + u_int8_t *buffer = (u_int8_t*)malloc(bytesInKey); + if (buffer == NULL) { + CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR); + } + unsigned i; for (i = 0; i < bytesInKey; ++i) @@ -759,6 +763,7 @@ void CSPFullPluginSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle, CSSM_RETURN result = CSSM_CSP_CreateAsymmetricContext(moduleHandle, encryptingKey->KeyHeader.AlgorithmId, &nullCreds, encryptingKey, CSSM_PADDING_NONE, &encryptHandle); if (result != CSSM_OK) { + free(buffer); CssmError::throwMe(result); } @@ -769,6 +774,7 @@ void CSPFullPluginSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle, result = CSSM_QuerySize(encryptHandle, CSSM_TRUE, 1, &qsData); if (result == CSSMERR_CSP_INVALID_ALGORITHM) { + free(buffer); return; } @@ -780,6 +786,7 @@ void CSPFullPluginSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle, result = CSSM_EncryptData(encryptHandle, &clearBuf, 1, &cipherBuf, 1, &bytesEncrypted, &remData); if (result != CSSM_OK) { + free(buffer); CssmError::throwMe(result); } @@ -803,12 +810,14 @@ void CSPFullPluginSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle, if (result != CSSM_OK) { + free(buffer); CssmError::throwMe(result); } result = CSSM_DecryptData(decryptHandle, &cipherBuf, 1, &decryptedBuf, 1, &bytesEncrypted, &remData); if (result != CSSM_OK) { + free(buffer); CssmError::throwMe(result); } @@ -826,6 +835,8 @@ void CSPFullPluginSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle, { free(remData.Data); } + + free(buffer); } void CSPFullPluginSession::ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey, diff --git a/OSX/libsecurity_cdsa_utilities/lib/cssmcred.cpp b/OSX/libsecurity_cdsa_utilities/lib/cssmcred.cpp index 5f877bbc..ee66a633 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/cssmcred.cpp +++ b/OSX/libsecurity_cdsa_utilities/lib/cssmcred.cpp @@ -30,20 +30,6 @@ namespace Security { - -// -// The null credential constant. -// -static const CSSM_ACCESS_CREDENTIALS null_credentials = { "" }; // and more nulls -#if BUG_GCC -const AccessCredentials &AccessCredentials::null = - *static_cast(&null_credentials); -#else -const AccessCredentials &AccessCredentials::null = - static_cast(null_credentials); -#endif - - // // Scan a SampleGroup for samples with a given CSSM_SAMPLE_TYPE. // Collect all matching samples into a list (which is cleared to begin with). @@ -67,6 +53,12 @@ bool SampleGroup::collect(CSSM_SAMPLE_TYPE sampleType, list &matches // // AccessCredentials // +const AccessCredentials& AccessCredentials::null_credential() +{ + static const CSSM_ACCESS_CREDENTIALS null_credentials = { "" }; // and more nulls + return AccessCredentials::overlay(null_credentials); +} + void AccessCredentials::tag(const char *tagString) { if (tagString == NULL) diff --git a/OSX/libsecurity_cdsa_utilities/lib/cssmcred.h b/OSX/libsecurity_cdsa_utilities/lib/cssmcred.h index 1b70b767..2a827f18 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/cssmcred.h +++ b/OSX/libsecurity_cdsa_utilities/lib/cssmcred.h @@ -102,11 +102,11 @@ public: bool authorizesUI() const; public: - static const AccessCredentials &null; // all null credential + static const AccessCredentials& null_credential(); // turn NULL into a null credential if needed static const AccessCredentials *needed(const CSSM_ACCESS_CREDENTIALS *cred) - { return cred ? overlay(cred) : &null; } + { return cred ? overlay(cred) : &null_credential(); } }; diff --git a/OSX/libsecurity_cdsa_utilities/lib/objectacl.cpp b/OSX/libsecurity_cdsa_utilities/lib/objectacl.cpp index 80989e2d..a44c8fa3 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/objectacl.cpp +++ b/OSX/libsecurity_cdsa_utilities/lib/objectacl.cpp @@ -43,7 +43,7 @@ using namespace DataWalkers; // These are the kinds of ACL subjects we can deal with. // ModuleNexus ObjectAcl::makers; -NormalMutex ObjectAcl::makersMutex; +ModuleNexus ObjectAcl::makersMutex; // @@ -579,7 +579,7 @@ void ObjectAcl::AclEntry::importBlob(Reader &pub, Reader &priv) AclSubject::Maker::Maker(CSSM_ACL_SUBJECT_TYPE type) : mType(type) { - StLock _(ObjectAcl::makersMutex); + StLock _(ObjectAcl::makersMutex()); ObjectAcl::makers()[type] = this; } @@ -598,7 +598,7 @@ AclSubject *ObjectAcl::make(uint32 typeAndVersion, Reader &pub, Reader &priv) AclSubject::Maker &ObjectAcl::makerFor(CSSM_ACL_SUBJECT_TYPE type) { - StLock _(ObjectAcl::makersMutex); + StLock _(ObjectAcl::makersMutex()); AclSubject::Maker *maker = makers()[type]; if (maker == NULL) CssmError::throwMe(CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED); diff --git a/OSX/libsecurity_cdsa_utilities/lib/objectacl.h b/OSX/libsecurity_cdsa_utilities/lib/objectacl.h index 67427cdf..46cefc54 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/objectacl.h +++ b/OSX/libsecurity_cdsa_utilities/lib/objectacl.h @@ -242,7 +242,7 @@ private: private: typedef map MakerMap; static ModuleNexus makers; // registered subject Makers - static NormalMutex makersMutex; + static ModuleNexus makersMutex; static AclSubject::Maker &makerFor(CSSM_ACL_SUBJECT_TYPE type); }; diff --git a/OSX/libsecurity_cdsa_utilities/lib/osxverifier.cpp b/OSX/libsecurity_cdsa_utilities/lib/osxverifier.cpp index 6075df06..bd2b8299 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/osxverifier.cpp +++ b/OSX/libsecurity_cdsa_utilities/lib/osxverifier.cpp @@ -126,8 +126,8 @@ void OSXVerifier::makeLegacyHash(OSXCode *code, SHA1::Digest digest) { secinfo("codesign", "calculating legacy hash for %s", code->canonicalPath().c_str()); UnixPlusPlus::AutoFileDesc fd(code->executablePath(), O_RDONLY); - char buffer[legacyHashLimit]; - size_t size = fd.read(buffer, legacyHashLimit); + char buffer[LEGACY_HASH_LIMIT]; + size_t size = fd.read(buffer, LEGACY_HASH_LIMIT); SHA1 hash; hash(buffer, size); hash.finish(digest); diff --git a/OSX/libsecurity_cdsa_utilities/lib/osxverifier.h b/OSX/libsecurity_cdsa_utilities/lib/osxverifier.h index 596e65b5..e2b9b151 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/osxverifier.h +++ b/OSX/libsecurity_cdsa_utilities/lib/osxverifier.h @@ -31,6 +31,8 @@ #include #include +#define LEGACY_HASH_LIMIT 16*1024 + namespace Security { @@ -43,7 +45,7 @@ namespace Security { // class OSXVerifier { public: - static const size_t legacyHashLimit = 16 * 1024; + static const size_t legacyHashLimit = LEGACY_HASH_LIMIT; static const uint32_t commentAlignment = 4; public: diff --git a/OSX/libsecurity_cdsa_utils/lib/cuCdsaUtils.cpp b/OSX/libsecurity_cdsa_utils/lib/cuCdsaUtils.cpp index a516d362..3171927a 100644 --- a/OSX/libsecurity_cdsa_utils/lib/cuCdsaUtils.cpp +++ b/OSX/libsecurity_cdsa_utils/lib/cuCdsaUtils.cpp @@ -502,7 +502,7 @@ CSSM_RETURN cuCspGenKeyPair(CSSM_CSP_HANDLE cspHand, CSSM_CC_HANDLE ccHand; CSSM_DATA keyLabelData; - keyLabelData.Data = (uint8 *)keyLabel, + keyLabelData.Data = (uint8 *)keyLabel; keyLabelData.Length = keyLabelLen; memset(pubKey, 0, sizeof(CSSM_KEY)); memset(privKey, 0, sizeof(CSSM_KEY)); diff --git a/OSX/libsecurity_cms/lib/CMSDecoder.cpp b/OSX/libsecurity_cms/lib/CMSDecoder.cpp index bcf4e5d6..a6fb2688 100644 --- a/OSX/libsecurity_cms/lib/CMSDecoder.cpp +++ b/OSX/libsecurity_cms/lib/CMSDecoder.cpp @@ -311,7 +311,9 @@ OSStatus CMSDecoderFinalizeMessage( (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci); /* dig down one more layer for eContentType */ ci = SecCmsSignedDataGetContentInfo(cmsDecoder->signedData); - cmsDecoder->eContentType = SecCmsContentInfoGetContentTypeOID(ci); + if (ci) { + cmsDecoder->eContentType = SecCmsContentInfoGetContentTypeOID(ci); + } break; default: break; @@ -1072,3 +1074,42 @@ exit: } return status; } + +/* + * Obtain the expiration time of signer 'signerIndex' of a CMS message, if + * present. This is part of the signed attributes of the message. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerAppleExpirationTime( + CMSDecoderRef cmsDecoder, + size_t signerIndex, + CFAbsoluteTime *expirationTime) /* RETURNED */ +{ + OSStatus status = errSecParam; + SecCmsMessageRef cmsg = NULL; + int numContentInfos = 0; + SecCmsSignedDataRef signedData = NULL; + + require(cmsDecoder && expirationTime, xit); + require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit); + numContentInfos = SecCmsMessageContentLevelCount(cmsg); + for (int dex = 0; !signedData && dex < numContentInfos; dex++) { + SecCmsContentInfoRef ci = SecCmsMessageContentLevel(cmsg, dex); + SECOidTag tag = SecCmsContentInfoGetContentTypeTag(ci); + if (tag == SEC_OID_PKCS7_SIGNED_DATA) { + if ((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci))) { + SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(signedData, (int)signerIndex); + if (signerInfo) { + status = SecCmsSignerInfoGetAppleExpirationTime(signerInfo, expirationTime); + break; + } + } + } + } +xit: + return status; +} diff --git a/OSX/libsecurity_cms/lib/CMSDecoder.h b/OSX/libsecurity_cms/lib/CMSDecoder.h index f0357bd0..7194f286 100644 --- a/OSX/libsecurity_cms/lib/CMSDecoder.h +++ b/OSX/libsecurity_cms/lib/CMSDecoder.h @@ -318,6 +318,8 @@ OSStatus CMSDecoderCopySignerSigningTime( CFAbsoluteTime *signingTime) /* RETURNED */ __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); +#define TIMESTAMPING_SUPPORTED 1 +#if TIMESTAMPING_SUPPORTED /* * Obtain the timestamp of signer 'signerIndex' of a CMS message, if * present. This timestamp is an authenticated timestamp provided by @@ -368,6 +370,7 @@ OSStatus CMSDecoderCopySignerTimestampCertificates( size_t signerIndex, /* usually 0 */ CFArrayRef * __nonnull CF_RETURNS_RETAINED certificateRefs) /* RETURNED */ __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); +#endif // TIMESTAMPING_SUPPORTED CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_cms/lib/CMSEncoder.cpp b/OSX/libsecurity_cms/lib/CMSEncoder.cpp index f8cb11be..de3b2c1e 100644 --- a/OSX/libsecurity_cms/lib/CMSEncoder.cpp +++ b/OSX/libsecurity_cms/lib/CMSEncoder.cpp @@ -99,6 +99,7 @@ struct _CMSEncoder { CMSCertificateChainMode chainMode; CFDataRef hashAgilityAttrValue; CFDictionaryRef hashAgilityV2AttrValues; + CFAbsoluteTime expirationTime; }; static void cmsEncoderInit(CFTypeRef enc); @@ -280,12 +281,20 @@ static int convertOid( // CFStringRef: OID representation is a dotted-decimal string CFStringRef inStr = (CFStringRef)inRef; CFIndex max = CFStringGetLength(inStr) * 3; - char buf[max]; - if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII)) + char *buf = (char *)malloc(max); + if (!buf) { + return errSecMemoryError; + } + if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII)) { + free(buf); return errSecParam; + } - if(encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0) + if (encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0) { + free(buf); return errSecParam; + } + free(buf); } else if (CFGetTypeID(inRef) == CFDataGetTypeID()) { // CFDataRef: OID representation is in binary DER format @@ -543,6 +552,14 @@ static OSStatus cmsSetupForSignedData( break; } } + if (cmsEncoder->signedAttributes & kCMSAttrAppleExpirationTime) { + ortn = SecCmsSignerInfoAddAppleExpirationTime(signerInfo, cmsEncoder->expirationTime); + if(ortn) { + ortn = cmsRtnToOSStatus(ortn); + CSSM_PERROR("SecCmsSignerInfoAddAppleExpirationTime", ortn); + break; + } + } ortn = SecCmsSignedDataAddSignerInfo(signedData, signerInfo); if(ortn) { @@ -1051,6 +1068,24 @@ OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2( return errSecSuccess; } +/* + * Set the expiration time for a CMSEncoder. + * This is only used if the kCMSAttrAppleExpirationTime attribute is included. + */ +OSStatus CMSEncoderSetAppleExpirationTime( + CMSEncoderRef cmsEncoder, + CFAbsoluteTime time) +{ + if(cmsEncoder == NULL) { + return errSecParam; + } + if(cmsEncoder->encState != ES_Init) { + return errSecParam; + } + cmsEncoder->expirationTime = time; + return errSecSuccess; +} + OSStatus CMSEncoderSetCertificateChainMode( CMSEncoderRef cmsEncoder, CMSCertificateChainMode chainMode) diff --git a/OSX/libsecurity_cms/lib/CMSEncoder.h b/OSX/libsecurity_cms/lib/CMSEncoder.h index a39bcbb9..32ec916a 100644 --- a/OSX/libsecurity_cms/lib/CMSEncoder.h +++ b/OSX/libsecurity_cms/lib/CMSEncoder.h @@ -44,6 +44,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -170,8 +171,7 @@ OSStatus CMSEncoderGetHasDetachedContent( OSStatus CMSEncoderSetEncapsulatedContentType( CMSEncoderRef cmsEncoder, const CSSM_OID *eContentType) - /* DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + API_DEPRECATED_WITH_REPLACEMENT("CMSEncoderSetEncapsulatedContentTypeOID", macos(10.5, 10.7)) API_UNAVAILABLE(ios); /* * Optionally specify an eContentType OID for the inner EncapsulatedData for @@ -268,6 +268,10 @@ typedef CF_OPTIONS(uint32_t, CMSSignedAttributes) { */ kCMSAttrAppleCodesigningHashAgility = 0x0010, kCMSAttrAppleCodesigningHashAgilityV2 = 0x0020, + /* + * Include the expiration time. + */ + kCMSAttrAppleExpirationTime = 0x0040, }; /* @@ -366,8 +370,7 @@ OSStatus CMSEncode( const void * content, size_t contentLen, CFDataRef * __nonnull CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */ - /* DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + API_DEPRECATED_WITH_REPLACEMENT("CMSEncodeContent", macos(10.5, 10.7)) API_UNAVAILABLE(ios); /* diff --git a/OSX/libsecurity_cms/lib/CMSPrivate.h b/OSX/libsecurity_cms/lib/CMSPrivate.h index 8278dbf5..d951d912 100644 --- a/OSX/libsecurity_cms/lib/CMSPrivate.h +++ b/OSX/libsecurity_cms/lib/CMSPrivate.h @@ -104,6 +104,14 @@ OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2( CMSEncoderRef cmsEncoder, CFDictionaryRef hashAgilityV2AttrValues); +/* + * Set the expiration time for a CMSEncoder. + * This is only used if the kCMSAttrAppleExpirationTime attribute is included. + */ +OSStatus CMSEncoderSetAppleExpirationTime( + CMSEncoderRef cmsEncoder, + CFAbsoluteTime time); + void CmsMessageSetTSAContext(CMSEncoderRef cmsEncoder, CFTypeRef tsaContext); @@ -173,6 +181,20 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgilityV2( CMSDecoderRef cmsDecoder, size_t signerIndex, /* usually 0 */ CFDictionaryRef CF_RETURNS_RETAINED * hashAgilityAttrValues); /* RETURNED */ + +/* + * Obtain the expiration time of signer 'signerIndex' of a CMS message, if + * present. This is part of the signed attributes of the message. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerAppleExpirationTime( + CMSDecoderRef cmsDecoder, + size_t signerIndex, + CFAbsoluteTime *expirationTime); /* RETURNED */ #ifdef __cplusplus } diff --git a/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj b/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj index 93dc2f9c..1517e57b 100644 --- a/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj +++ b/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj @@ -17,8 +17,6 @@ D43B9E7E1D064F0B00B9DDDA /* cms-trust-settings-test.c in Sources */ = {isa = PBXBuildFile; fileRef = D43B9E7C1D064F0B00B9DDDA /* cms-trust-settings-test.c */; }; D43B9E7F1D064F0B00B9DDDA /* cms-trust-settings-test.h in Headers */ = {isa = PBXBuildFile; fileRef = D43B9E7D1D064F0B00B9DDDA /* cms-trust-settings-test.h */; }; D4C334601BE2A2B900D8C1EF /* cms_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = D4C334571BE29F5200D8C1EF /* cms_regressions.h */; }; - D4C334631BE2A31200D8C1EF /* cms-hashagility-test.m in Sources */ = {isa = PBXBuildFile; fileRef = D4C334611BE2A31200D8C1EF /* cms-hashagility-test.m */; }; - D4C334641BE2A31200D8C1EF /* cms-hashagility-test.h in Headers */ = {isa = PBXBuildFile; fileRef = D4C334621BE2A31200D8C1EF /* cms-hashagility-test.h */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -38,8 +36,6 @@ D43B9E7D1D064F0B00B9DDDA /* cms-trust-settings-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "cms-trust-settings-test.h"; path = "regressions/cms-trust-settings-test.h"; sourceTree = ""; }; D4C334571BE29F5200D8C1EF /* cms_regressions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cms_regressions.h; path = regressions/cms_regressions.h; sourceTree = ""; }; D4C3345C1BE2A2B100D8C1EF /* libsecurity_cms_regressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_cms_regressions.a; sourceTree = BUILT_PRODUCTS_DIR; }; - D4C334611BE2A31200D8C1EF /* cms-hashagility-test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "cms-hashagility-test.m"; path = "regressions/cms-hashagility-test.m"; sourceTree = ""; }; - D4C334621BE2A31200D8C1EF /* cms-hashagility-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "cms-hashagility-test.h"; path = "regressions/cms-hashagility-test.h"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -111,8 +107,6 @@ D4C334571BE29F5200D8C1EF /* cms_regressions.h */, D43B9E7C1D064F0B00B9DDDA /* cms-trust-settings-test.c */, D43B9E7D1D064F0B00B9DDDA /* cms-trust-settings-test.h */, - D4C334611BE2A31200D8C1EF /* cms-hashagility-test.m */, - D4C334621BE2A31200D8C1EF /* cms-hashagility-test.h */, ); name = regressions; sourceTree = ""; @@ -136,7 +130,6 @@ buildActionMask = 2147483647; files = ( D43B9E7F1D064F0B00B9DDDA /* cms-trust-settings-test.h in Headers */, - D4C334641BE2A31200D8C1EF /* cms-hashagility-test.h in Headers */, D4C334601BE2A2B900D8C1EF /* cms_regressions.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -184,7 +177,7 @@ 4CA1FEAB052A3C3800F22E42 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0810; + LastUpgradeCheck = 1000; TargetAttributes = { D4C3345B1BE2A2B100D8C1EF = { CreatedOnToolsVersion = 7.1; @@ -224,7 +217,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D4C334631BE2A31200D8C1EF /* cms-hashagility-test.m in Sources */, D43B9E7E1D064F0B00B9DDDA /* cms-trust-settings-test.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -236,6 +228,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 18446178146E984400B12992 /* debug.xcconfig */; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; }; name = Debug; @@ -244,6 +237,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 1844617A146E984400B12992 /* release.xcconfig */; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; }; name = Release; @@ -253,12 +247,20 @@ baseConfigurationReference = 18446179146E984400B12992 /* lib.xcconfig */; buildSettings = { ASSETCATALOG_COMPRESSION = lossless; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -278,12 +280,20 @@ baseConfigurationReference = 18446179146E984400B12992 /* lib.xcconfig */; buildSettings = { ASSETCATALOG_COMPRESSION = "respect-asset-catalog"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; diff --git a/OSX/libsecurity_cms/regressions/cms-hashagility-test.h b/OSX/libsecurity_cms/regressions/cms-hashagility-test.h deleted file mode 100644 index f58da959..00000000 --- a/OSX/libsecurity_cms/regressions/cms-hashagility-test.h +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * Copyright (c) 2015 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@ - */ - -#ifndef cms_hashagility_test_h -#define cms_hashagility_test_h - -#include -#include - -int cms_hash_agility_test(int argc, char *const *argv); - -/* - * password: "password" - * localKeyID: 01 AE 1A 61 75 AE 23 D9 11 5C 28 93 A9 E2 49 5E 74 28 4C 08 - * subject=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer - * issuer=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer - */ -unsigned char signing_identity_p12[4477] = { - 0x30, 0x82, 0x11, 0x79, 0x02, 0x01, 0x03, 0x30, 0x82, 0x11, 0x3f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x07, 0x01, 0xa0, 0x82, 0x11, 0x30, 0x04, 0x82, 0x11, 0x2c, 0x30, 0x82, 0x11, 0x28, 0x30, 0x82, 0x07, 0x57, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x07, 0x48, 0x30, 0x82, 0x07, 0x44, 0x02, 0x01, 0x00, - 0x30, 0x82, 0x07, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xed, 0xd8, 0x65, 0x57, 0xbb, 0xca, 0x25, - 0x46, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x07, 0x10, 0xc0, 0x1d, 0x0d, 0x5c, 0x7f, 0x3b, 0xbe, 0x20, 0xd4, 0x9a, 0x0d, - 0xaf, 0xb6, 0x4b, 0xc7, 0x7f, 0xa8, 0xa8, 0x3f, 0x6c, 0x96, 0x1c, 0xea, 0x90, 0xd2, 0x79, 0x9f, 0x56, 0x3a, 0x5a, 0x29, - 0x93, 0xff, 0x72, 0x39, 0x9e, 0x41, 0xd9, 0x5a, 0xfc, 0xb5, 0x54, 0x2d, 0x89, 0x60, 0x18, 0xf2, 0xea, 0x8c, 0xeb, 0x7f, - 0xba, 0x87, 0xc6, 0x70, 0x42, 0x25, 0x55, 0x24, 0xc5, 0x4f, 0x26, 0x66, 0x8d, 0x78, 0x44, 0x47, 0x85, 0x36, 0x53, 0x86, - 0xc9, 0x18, 0x83, 0x33, 0x4b, 0x4b, 0x08, 0x2d, 0x7b, 0x68, 0x37, 0x29, 0x4c, 0x20, 0x74, 0xd4, 0x4f, 0xbb, 0x6e, 0x97, - 0x7a, 0xf4, 0xbf, 0xcb, 0x40, 0x26, 0x2d, 0xac, 0x95, 0x82, 0xe0, 0x88, 0xfe, 0x54, 0x80, 0xe9, 0xf5, 0xda, 0x8e, 0x6e, - 0x3a, 0x47, 0x2d, 0xc8, 0xd4, 0xe7, 0x2e, 0xff, 0xec, 0xfa, 0xa5, 0x70, 0xcd, 0x2e, 0x99, 0x26, 0x32, 0xc8, 0x1d, 0x53, - 0x60, 0x1e, 0x6f, 0x68, 0xcb, 0x49, 0xd0, 0xa2, 0xf8, 0x47, 0x70, 0x1b, 0x9e, 0x85, 0xbe, 0x4e, 0x56, 0xb5, 0x8b, 0x66, - 0x45, 0x57, 0xe3, 0xbd, 0x57, 0xed, 0x94, 0x53, 0xf6, 0x72, 0xd7, 0xb7, 0xc6, 0x9f, 0x05, 0xf5, 0x98, 0xb4, 0x13, 0x35, - 0x69, 0x24, 0x94, 0xd9, 0x3d, 0x80, 0xbc, 0xa8, 0xea, 0x78, 0x0c, 0xe0, 0xa2, 0xfe, 0x1b, 0xd2, 0x82, 0x3d, 0x83, 0x34, - 0x76, 0xb4, 0x45, 0xf8, 0x14, 0x09, 0x66, 0x02, 0x68, 0xc3, 0x1b, 0xcb, 0x6c, 0x91, 0x6b, 0x3e, 0xdc, 0x35, 0x68, 0xab, - 0x49, 0x47, 0x6c, 0x60, 0xea, 0xe3, 0xd5, 0x59, 0x82, 0x9c, 0x18, 0xb0, 0x6d, 0x45, 0xc0, 0x2f, 0x58, 0xf1, 0x44, 0x79, - 0xe3, 0xd2, 0xd6, 0x16, 0xbc, 0xde, 0x17, 0xae, 0xf7, 0xea, 0x3c, 0xe4, 0xb4, 0x7b, 0xdf, 0xba, 0x9b, 0xf1, 0xb8, 0xa8, - 0xb0, 0x51, 0xeb, 0xe8, 0xc3, 0xe9, 0x9c, 0x1b, 0x06, 0xdd, 0x89, 0x07, 0x98, 0xf8, 0x01, 0x7f, 0xde, 0x7e, 0x05, 0xa6, - 0x72, 0x0b, 0x3f, 0xf4, 0x7d, 0xca, 0x74, 0x7b, 0xc9, 0x87, 0x0d, 0x35, 0x8b, 0x05, 0x3a, 0x73, 0x04, 0x08, 0x7a, 0x51, - 0x34, 0x29, 0x5b, 0xd8, 0x90, 0x0f, 0xa7, 0xf0, 0x48, 0xfc, 0x9c, 0x74, 0xca, 0xe9, 0x34, 0x75, 0x1c, 0xd1, 0xa6, 0xd1, - 0xfb, 0x9f, 0xc7, 0x82, 0x40, 0x75, 0x87, 0xdd, 0xa2, 0x22, 0xeb, 0x91, 0xd7, 0x85, 0x1a, 0x2c, 0xa7, 0x3d, 0xd5, 0xe4, - 0xca, 0x85, 0x00, 0x33, 0x11, 0x6d, 0x62, 0xa8, 0xb7, 0xd3, 0x45, 0x46, 0xdc, 0xb4, 0xa3, 0xeb, 0xae, 0x5e, 0x8c, 0xc2, - 0x7a, 0x0b, 0x83, 0x98, 0x5a, 0x94, 0x0f, 0x68, 0x61, 0x36, 0x57, 0x6e, 0x94, 0xe0, 0x6d, 0x93, 0x76, 0xa0, 0x5d, 0x3f, - 0x25, 0x8b, 0x3b, 0x46, 0x1e, 0x0c, 0x15, 0x6b, 0x9f, 0x1d, 0xc3, 0x5f, 0x61, 0x42, 0xd5, 0xf8, 0x79, 0xcd, 0xd1, 0x0a, - 0x96, 0xce, 0x49, 0x8a, 0xff, 0x54, 0x46, 0x77, 0x65, 0x37, 0x70, 0xcd, 0x65, 0x6f, 0x3d, 0x49, 0xc1, 0x29, 0x8d, 0x16, - 0xbd, 0x36, 0x47, 0x54, 0xa5, 0x4d, 0x06, 0xfb, 0x33, 0x00, 0x29, 0xd8, 0x31, 0x09, 0x58, 0x12, 0x4c, 0xfe, 0xef, 0x8e, - 0xf9, 0x1e, 0x30, 0xf7, 0x05, 0xb2, 0xd8, 0xd4, 0x7d, 0xae, 0xab, 0x57, 0xb7, 0x46, 0x09, 0xff, 0xca, 0xc7, 0x7b, 0xca, - 0x73, 0xfa, 0xf9, 0x50, 0xa0, 0xb8, 0x09, 0xc2, 0x80, 0x43, 0x0d, 0x99, 0x7f, 0x4e, 0xdf, 0xd5, 0x6c, 0xc4, 0x42, 0x1a, - 0x05, 0xbd, 0x65, 0xf4, 0x57, 0x2a, 0xe5, 0xc4, 0xcb, 0x79, 0x3f, 0x8f, 0x74, 0x93, 0x66, 0x8d, 0x93, 0xda, 0xba, 0x23, - 0x77, 0x3f, 0xad, 0xd3, 0x8b, 0xae, 0xf5, 0xf1, 0x5c, 0xc1, 0xd2, 0x00, 0x3a, 0x60, 0x8e, 0xc3, 0x32, 0xd6, 0x8e, 0xce, - 0x95, 0x24, 0x03, 0x79, 0x03, 0xf2, 0xb8, 0x2a, 0x94, 0xeb, 0x15, 0x97, 0xdc, 0x18, 0x8d, 0xc7, 0xd9, 0xc2, 0x63, 0x69, - 0xfb, 0xf9, 0x8f, 0x05, 0xd3, 0x7c, 0x60, 0x5a, 0x57, 0xe4, 0xa5, 0xc1, 0xdf, 0x1d, 0x11, 0x84, 0x69, 0xba, 0x20, 0xd8, - 0x79, 0xc3, 0x34, 0x3a, 0xb1, 0x63, 0x4c, 0xd2, 0x91, 0x2d, 0x87, 0x1e, 0xec, 0x06, 0xea, 0x35, 0x97, 0x0e, 0x59, 0x54, - 0x83, 0x50, 0x3e, 0xac, 0xf2, 0xea, 0x6c, 0x0c, 0xa0, 0x57, 0xfb, 0xe8, 0x6b, 0xf9, 0xd1, 0x25, 0xc0, 0xa2, 0xb0, 0xa2, - 0xcd, 0xde, 0x2b, 0xa7, 0xb3, 0x40, 0x75, 0x36, 0xf7, 0x20, 0xbe, 0xd7, 0xd1, 0x2e, 0x66, 0xc5, 0x3c, 0xf8, 0x6e, 0xce, - 0xcb, 0x76, 0x7f, 0x1d, 0x32, 0x3b, 0x14, 0x27, 0x9c, 0x9e, 0xa3, 0xeb, 0x0c, 0x2f, 0x71, 0xba, 0x0d, 0xca, 0x27, 0x90, - 0x42, 0xfd, 0xd4, 0x34, 0xb9, 0x96, 0xae, 0xcb, 0xd8, 0xfe, 0x31, 0x62, 0xe8, 0x4c, 0x07, 0x71, 0xb9, 0x0c, 0x9f, 0xe2, - 0x8e, 0x66, 0xc2, 0x39, 0xc5, 0xc3, 0x1c, 0xfd, 0x5e, 0x18, 0x0b, 0xd4, 0x93, 0x3d, 0x98, 0x33, 0xaf, 0x6d, 0xb4, 0x6f, - 0xe6, 0x75, 0x67, 0x62, 0xe7, 0x42, 0xee, 0xc6, 0xf2, 0x2e, 0x21, 0xa9, 0x75, 0xde, 0x0a, 0x8c, 0x39, 0xb7, 0x4b, 0x54, - 0x01, 0xa7, 0xeb, 0x5a, 0x88, 0x79, 0xa8, 0xb3, 0x3f, 0x31, 0x8c, 0x47, 0x08, 0x94, 0x47, 0x52, 0xcf, 0x3c, 0xac, 0xd9, - 0x32, 0x57, 0x4a, 0x18, 0x55, 0x5b, 0x66, 0xdc, 0x89, 0xd2, 0xc6, 0xa1, 0x11, 0x40, 0x19, 0x9c, 0x46, 0x88, 0x21, 0x77, - 0xc1, 0x7f, 0x09, 0xc7, 0xfb, 0x52, 0x92, 0xec, 0x1a, 0xe0, 0xdd, 0x76, 0xb9, 0xfd, 0xa7, 0x8f, 0x61, 0xe3, 0xf0, 0x1b, - 0x4e, 0xdb, 0xa0, 0xde, 0x90, 0xd6, 0x49, 0xea, 0xe9, 0x86, 0xc6, 0x5d, 0xac, 0xd0, 0xc2, 0xc5, 0x01, 0xcb, 0x3f, 0xcb, - 0xf0, 0x62, 0x90, 0xa1, 0x17, 0x4b, 0x72, 0x5c, 0xc8, 0xe9, 0x24, 0x93, 0xda, 0x5c, 0x75, 0x24, 0x96, 0x35, 0x54, 0xf4, - 0xfa, 0xc8, 0x27, 0xe1, 0xdd, 0x32, 0xda, 0x2f, 0x2b, 0x7d, 0xf6, 0xd8, 0x0b, 0xf2, 0xca, 0xb5, 0xee, 0x8a, 0xcf, 0xb6, - 0x26, 0x71, 0x65, 0x85, 0xfe, 0x8c, 0x37, 0xf1, 0x17, 0x6b, 0x5e, 0x8a, 0xee, 0xb4, 0xc7, 0x0a, 0xff, 0xb2, 0x9a, 0x72, - 0xe5, 0x85, 0xf3, 0xc0, 0xf9, 0x84, 0xbc, 0xe0, 0x18, 0x3c, 0x12, 0x0c, 0xa1, 0xe9, 0x10, 0xd4, 0x3b, 0x1a, 0x21, 0x35, - 0xc6, 0x06, 0x93, 0xa0, 0xdf, 0x0d, 0x68, 0xa3, 0xf1, 0x06, 0xd9, 0xed, 0xb7, 0xa7, 0xba, 0xb0, 0x22, 0xc2, 0x0b, 0x6b, - 0x70, 0x50, 0xf5, 0x49, 0x9a, 0x4f, 0x99, 0xaa, 0x1e, 0x9c, 0xa6, 0xf3, 0x99, 0x3a, 0xfd, 0x3b, 0xd2, 0xeb, 0xce, 0x1e, - 0x72, 0x62, 0x99, 0xc0, 0x1e, 0x2b, 0x09, 0x75, 0x4a, 0xfb, 0xc8, 0x26, 0xcf, 0x76, 0xa2, 0x0e, 0xef, 0xf4, 0xa8, 0x70, - 0x31, 0xd8, 0xa1, 0x22, 0x62, 0xcc, 0x9f, 0xd5, 0xa3, 0x55, 0xc2, 0x78, 0xd7, 0x27, 0xfc, 0x3c, 0x53, 0xe8, 0xeb, 0x7e, - 0x7a, 0x27, 0xcf, 0x6d, 0x52, 0xb5, 0x9a, 0x2b, 0x49, 0x8d, 0x3f, 0x89, 0x80, 0x1a, 0x5c, 0x39, 0xe7, 0x53, 0xb3, 0xf3, - 0x33, 0x97, 0xcf, 0x7d, 0xfb, 0x8e, 0x19, 0xf4, 0x72, 0xeb, 0xe7, 0xdf, 0xb1, 0xe3, 0xc1, 0x6c, 0x7f, 0x17, 0x89, 0x34, - 0x4f, 0x45, 0x0f, 0xc5, 0xfc, 0x15, 0xb3, 0x3f, 0xc6, 0xdc, 0x25, 0xa6, 0xda, 0x28, 0x85, 0x5d, 0x25, 0x02, 0x78, 0x74, - 0xd9, 0x74, 0xb8, 0x65, 0x48, 0x3a, 0x8a, 0x2a, 0xd5, 0xa9, 0xb8, 0x7f, 0xaa, 0x9d, 0xe7, 0xaf, 0xbd, 0xdf, 0xfd, 0x00, - 0x67, 0xab, 0x39, 0xe1, 0x2c, 0x3d, 0xd1, 0x5c, 0x9b, 0x61, 0x2b, 0x51, 0xdc, 0x87, 0x19, 0x6c, 0xa0, 0x12, 0xd4, 0x60, - 0xed, 0x94, 0xe9, 0xeb, 0x4e, 0x51, 0xd8, 0x50, 0xcb, 0x97, 0x8a, 0x20, 0x21, 0xdf, 0xe9, 0x2c, 0xd2, 0xe2, 0x04, 0x14, - 0xaf, 0x7b, 0x7e, 0xd6, 0xeb, 0x1d, 0x25, 0x09, 0x98, 0x8e, 0x9e, 0x56, 0xf8, 0x7d, 0xfc, 0x0f, 0xbf, 0xd2, 0x6b, 0xbc, - 0xab, 0xed, 0xca, 0x43, 0x6d, 0x28, 0xbe, 0xd5, 0x20, 0x44, 0xcb, 0x6b, 0xbc, 0x80, 0x5a, 0x82, 0x13, 0x50, 0xbd, 0xda, - 0x18, 0x10, 0xac, 0xae, 0x56, 0xb9, 0x46, 0xc5, 0xa2, 0xca, 0xb2, 0x03, 0xf0, 0x57, 0xfe, 0xcd, 0x9a, 0x1b, 0x81, 0x6a, - 0x10, 0x51, 0x2e, 0x88, 0x30, 0x57, 0x3c, 0xfe, 0x7c, 0x56, 0x0c, 0x00, 0x89, 0x5c, 0x21, 0x57, 0x19, 0x96, 0x85, 0x98, - 0xeb, 0x43, 0x71, 0x0d, 0x8a, 0x35, 0xc3, 0xae, 0x36, 0x59, 0x72, 0x97, 0x12, 0x6d, 0xcd, 0x28, 0x64, 0x17, 0x9e, 0xe7, - 0x2c, 0x28, 0xfd, 0x32, 0xa8, 0x10, 0x67, 0x4e, 0xc0, 0x14, 0x21, 0x7c, 0x36, 0x20, 0xe9, 0x46, 0x68, 0x62, 0xc1, 0xff, - 0xb0, 0xdf, 0xaa, 0x87, 0xff, 0x94, 0xa4, 0xf3, 0xb3, 0xc8, 0x53, 0x57, 0x18, 0x92, 0x15, 0xc7, 0x78, 0x2d, 0x91, 0xba, - 0xb3, 0x1f, 0x06, 0x13, 0x79, 0x21, 0x86, 0x1d, 0xa2, 0x38, 0x2c, 0xda, 0x35, 0x31, 0xbb, 0x04, 0x65, 0xa3, 0x01, 0xa6, - 0x63, 0xa4, 0x4a, 0xa2, 0xc1, 0xad, 0x04, 0xc1, 0xfa, 0x78, 0xe1, 0xb6, 0x50, 0x46, 0xab, 0xad, 0x1c, 0xcf, 0xf4, 0xe5, - 0xba, 0xa5, 0xe2, 0x91, 0x29, 0x4b, 0xa1, 0xc6, 0x4b, 0x30, 0xa5, 0x31, 0x02, 0xe9, 0xd0, 0x50, 0x72, 0x2c, 0x8e, 0xbd, - 0xb2, 0x12, 0xd9, 0x4f, 0x7c, 0x87, 0x4b, 0xa0, 0x45, 0x71, 0x0c, 0x23, 0x37, 0x6b, 0x60, 0xd7, 0x9f, 0x19, 0xe8, 0x0b, - 0x85, 0x57, 0x72, 0xb6, 0xbb, 0x20, 0x23, 0xd3, 0x7d, 0x9a, 0x9b, 0x9a, 0x05, 0x46, 0x5c, 0xf5, 0x02, 0xf1, 0x56, 0x00, - 0xc2, 0x05, 0x85, 0x48, 0xd3, 0x8d, 0x8e, 0xe1, 0xcb, 0xc5, 0x83, 0x1f, 0x78, 0xd0, 0xc5, 0xb1, 0xdf, 0x80, 0x9d, 0x04, - 0xe7, 0xac, 0xd1, 0x68, 0x1a, 0x19, 0x18, 0x16, 0xfa, 0x3a, 0xe2, 0xd2, 0x30, 0x08, 0x17, 0x4d, 0x50, 0x2b, 0xd4, 0xa3, - 0xbe, 0x98, 0x5f, 0xe0, 0xcf, 0xed, 0x7d, 0x74, 0x94, 0xd1, 0xb2, 0x77, 0xbc, 0x72, 0xbc, 0xf5, 0xc7, 0x82, 0x26, 0x53, - 0x14, 0xcc, 0xf9, 0xf7, 0x71, 0xea, 0x97, 0xaa, 0xbf, 0x21, 0x46, 0x59, 0x2c, 0x9a, 0xc4, 0xeb, 0xa3, 0x4a, 0x97, 0x91, - 0x11, 0xf1, 0x01, 0x19, 0x7e, 0xb1, 0xb2, 0x63, 0x0d, 0xf0, 0x5d, 0xaf, 0x53, 0xdf, 0x4d, 0xa1, 0x90, 0xe5, 0x12, 0x82, - 0x33, 0x6f, 0x1d, 0x73, 0xdf, 0xdb, 0x1f, 0x18, 0xa0, 0x72, 0xc1, 0xd6, 0xa7, 0x4d, 0xb2, 0x3e, 0x24, 0xb7, 0xa7, 0x76, - 0x15, 0x46, 0x22, 0x48, 0x49, 0x55, 0xd1, 0xfb, 0x66, 0x32, 0x02, 0xa9, 0xfc, 0xbe, 0x7e, 0x16, 0xcf, 0xac, 0x32, 0xbc, - 0xdb, 0xd5, 0xd8, 0xa3, 0x23, 0x6a, 0x10, 0xa6, 0x37, 0x03, 0xf6, 0x2a, 0xde, 0xba, 0xde, 0x2d, 0x7d, 0xef, 0x1d, 0xb9, - 0xf3, 0x93, 0xd4, 0xf2, 0x13, 0xf4, 0x9c, 0x5a, 0x32, 0xba, 0x5f, 0xef, 0x7b, 0xd0, 0x6b, 0xd7, 0x91, 0x6d, 0x7b, 0xe1, - 0x4d, 0xf2, 0x8c, 0xe7, 0xf1, 0x66, 0xb9, 0xad, 0xc6, 0x30, 0x08, 0x9e, 0x51, 0xd4, 0x39, 0x87, 0x09, 0xfa, 0x6b, 0x7a, - 0xa7, 0x5f, 0x1a, 0x9c, 0x98, 0xc5, 0x76, 0xb0, 0x71, 0x76, 0xf5, 0xfc, 0x56, 0x88, 0x1c, 0xca, 0xee, 0x76, 0xd4, 0x2c, - 0xa6, 0x64, 0x80, 0x59, 0x12, 0x8c, 0x08, 0xce, 0x83, 0xb3, 0xd9, 0x68, 0x59, 0xc1, 0x26, 0x86, 0xa7, 0x80, 0x10, 0xbc, - 0x41, 0x28, 0x6c, 0x45, 0xd4, 0x6d, 0x15, 0xd0, 0x76, 0x44, 0x0e, 0xcf, 0xc1, 0xde, 0xef, 0x7a, 0x97, 0x36, 0x8f, 0x0d, - 0x8a, 0xf5, 0x45, 0xde, 0xae, 0x61, 0xd0, 0x55, 0xe9, 0x8d, 0x62, 0xfd, 0xa3, 0x0d, 0x44, 0x0f, 0x49, 0xb6, 0x5a, 0xa4, - 0xaa, 0x03, 0x4e, 0x60, 0x35, 0x53, 0x86, 0x9e, 0xec, 0x75, 0xd9, 0x0a, 0xca, 0x14, 0xe3, 0x1b, 0x06, 0x05, 0xd6, 0x8f, - 0x4f, 0x11, 0xb3, 0x13, 0xdd, 0x26, 0x35, 0xbd, 0x56, 0x55, 0xf1, 0x43, 0x89, 0x5e, 0x5b, 0x25, 0x4d, 0xa8, 0x09, 0xdd, - 0xf2, 0x6d, 0x9e, 0x8c, 0xcd, 0xa2, 0xde, 0x84, 0x00, 0x6a, 0x0a, 0xc6, 0x92, 0x30, 0x82, 0xcf, 0xa4, 0x31, 0x67, 0xbd, - 0xd4, 0x36, 0x6a, 0x8b, 0xc6, 0x33, 0xdf, 0x8b, 0xde, 0x33, 0x01, 0x7b, 0x9d, 0xbf, 0xe9, 0x12, 0x35, 0x8a, 0x97, 0x07, - 0x72, 0x0b, 0x6b, 0x60, 0xe6, 0x1e, 0x7d, 0x78, 0x22, 0x9f, 0xbf, 0x66, 0x8e, 0x02, 0xf4, 0xdc, 0xa1, 0xb0, 0x42, 0x73, - 0x86, 0xca, 0x34, 0xf0, 0xa7, 0x2e, 0x15, 0x84, 0xa4, 0x60, 0xa8, 0x47, 0x05, 0x80, 0x03, 0x27, 0xa8, 0x04, 0x03, 0xfe, - 0x47, 0xd4, 0xeb, 0x33, 0x27, 0xbf, 0x89, 0xff, 0x4c, 0xd9, 0x27, 0x0e, 0xd0, 0xa9, 0x41, 0x8b, 0xd5, 0x7c, 0xc4, 0x14, - 0x7a, 0x9c, 0xb3, 0xaa, 0x13, 0x32, 0xa4, 0x67, 0xd5, 0x95, 0xdc, 0x4a, 0x3d, 0xf2, 0x54, 0xd7, 0x02, 0xf8, 0x06, 0x7b, - 0x1d, 0x9a, 0xa4, 0x53, 0xa0, 0x9c, 0x76, 0x7d, 0xf4, 0x01, 0xa3, 0x4b, 0xb2, 0x8b, 0x44, 0x85, 0xf6, 0x80, 0x99, 0x2f, - 0x77, 0x08, 0x20, 0xea, 0x08, 0xf8, 0x14, 0x76, 0xfe, 0xa0, 0x5a, 0xf9, 0x1f, 0x87, 0x03, 0xff, 0x8d, 0x1f, 0x5d, 0x02, - 0x64, 0x8a, 0xf4, 0xa5, 0x8c, 0xb7, 0x0a, 0x34, 0x68, 0xaa, 0xca, 0xc8, 0xe1, 0x78, 0x9b, 0xd3, 0x6c, 0x5c, 0x07, 0x99, - 0xc1, 0x10, 0x3f, 0x77, 0x0c, 0x45, 0xa2, 0xda, 0xda, 0xab, 0x7c, 0xf0, 0x90, 0x12, 0xa2, 0x7c, 0x84, 0x30, 0x82, 0x09, - 0xc9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x09, 0xba, 0x04, 0x82, 0x09, 0xb6, - 0x30, 0x82, 0x09, 0xb2, 0x30, 0x82, 0x09, 0xae, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, - 0x02, 0xa0, 0x82, 0x09, 0x76, 0x30, 0x82, 0x09, 0x72, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0xd3, 0x5d, 0xa8, 0x14, 0xbc, 0x7a, 0xaa, 0x5f, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x09, 0x50, 0xaf, 0xe9, 0x63, 0xb6, 0x05, 0x8b, 0x48, 0xe1, 0x11, 0xd0, 0x37, 0x1d, 0x48, 0x71, 0x22, 0x70, 0xdc, - 0xbd, 0xca, 0x98, 0x5d, 0x72, 0xca, 0x38, 0xdc, 0x2e, 0x4f, 0xd4, 0x71, 0xd3, 0xac, 0xf3, 0x0c, 0xcf, 0x78, 0x4e, 0x5c, - 0x63, 0x35, 0xaa, 0xac, 0x5a, 0xf0, 0xef, 0x6c, 0xc0, 0x89, 0x28, 0xc4, 0x64, 0xec, 0x5c, 0x92, 0x72, 0xbc, 0xe5, 0x30, - 0xe9, 0x5c, 0x35, 0xff, 0xe0, 0xb1, 0x1f, 0xc6, 0x37, 0x50, 0xb7, 0x3d, 0x94, 0x28, 0xbd, 0x3b, 0xf0, 0xd9, 0x5c, 0xb1, - 0x45, 0x93, 0xde, 0x41, 0x5b, 0x12, 0xba, 0xfa, 0x27, 0x49, 0x6b, 0xb7, 0x9a, 0xa6, 0x46, 0x8e, 0xe3, 0x15, 0x1b, 0x7f, - 0x2c, 0x91, 0x2e, 0x33, 0xf3, 0xef, 0x7a, 0x9b, 0x9d, 0xa8, 0x82, 0x95, 0xa0, 0x7e, 0x43, 0xd6, 0x9d, 0xe2, 0xfb, 0xb1, - 0xb0, 0xcf, 0xbd, 0xb6, 0x9b, 0x55, 0x4c, 0xc8, 0x4a, 0xc7, 0x82, 0xeb, 0x3d, 0x09, 0x8d, 0x85, 0x6f, 0x8c, 0x42, 0x6d, - 0x10, 0x7d, 0x77, 0x57, 0x29, 0x00, 0xe2, 0xd8, 0x2f, 0xed, 0x7c, 0x10, 0x5b, 0x03, 0xfa, 0x60, 0x34, 0xc9, 0x63, 0x25, - 0x4d, 0x02, 0x77, 0x8f, 0x7f, 0x4b, 0x53, 0xe4, 0x8d, 0x1e, 0x4e, 0x2c, 0x0c, 0x7f, 0x0e, 0x48, 0x4b, 0xcd, 0xc8, 0x6a, - 0xfa, 0xd3, 0x9f, 0x6f, 0x20, 0x4e, 0x2c, 0x77, 0x2a, 0x84, 0x5e, 0x6c, 0xc3, 0x57, 0xba, 0x97, 0xa7, 0xa8, 0xcb, 0x6f, - 0x22, 0xc1, 0xa7, 0x61, 0xf7, 0x7e, 0x7a, 0xae, 0xda, 0xbd, 0x3a, 0xea, 0xb3, 0x46, 0x54, 0x8d, 0x46, 0x48, 0x1f, 0xf3, - 0x5c, 0xaa, 0x2e, 0x44, 0xe1, 0x83, 0x69, 0x45, 0x30, 0x02, 0x49, 0x63, 0xa6, 0xdd, 0xf0, 0x25, 0xce, 0x81, 0xab, 0x66, - 0x20, 0x04, 0x12, 0x2f, 0x94, 0x2f, 0x8f, 0xf9, 0x88, 0xea, 0x5b, 0xba, 0x87, 0xd7, 0xbe, 0x63, 0x2e, 0xb4, 0xa4, 0x15, - 0xe8, 0x56, 0x9e, 0xb5, 0x7b, 0x27, 0xf8, 0x06, 0xfd, 0xf5, 0x21, 0x93, 0x2b, 0x64, 0xb0, 0xe2, 0x31, 0xb3, 0x19, 0xe0, - 0x6b, 0x10, 0x8c, 0xa5, 0xa5, 0x38, 0x27, 0x78, 0xc9, 0x9c, 0x01, 0xa7, 0x42, 0x22, 0x3d, 0xf8, 0x8c, 0x23, 0x46, 0xc5, - 0x4e, 0x47, 0xa5, 0x9e, 0xd7, 0xa5, 0x50, 0x24, 0x02, 0x30, 0xe9, 0x15, 0x3e, 0x17, 0xba, 0x2c, 0xf2, 0x5e, 0xc7, 0x01, - 0x25, 0x9a, 0x74, 0x73, 0x5c, 0x5e, 0xca, 0x01, 0xe2, 0x58, 0x96, 0x47, 0x3e, 0x4c, 0xb9, 0x0f, 0x95, 0xbf, 0xf3, 0xc4, - 0x24, 0x98, 0x6c, 0xc5, 0x40, 0xd2, 0xf3, 0x88, 0x62, 0xb0, 0x25, 0x54, 0xb5, 0xf6, 0x2b, 0xfd, 0xf5, 0x6a, 0x6d, 0x15, - 0xb2, 0x18, 0x7d, 0xef, 0x3e, 0x66, 0x7d, 0x38, 0x4c, 0xda, 0xc9, 0x1a, 0xcd, 0x40, 0x2a, 0xc6, 0x7b, 0x2e, 0x8a, 0x15, - 0xa7, 0xae, 0x99, 0xf5, 0x93, 0x39, 0x20, 0xd2, 0xd8, 0xfd, 0x1f, 0x87, 0x2e, 0xa0, 0xcd, 0x95, 0xa2, 0xd7, 0xd0, 0x48, - 0xf7, 0x6e, 0x81, 0x91, 0x1c, 0x37, 0x8a, 0x28, 0x6f, 0x22, 0x7b, 0x37, 0x69, 0x30, 0x3a, 0x64, 0x6e, 0x4a, 0x5f, 0x0a, - 0xa6, 0xd7, 0x53, 0xce, 0x1d, 0x60, 0x88, 0xa5, 0x0b, 0xde, 0xf5, 0x01, 0x3a, 0x20, 0xfa, 0xd6, 0x08, 0xdf, 0x83, 0x39, - 0x2e, 0xb8, 0x3a, 0x91, 0xec, 0x39, 0x47, 0xaa, 0x66, 0x8a, 0xb4, 0x35, 0x70, 0xaf, 0x88, 0x24, 0xb2, 0xc3, 0xdc, 0x7c, - 0xd0, 0x8f, 0x93, 0x0d, 0xa4, 0x53, 0xf1, 0x55, 0x92, 0xae, 0xd9, 0xeb, 0x31, 0xa0, 0x68, 0x29, 0xf5, 0xdb, 0x2f, 0xd1, - 0xa3, 0xfe, 0x34, 0x2f, 0xcd, 0x64, 0x0c, 0x11, 0x13, 0x14, 0x50, 0xeb, 0x27, 0x56, 0xda, 0xc0, 0x30, 0x3a, 0x8c, 0x92, - 0xb3, 0xb8, 0xc8, 0xb7, 0x19, 0xea, 0x4c, 0x74, 0xb9, 0x95, 0x46, 0x9f, 0xc0, 0x63, 0xfd, 0x72, 0x35, 0x0b, 0xb9, 0x1d, - 0x1e, 0x85, 0xf8, 0xf9, 0x23, 0xf7, 0x42, 0xe2, 0xf4, 0x67, 0xbf, 0x3d, 0x30, 0x4b, 0x6a, 0xf2, 0x44, 0x2f, 0xcb, 0x6f, - 0xe9, 0x73, 0x4b, 0x8f, 0x09, 0x29, 0x69, 0xcd, 0x8d, 0xcd, 0xc7, 0xd4, 0xa2, 0x0c, 0x6a, 0xc4, 0x9a, 0x33, 0xe2, 0x64, - 0x5f, 0x07, 0xf2, 0xb6, 0xf8, 0x86, 0x7f, 0x05, 0x04, 0xf1, 0x1d, 0x9d, 0xd1, 0xc8, 0x3c, 0x16, 0x6e, 0x18, 0x96, 0x15, - 0x33, 0xda, 0x84, 0xb6, 0xfd, 0x13, 0x29, 0x2f, 0x5e, 0xa0, 0x0e, 0xaa, 0xf6, 0x24, 0xb4, 0xa5, 0x48, 0x01, 0x02, 0x07, - 0x31, 0x98, 0x0d, 0x9c, 0x65, 0x59, 0x68, 0x61, 0x22, 0xdb, 0x64, 0x16, 0x05, 0xae, 0xd8, 0x64, 0x5f, 0xba, 0x51, 0xab, - 0x5e, 0xe0, 0xbe, 0x3d, 0x29, 0x67, 0x20, 0x94, 0x63, 0xfe, 0xc7, 0x90, 0x30, 0xc9, 0x43, 0xf1, 0xce, 0x9c, 0x53, 0x01, - 0x2c, 0x64, 0x56, 0x85, 0xb7, 0x3b, 0xa4, 0x05, 0x5d, 0x88, 0xdf, 0x44, 0xda, 0x18, 0xf3, 0x8c, 0xdb, 0xae, 0xd2, 0x9f, - 0xee, 0x4e, 0x08, 0x17, 0xf9, 0xd8, 0xe0, 0xc9, 0x7d, 0xa5, 0xad, 0x79, 0x06, 0x1b, 0x8c, 0x92, 0xe7, 0x53, 0xdf, 0xde, - 0xa3, 0xa5, 0x84, 0x1d, 0xd8, 0x75, 0x35, 0x78, 0x32, 0x55, 0x6f, 0x4f, 0x29, 0x34, 0x4e, 0x6f, 0x32, 0x16, 0xe4, 0xfd, - 0xbc, 0xf5, 0x76, 0x99, 0xf3, 0x48, 0x5b, 0xa0, 0x65, 0xb2, 0xef, 0xeb, 0x58, 0x6c, 0xf4, 0x1e, 0x97, 0x34, 0xee, 0xf9, - 0x74, 0xe2, 0x94, 0xc0, 0xf2, 0xf5, 0x0b, 0x97, 0x40, 0xce, 0x25, 0xd6, 0xe5, 0xdf, 0x0b, 0x3b, 0x6b, 0xf3, 0x38, 0x28, - 0xc3, 0xa6, 0x30, 0xa5, 0x22, 0x3c, 0xb0, 0xbd, 0x4d, 0xd5, 0x79, 0x25, 0xb9, 0xb2, 0xb4, 0xc4, 0x31, 0x62, 0x0b, 0xe7, - 0x73, 0x4e, 0xf9, 0xa7, 0x57, 0xdf, 0x33, 0x0e, 0xf0, 0xb9, 0x3b, 0x6d, 0xff, 0x6b, 0x11, 0xb0, 0x90, 0x10, 0x2a, 0x7b, - 0xb5, 0x0b, 0x41, 0x17, 0x0b, 0x12, 0xc7, 0x61, 0xef, 0xb1, 0x9b, 0x57, 0x3a, 0x01, 0x55, 0x91, 0xe3, 0xd5, 0xc8, 0xd5, - 0xeb, 0x26, 0x90, 0x2b, 0x67, 0x5b, 0xc2, 0x0b, 0xad, 0x6f, 0x26, 0x3a, 0xf5, 0x45, 0xb2, 0xd7, 0x6a, 0x78, 0xaa, 0x43, - 0xd0, 0xdb, 0x53, 0x6f, 0x1a, 0x7a, 0x5c, 0x92, 0xe1, 0xb7, 0xe5, 0xad, 0xda, 0xac, 0x3b, 0x5a, 0x20, 0x06, 0xe1, 0x56, - 0xf0, 0x55, 0x66, 0x64, 0x42, 0xd4, 0xe4, 0x77, 0x3b, 0xa5, 0x60, 0x8d, 0x5b, 0x24, 0x7a, 0x2a, 0xb9, 0xe2, 0x2f, 0xc6, - 0x02, 0xd1, 0x21, 0xf3, 0x08, 0xbd, 0x7b, 0xf4, 0x44, 0x47, 0x00, 0xd2, 0xca, 0x3c, 0x80, 0x37, 0xb0, 0xf2, 0x3d, 0x07, - 0x87, 0xbd, 0xe8, 0x59, 0x01, 0x17, 0x7b, 0xb3, 0x1b, 0xc3, 0xce, 0x45, 0x77, 0x3c, 0x0e, 0xdd, 0xac, 0x38, 0xf1, 0x5e, - 0xde, 0x5e, 0xdd, 0xad, 0xf2, 0xc9, 0x0f, 0xed, 0xec, 0xe5, 0x00, 0x8b, 0x61, 0xf4, 0x62, 0xd5, 0x58, 0x37, 0xec, 0xbf, - 0x36, 0xcf, 0x7a, 0x6a, 0x55, 0x1f, 0x25, 0x53, 0xba, 0xcd, 0x76, 0xc3, 0x07, 0x5e, 0x12, 0xf0, 0xc3, 0x82, 0x52, 0x5f, - 0xc6, 0x24, 0x54, 0x76, 0x49, 0xa3, 0xf1, 0xdd, 0x67, 0x29, 0x81, 0x19, 0x5f, 0x7b, 0xcd, 0xc6, 0x60, 0x3e, 0x80, 0x02, - 0xb3, 0xd9, 0xb6, 0x9d, 0x29, 0x59, 0xdc, 0x79, 0x90, 0xab, 0x53, 0xf4, 0xe6, 0x23, 0xb4, 0x77, 0x0f, 0xc8, 0xf2, 0x88, - 0xb3, 0x1c, 0x70, 0xb4, 0xeb, 0xa8, 0xdf, 0x25, 0x5b, 0x94, 0xa6, 0xce, 0x80, 0xbd, 0x46, 0xe6, 0x26, 0x8c, 0x4f, 0xee, - 0x37, 0x81, 0x84, 0xc6, 0xff, 0x0a, 0x37, 0x2e, 0xa4, 0xcb, 0xdf, 0x62, 0x81, 0x79, 0x3b, 0xa2, 0xdb, 0x07, 0x14, 0x0c, - 0xf7, 0x44, 0x1e, 0xda, 0xe0, 0x6c, 0x1a, 0xb6, 0x52, 0x7f, 0xd8, 0xce, 0xe7, 0x29, 0x98, 0xc1, 0x69, 0x40, 0xb9, 0x2a, - 0xe7, 0xb4, 0xee, 0x04, 0x67, 0xf7, 0x54, 0xac, 0x94, 0x12, 0x5c, 0x67, 0xb4, 0x51, 0x9c, 0xf6, 0xfa, 0x9b, 0x10, 0xd3, - 0x7e, 0xce, 0x78, 0xd5, 0x88, 0x80, 0xd7, 0x88, 0xea, 0x16, 0x51, 0x0c, 0xc9, 0xf2, 0x55, 0xda, 0xbd, 0x22, 0x34, 0x1a, - 0x65, 0x8f, 0xd7, 0x52, 0x00, 0x98, 0xc3, 0x76, 0xff, 0x3e, 0xfc, 0x44, 0x4b, 0x7e, 0xc2, 0x40, 0x00, 0x94, 0xf3, 0xc6, - 0xd5, 0xa3, 0x0f, 0x95, 0x9a, 0x96, 0xbb, 0x50, 0xcd, 0xd0, 0x6f, 0x75, 0xd7, 0xcc, 0x89, 0xb4, 0xc2, 0x85, 0x7f, 0x5f, - 0x06, 0xc1, 0xdf, 0x3c, 0xdd, 0x32, 0xdb, 0x44, 0xae, 0x1e, 0xd8, 0x56, 0xde, 0x93, 0xb0, 0xbd, 0xed, 0x8c, 0xb6, 0xcc, - 0x15, 0xe7, 0x81, 0x98, 0x36, 0x36, 0xd6, 0x91, 0x61, 0xd8, 0x65, 0x57, 0x5d, 0xcd, 0xbf, 0xf1, 0x3b, 0x31, 0xb6, 0xdd, - 0x6e, 0xc6, 0xd3, 0x1b, 0xc9, 0x47, 0x8c, 0x09, 0x03, 0x81, 0x7d, 0xbd, 0x64, 0xa9, 0x09, 0x66, 0x81, 0x2d, 0x56, 0x43, - 0xe8, 0x3c, 0x3e, 0xaa, 0xf8, 0x28, 0x92, 0x13, 0xea, 0x1f, 0xc1, 0x81, 0x4f, 0xb1, 0x1e, 0x88, 0xd2, 0x47, 0xdb, 0xb4, - 0x7e, 0xcb, 0xac, 0xc4, 0xbc, 0x07, 0x68, 0x83, 0x7d, 0xd2, 0x90, 0x90, 0x01, 0xa7, 0x0b, 0xac, 0x60, 0x67, 0x0f, 0xf4, - 0x1b, 0x2c, 0x1e, 0x93, 0x93, 0x6a, 0x16, 0x63, 0x78, 0x36, 0x7d, 0xc5, 0xa5, 0x04, 0xf4, 0x96, 0x1d, 0xae, 0x1a, 0xdf, - 0x1d, 0xba, 0xfc, 0x00, 0x21, 0x07, 0x8c, 0xa7, 0x9d, 0x00, 0x60, 0xb7, 0xa4, 0x05, 0xdd, 0xcd, 0x05, 0xee, 0x70, 0x5e, - 0xc5, 0x79, 0x6c, 0xc1, 0x22, 0x57, 0xfb, 0x5a, 0x25, 0x3e, 0xb9, 0x37, 0x76, 0x61, 0xc2, 0x7d, 0x14, 0x3c, 0xd3, 0x3a, - 0x13, 0xb9, 0x33, 0x07, 0xf6, 0x53, 0xc9, 0x5b, 0xb9, 0x97, 0x03, 0xd0, 0x76, 0xb8, 0xd1, 0xf1, 0x43, 0x9d, 0x7f, 0x37, - 0x46, 0x1a, 0xda, 0xdf, 0xd7, 0x4a, 0xb7, 0x79, 0x84, 0x9e, 0x47, 0x73, 0xac, 0x26, 0xf7, 0xd7, 0x54, 0x16, 0xad, 0x49, - 0x5e, 0x5d, 0x77, 0x61, 0x79, 0xdd, 0x52, 0x13, 0x2f, 0x20, 0xce, 0x26, 0x35, 0xa3, 0x60, 0x28, 0x3f, 0xc5, 0x67, 0xce, - 0x43, 0xa0, 0x86, 0x28, 0xf7, 0xa6, 0xf9, 0x6a, 0xbf, 0x25, 0x41, 0xb7, 0x7d, 0xbc, 0x04, 0x02, 0xd1, 0xe5, 0xed, 0x74, - 0xf5, 0xf5, 0x39, 0xf5, 0x18, 0x42, 0x9f, 0xdc, 0xaf, 0x46, 0xb6, 0x55, 0x48, 0x72, 0xa6, 0x66, 0x94, 0xef, 0x4a, 0x45, - 0x92, 0xf8, 0x31, 0x7a, 0x19, 0x69, 0xcb, 0xcf, 0xf3, 0x10, 0x4a, 0x65, 0x53, 0x18, 0xf4, 0x7f, 0x47, 0xe8, 0xe5, 0x07, - 0xb1, 0x8b, 0x3c, 0x3b, 0xb1, 0x1f, 0xdb, 0xb8, 0x5d, 0x53, 0xcb, 0xad, 0xf7, 0x38, 0x91, 0x8a, 0x1e, 0xa6, 0x76, 0x05, - 0x48, 0x89, 0xcc, 0xff, 0x51, 0x59, 0x53, 0xe9, 0xd7, 0x6e, 0x1a, 0x6e, 0xad, 0xf2, 0xcb, 0xf5, 0xfd, 0x48, 0xbe, 0xa8, - 0x70, 0xae, 0x5e, 0xc1, 0x7e, 0x1e, 0x07, 0x8e, 0x64, 0x0d, 0x70, 0xb7, 0x92, 0xda, 0x6f, 0x45, 0xb0, 0xe3, 0x8a, 0x30, - 0xbc, 0x45, 0xd1, 0x65, 0xf2, 0xb7, 0xab, 0x4e, 0x16, 0x5c, 0xa2, 0xb2, 0x9a, 0x4d, 0x2f, 0x76, 0x26, 0x62, 0x92, 0x7a, - 0x3c, 0x47, 0xf6, 0x87, 0x04, 0x0f, 0x7b, 0xda, 0x4b, 0x02, 0x6b, 0xd6, 0x16, 0x79, 0xbd, 0x16, 0x24, 0x42, 0x7a, 0xf4, - 0x44, 0x58, 0xb4, 0x68, 0x71, 0xce, 0xb3, 0x28, 0xba, 0x84, 0x6c, 0x26, 0x82, 0x1e, 0xba, 0x19, 0x83, 0xb7, 0x75, 0x1b, - 0xde, 0x09, 0xf6, 0x1b, 0x4f, 0x31, 0x65, 0xae, 0xb6, 0x45, 0xc2, 0xa7, 0x35, 0x2d, 0x9f, 0x14, 0x10, 0xe0, 0x3e, 0x43, - 0xa7, 0x82, 0x01, 0x06, 0x95, 0x2c, 0x19, 0x43, 0x8c, 0x94, 0xd4, 0x8c, 0x85, 0x6d, 0x88, 0x33, 0xff, 0x19, 0x51, 0xd3, - 0x7c, 0xf2, 0xa7, 0x5b, 0x05, 0xd1, 0x2b, 0x56, 0x18, 0x5e, 0xa6, 0xb9, 0x66, 0x3c, 0xf7, 0x4d, 0xbd, 0xa9, 0x95, 0x75, - 0xa9, 0xa1, 0x87, 0x24, 0x87, 0xf0, 0x60, 0xbb, 0x39, 0xec, 0xd1, 0xe5, 0x67, 0x51, 0x76, 0x99, 0xbc, 0x64, 0x7b, 0x5a, - 0xd5, 0xa6, 0x54, 0x4f, 0x16, 0x10, 0xb2, 0xe9, 0x43, 0x1c, 0x3a, 0x4c, 0x88, 0x51, 0xf4, 0xc2, 0x95, 0x16, 0x8e, 0xbf, - 0x79, 0x19, 0x22, 0x95, 0xd1, 0x76, 0x99, 0xb8, 0x68, 0xf3, 0x6a, 0x1a, 0x4e, 0x43, 0xf8, 0x9c, 0x6b, 0x75, 0x8c, 0xa5, - 0xbd, 0x65, 0x3a, 0x83, 0x0b, 0x47, 0xcf, 0x08, 0xf7, 0x22, 0x86, 0xad, 0xd5, 0x89, 0xd0, 0x6f, 0x4e, 0xbe, 0x2a, 0x81, - 0x1d, 0x1c, 0xf1, 0xc8, 0xf3, 0x18, 0x44, 0x40, 0xf3, 0x99, 0xfd, 0x18, 0xe3, 0x1a, 0xc9, 0x7f, 0x3b, 0x93, 0x68, 0x84, - 0xe2, 0x49, 0xb9, 0xcf, 0x00, 0x5c, 0x76, 0xc4, 0xcc, 0x4b, 0x7e, 0x86, 0x7e, 0x3f, 0x4b, 0x23, 0x61, 0x92, 0x7c, 0xcb, - 0x0c, 0x0c, 0x3e, 0x97, 0x34, 0xcc, 0xfd, 0x34, 0xa9, 0xcc, 0xf0, 0x83, 0xb1, 0xbc, 0x50, 0x4c, 0x84, 0x6f, 0xba, 0x68, - 0x01, 0x4f, 0x71, 0x57, 0x05, 0x7f, 0x01, 0xe2, 0x18, 0x23, 0xe9, 0x44, 0xa8, 0x4d, 0x93, 0x11, 0xee, 0xc0, 0x79, 0x5a, - 0x94, 0x13, 0x81, 0xf4, 0x67, 0xa0, 0x50, 0x79, 0x83, 0xa1, 0x13, 0x5f, 0x0e, 0x82, 0x9a, 0x72, 0x90, 0xba, 0x43, 0x21, - 0x28, 0xa9, 0x65, 0x1c, 0x16, 0x97, 0x6f, 0xdb, 0xc3, 0x1e, 0x23, 0xc5, 0x4a, 0xdb, 0x3b, 0x3c, 0x42, 0x4a, 0xc4, 0xb5, - 0x7f, 0x6b, 0x5d, 0xfc, 0x09, 0x08, 0x43, 0x2f, 0xf8, 0x11, 0x27, 0x6f, 0x1d, 0xc0, 0x12, 0x59, 0x04, 0xa4, 0x5b, 0xe9, - 0x9f, 0x25, 0xd1, 0x58, 0x3a, 0x1f, 0xac, 0x05, 0x15, 0x18, 0xea, 0xbd, 0x4b, 0xd2, 0xba, 0x67, 0xf3, 0x1d, 0x89, 0x09, - 0x52, 0xe5, 0x0e, 0x15, 0xd6, 0x5b, 0x87, 0xf5, 0xc3, 0x3c, 0x98, 0xbc, 0x46, 0x4e, 0x19, 0x8d, 0xbb, 0x3e, 0xe0, 0xde, - 0x19, 0x59, 0x53, 0x32, 0x62, 0x31, 0x16, 0xd4, 0xea, 0x63, 0xda, 0xf4, 0xcc, 0x94, 0xd0, 0x18, 0x98, 0xbc, 0x00, 0xd3, - 0x6c, 0xe2, 0xa5, 0xac, 0x30, 0x08, 0x9d, 0x68, 0x82, 0x8e, 0xbb, 0xdf, 0x9a, 0xa1, 0x13, 0xa5, 0x98, 0x18, 0xa9, 0x11, - 0xde, 0x49, 0x18, 0x88, 0xab, 0xff, 0xc6, 0x2c, 0xa8, 0xe1, 0xf7, 0x49, 0xba, 0x17, 0x93, 0x1c, 0x6c, 0x7f, 0x2c, 0xa9, - 0x3a, 0xee, 0x77, 0x9d, 0x46, 0x0c, 0xf9, 0x1c, 0x24, 0x33, 0x6f, 0x9b, 0xf8, 0x47, 0x9d, 0xc9, 0x7f, 0x9c, 0x80, 0xa0, - 0x2c, 0x96, 0x63, 0xe1, 0x97, 0x75, 0x75, 0x1f, 0xb3, 0xc6, 0x0d, 0xa9, 0x49, 0x82, 0x66, 0x86, 0x13, 0xa4, 0x62, 0x4c, - 0x56, 0x89, 0x73, 0x03, 0x1b, 0x61, 0xff, 0xfa, 0x0f, 0xf4, 0x84, 0xe3, 0xad, 0x89, 0xc0, 0x8e, 0x03, 0x91, 0x1c, 0x99, - 0x9f, 0x99, 0x92, 0x7e, 0xb5, 0xd8, 0xe3, 0xee, 0x6c, 0x21, 0x27, 0x5d, 0xa2, 0xa5, 0x90, 0xf2, 0x67, 0xed, 0xf3, 0xca, - 0x51, 0x56, 0x28, 0x7d, 0xa9, 0xd0, 0x4a, 0x4b, 0x76, 0x2b, 0xa8, 0x95, 0x8a, 0x37, 0xb4, 0x72, 0x96, 0xb2, 0xa0, 0xbe, - 0x90, 0x4f, 0x4e, 0x37, 0xbb, 0x14, 0xf8, 0xd2, 0x76, 0x7c, 0x79, 0xf3, 0xd2, 0xbf, 0x35, 0xad, 0x64, 0xbc, 0x98, 0x73, - 0xe5, 0xb9, 0xb3, 0xa2, 0x9b, 0x54, 0x17, 0x9b, 0x99, 0xa1, 0xeb, 0xfd, 0xc2, 0x8b, 0xbd, 0xac, 0x6d, 0x14, 0x35, 0xc2, - 0x3b, 0xc9, 0x88, 0x57, 0x64, 0xaa, 0x52, 0x3d, 0xf1, 0x80, 0x9c, 0xb2, 0xfc, 0xe9, 0x53, 0x7c, 0x12, 0x81, 0xe6, 0x07, - 0xa1, 0x0b, 0x2b, 0xb3, 0x88, 0xa6, 0x07, 0xb8, 0x10, 0x7e, 0xc4, 0x55, 0x14, 0xa2, 0x66, 0xf1, 0xcc, 0xff, 0x49, 0x84, - 0xbc, 0x54, 0x15, 0x41, 0x26, 0x15, 0x44, 0xf1, 0xe4, 0x4e, 0x8a, 0xf4, 0x02, 0xb1, 0x87, 0x51, 0xa7, 0xa4, 0xe6, 0x4f, - 0xbb, 0xff, 0xfe, 0x94, 0x51, 0x54, 0x20, 0x7e, 0x16, 0x60, 0x23, 0xfe, 0x05, 0x8c, 0x1a, 0xe1, 0x12, 0x7c, 0xd4, 0xc0, - 0xae, 0x3a, 0x96, 0x13, 0x5d, 0x83, 0x89, 0x49, 0x99, 0x2c, 0x3e, 0x19, 0x8b, 0xa8, 0xf0, 0x0d, 0x65, 0x5d, 0x35, 0x37, - 0xa1, 0x2d, 0xdd, 0xe2, 0x6b, 0x0d, 0xa9, 0x47, 0x9e, 0xf0, 0x22, 0xb5, 0x8e, 0xab, 0xc1, 0x34, 0x93, 0x4c, 0xff, 0x89, - 0x9b, 0x24, 0xd4, 0x01, 0x24, 0xbc, 0xf5, 0x42, 0xd8, 0xee, 0xc2, 0xbc, 0x78, 0x03, 0xc1, 0x24, 0xa8, 0x88, 0xba, 0x3f, - 0x71, 0x58, 0x3d, 0xdd, 0xef, 0xa8, 0xf8, 0x15, 0x4c, 0xb0, 0x68, 0x7c, 0xbc, 0x41, 0x66, 0x72, 0xc4, 0x4d, 0x9f, 0xd0, - 0xdb, 0x9a, 0xd0, 0x65, 0xde, 0xf1, 0x25, 0x02, 0x35, 0xff, 0x49, 0x4a, 0xd8, 0xa4, 0x19, 0x49, 0xb4, 0x51, 0xda, 0x4b, - 0x75, 0x81, 0x17, 0xa7, 0x84, 0x80, 0x70, 0x3f, 0xc7, 0x0d, 0xb2, 0x79, 0x24, 0x25, 0x7c, 0xe2, 0x30, 0x67, 0x15, 0x00, - 0x80, 0x68, 0x1e, 0xde, 0xf0, 0x3e, 0xda, 0xc6, 0x31, 0x4d, 0xa7, 0xf0, 0x53, 0x0d, 0x88, 0x08, 0xe1, 0xd8, 0xe2, 0x8b, - 0x01, 0xdb, 0x9f, 0x5b, 0x7c, 0xd4, 0x68, 0x89, 0xb1, 0xeb, 0xdb, 0x4e, 0x6f, 0xac, 0x21, 0xad, 0xf2, 0xed, 0x6f, 0x61, - 0x4d, 0x1f, 0x2f, 0x64, 0x0b, 0xdb, 0x07, 0x54, 0x65, 0xd7, 0xf0, 0xf8, 0x40, 0xdb, 0xd9, 0x5e, 0x2d, 0xaf, 0x4f, 0x14, - 0x9f, 0x5b, 0x0b, 0x74, 0x4e, 0xad, 0x07, 0x60, 0xac, 0x24, 0x04, 0x5b, 0xc8, 0xf4, 0xc9, 0x6f, 0x28, 0xb0, 0x2b, 0xb3, - 0xd9, 0x43, 0xf1, 0x55, 0xc9, 0x25, 0x01, 0xb7, 0xab, 0x8f, 0xd8, 0x0f, 0x78, 0x6a, 0xbf, 0xa0, 0x4e, 0x80, 0x22, 0xc6, - 0x8a, 0x42, 0x37, 0x6d, 0x3a, 0xbd, 0xf3, 0x66, 0xbe, 0x84, 0x87, 0xf6, 0xa1, 0xa0, 0x99, 0x7f, 0x13, 0x66, 0x40, 0x39, - 0xce, 0x43, 0x8f, 0xe5, 0x83, 0x48, 0x94, 0xc6, 0x59, 0xc2, 0xce, 0x55, 0x35, 0x44, 0x74, 0xa6, 0x37, 0x0c, 0x3c, 0x69, - 0xdc, 0xdb, 0x2b, 0x3a, 0xd8, 0x32, 0x4d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x01, 0xae, 0x1a, 0x61, 0x75, 0xae, 0x23, 0xd9, 0x11, 0x5c, 0x28, 0x93, 0xa9, 0xe2, - 0x49, 0x5e, 0x74, 0x28, 0x4c, 0x08, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, - 0x00, 0x04, 0x14, 0x3d, 0xc6, 0xb0, 0x07, 0xf5, 0xd4, 0xa7, 0x42, 0x90, 0xa1, 0x2f, 0x4d, 0x1e, 0x43, 0x09, 0x7d, 0xd5, - 0xfe, 0x15, 0xb1, 0x04, 0x08, 0xdd, 0xee, 0x2c, 0x8a, 0x3d, 0x65, 0x41, 0x94, 0x02, 0x02, 0x08, 0x00 -}; - -/* Random data for content */ -uint8_t content[1024] = { - 0x2a, 0xb1, 0x8c, 0xf1, 0x66, 0x52, 0xd5, 0x3c, 0xdd, 0x53, 0xc0, 0x07, 0x6a, 0x13, 0xda, 0x25, 0x9c, 0x04, 0x64, 0x5c, - 0x97, 0xb8, 0xb3, 0xb5, 0xcf, 0xf8, 0xe1, 0x8f, 0xdd, 0x49, 0x64, 0x55, 0x97, 0xad, 0xbc, 0xad, 0xff, 0xd1, 0xd9, 0xdf, - 0x0f, 0x26, 0x96, 0x27, 0x78, 0x1b, 0x13, 0xf6, 0x2e, 0x75, 0xb2, 0x6a, 0xf1, 0x04, 0x71, 0xa3, 0x51, 0x8d, 0x9c, 0xe8, - 0xab, 0xee, 0xf4, 0xf4, 0xfa, 0x75, 0x16, 0xbe, 0x08, 0xaf, 0xdf, 0x23, 0xc2, 0x17, 0x75, 0x80, 0xad, 0x0e, 0x68, 0xc1, - 0x37, 0xd9, 0x49, 0x0b, 0xea, 0x8a, 0x29, 0x3a, 0x2d, 0xff, 0x45, 0xe9, 0x13, 0x93, 0xac, 0x2e, 0x25, 0x3d, 0x5f, 0xd1, - 0x36, 0x66, 0x61, 0x14, 0xa9, 0xf1, 0xae, 0x83, 0x3a, 0x96, 0xe3, 0xcd, 0xe1, 0xdd, 0xb8, 0x8b, 0x85, 0xe7, 0xd9, 0x1b, - 0x76, 0xf9, 0x55, 0xf7, 0xd8, 0xb6, 0xca, 0x5b, 0x0f, 0xb8, 0x40, 0x1b, 0x69, 0x54, 0x07, 0xde, 0xd5, 0x26, 0x85, 0x9b, - 0xd1, 0x4a, 0xce, 0x2b, 0xe1, 0xd8, 0xe7, 0x6a, 0x06, 0x28, 0x4b, 0x05, 0xa9, 0x0b, 0x65, 0x07, 0x3d, 0xf5, 0xca, 0x31, - 0xd0, 0xfb, 0x5b, 0xf8, 0x1e, 0x19, 0x5f, 0x69, 0x64, 0x1b, 0xe1, 0x6d, 0x15, 0x88, 0x9c, 0xd1, 0x25, 0x4d, 0xf2, 0xa5, - 0x74, 0x82, 0xa4, 0xd3, 0x21, 0xc2, 0x4f, 0x78, 0xcf, 0x37, 0xdd, 0x3c, 0xe5, 0x69, 0x27, 0x82, 0xf1, 0xc8, 0xe9, 0x2f, - 0x7a, 0x7d, 0xd4, 0x65, 0x78, 0xad, 0x4c, 0xfc, 0xa5, 0x29, 0x51, 0xe2, 0x67, 0xac, 0x29, 0xa4, 0x23, 0x46, 0xe0, 0x10, - 0x55, 0x2a, 0x7e, 0xef, 0x04, 0xd4, 0x9f, 0xe3, 0x65, 0x09, 0x2d, 0x33, 0x07, 0xa5, 0x6c, 0x3d, 0x6e, 0xf5, 0x3e, 0xda, - 0x92, 0xb3, 0x47, 0x89, 0xa8, 0xda, 0x04, 0xe0, 0xa6, 0xcd, 0xd5, 0x84, 0xd6, 0xd5, 0x6f, 0xa5, 0x30, 0x3f, 0xcc, 0x9e, - 0xfe, 0xd5, 0xd6, 0xb8, 0x61, 0xf6, 0xb0, 0x10, 0x9d, 0x4d, 0x5c, 0x90, 0xc8, 0x05, 0x4d, 0xba, 0x99, 0x8e, 0xa7, 0xc8, - 0x53, 0xe7, 0x5d, 0xd7, 0x37, 0xf3, 0x0b, 0xc9, 0x0f, 0x97, 0x2d, 0x3e, 0x22, 0xed, 0xdc, 0x28, 0x22, 0x32, 0x04, 0xc0, - 0x6a, 0x38, 0xd8, 0xc8, 0x85, 0xef, 0x57, 0x9c, 0xa1, 0xe0, 0x0b, 0x7e, 0x6a, 0xb4, 0x5a, 0x76, 0x7c, 0xaf, 0x6f, 0x5d, - 0xcc, 0x56, 0xef, 0x60, 0x3c, 0xce, 0x0f, 0x0a, 0x5e, 0xfa, 0xbb, 0xb6, 0xd8, 0xba, 0xda, 0x9d, 0xf5, 0x86, 0x55, 0xc2, - 0x84, 0x9b, 0x3d, 0xc2, 0x54, 0x5b, 0xa9, 0x23, 0x57, 0xe1, 0x0a, 0x84, 0x7e, 0x3c, 0x52, 0x9c, 0x3d, 0x02, 0x9b, 0xb5, - 0x9c, 0x50, 0xfb, 0xfc, 0x43, 0xf9, 0x07, 0x34, 0xd9, 0xad, 0x3f, 0x59, 0x44, 0x6b, 0x47, 0xa0, 0xb9, 0x29, 0x63, 0xfb, - 0xd9, 0xd7, 0xfc, 0x62, 0xda, 0x23, 0x7e, 0x2b, 0xb6, 0x09, 0xfc, 0x52, 0x70, 0x77, 0xb9, 0x4d, 0x92, 0xdd, 0xf2, 0x82, - 0x8c, 0xa3, 0xf5, 0x79, 0xf9, 0x21, 0xe8, 0x36, 0xea, 0xf5, 0xa7, 0x8c, 0x3c, 0x46, 0xab, 0x29, 0xdc, 0x91, 0xa8, 0x8e, - 0xc5, 0xe7, 0xe5, 0x95, 0xd5, 0xca, 0xed, 0xad, 0x54, 0x24, 0xf2, 0xee, 0x40, 0x9c, 0x06, 0x08, 0x03, 0x36, 0x0a, 0x73, - 0xa4, 0xcb, 0xbb, 0x28, 0x83, 0x28, 0x66, 0xc3, 0x79, 0xba, 0x7a, 0x76, 0x90, 0x10, 0x88, 0x04, 0x3f, 0x0f, 0x67, 0xd2, - 0x53, 0xab, 0x63, 0xc7, 0x83, 0xc9, 0x2b, 0xdd, 0x9c, 0x61, 0x99, 0xe4, 0x12, 0x18, 0xc6, 0x9a, 0x9d, 0x3c, 0xea, 0x13, - 0x87, 0x32, 0x57, 0x8d, 0x01, 0x11, 0x39, 0x56, 0x94, 0xb2, 0x4d, 0x73, 0xc0, 0xdc, 0x2d, 0x4c, 0xb3, 0xd1, 0x90, 0x36, - 0xd8, 0xae, 0xd3, 0x06, 0xd7, 0x70, 0xa5, 0xd6, 0x0e, 0x64, 0xf8, 0x80, 0xb6, 0x36, 0x0c, 0x31, 0xd3, 0xcc, 0x46, 0xba, - 0xb4, 0x14, 0xb4, 0xcb, 0x43, 0x68, 0x0f, 0x8d, 0xf7, 0x2c, 0x61, 0xf4, 0xfb, 0xce, 0xf1, 0xaf, 0xe9, 0x2e, 0x52, 0x02, - 0x29, 0x5e, 0xd7, 0xc6, 0xed, 0xf6, 0x22, 0xb9, 0x7b, 0xe8, 0x1a, 0xe6, 0x59, 0xdb, 0x43, 0xdd, 0x58, 0xe2, 0x50, 0xab, - 0x57, 0x01, 0xf0, 0x61, 0xb0, 0x83, 0xa9, 0x40, 0x0c, 0x24, 0x08, 0x6e, 0x95, 0x45, 0xba, 0xb3, 0x02, 0xa9, 0x41, 0xde, - 0xaf, 0xc2, 0x4c, 0xc2, 0x71, 0x1e, 0x86, 0xe4, 0xe9, 0x81, 0x9e, 0xdf, 0xea, 0x11, 0x66, 0x91, 0x02, 0x8c, 0xf5, 0xa3, - 0x05, 0xe3, 0xe9, 0x6e, 0x7f, 0x34, 0xb5, 0x0a, 0x3f, 0xc3, 0x70, 0x18, 0x33, 0x33, 0x7e, 0x85, 0x81, 0x04, 0x1f, 0xaa, - 0x14, 0x0c, 0x57, 0xca, 0x41, 0x97, 0x79, 0x62, 0x2e, 0x99, 0xbc, 0x6f, 0xce, 0x21, 0xad, 0xde, 0x7d, 0x74, 0x73, 0x3f, - 0x75, 0x00, 0x65, 0xc2, 0x40, 0x5e, 0xda, 0xce, 0x41, 0x4e, 0x8b, 0xd0, 0x32, 0x4f, 0x7f, 0xee, 0xbe, 0xc9, 0x41, 0xb2, - 0x42, 0xe9, 0x5a, 0xe5, 0xee, 0x18, 0x0c, 0x70, 0x93, 0xec, 0xb2, 0x46, 0xcd, 0x11, 0x16, 0x31, 0x81, 0x33, 0x5e, 0x82, - 0x20, 0x85, 0x1b, 0x02, 0x76, 0xeb, 0x13, 0xb9, 0xd4, 0xbd, 0xf9, 0xe7, 0xb5, 0x5e, 0x5e, 0x05, 0x48, 0x74, 0x27, 0xf2, - 0xdc, 0x3e, 0x87, 0x8b, 0x33, 0x3f, 0x50, 0xb6, 0xc6, 0x52, 0xf8, 0x61, 0x69, 0x7e, 0x6b, 0x30, 0xef, 0x2c, 0x6c, 0x5e, - 0x69, 0xc8, 0xba, 0x1e, 0x3d, 0x2a, 0x0c, 0x74, 0xbd, 0x93, 0xc9, 0x36, 0xcc, 0x72, 0x15, 0xe6, 0xbb, 0xd0, 0xc0, 0xe3, - 0xaf, 0x60, 0xcd, 0x83, 0x54, 0x50, 0x67, 0xbb, 0x70, 0x2a, 0xa1, 0x51, 0x87, 0x9b, 0xc5, 0xe0, 0xbb, 0xa3, 0xb1, 0x6f, - 0x3a, 0x1a, 0x62, 0x72, 0x6f, 0x89, 0x8a, 0x1d, 0xc4, 0x09, 0x55, 0xac, 0x67, 0x7b, 0xa3, 0xe6, 0xed, 0x4e, 0xbb, 0xf2, - 0x5f, 0x42, 0x95, 0x7b, 0x95, 0x7a, 0xbe, 0x3e, 0xf5, 0x2f, 0xee, 0x5f, 0x30, 0x57, 0x51, 0x94, 0x7d, 0x45, 0xd5, 0xd7, - 0x6e, 0xcc, 0xf6, 0x4d, 0xac, 0x7b, 0x51, 0x70, 0x32, 0x07, 0x1c, 0xaf, 0x97, 0xdd, 0x92, 0x0d, 0x9d, 0xba, 0x53, 0xf5, - 0x49, 0xc7, 0xa5, 0x6a, 0x7a, 0x3b, 0xb0, 0x3f, 0x0c, 0x01, 0xa5, 0x00, 0x4a, 0x33, 0x90, 0xf7, 0xee, 0x0a, 0x12, 0x5d, - 0xc0, 0x5d, 0xb1, 0x85, 0x63, 0xed, 0xcf, 0xb8, 0x84, 0xde, 0x51, 0x8f, 0xd9, 0xf4, 0x15, 0x76, 0x43, 0xc4, 0xfe, 0x89, - 0x16, 0xfe, 0x13, 0x92, 0xbd, 0x25, 0x66, 0xb9, 0x56, 0x60, 0x1f, 0x85, 0x3d, 0xc6, 0x9a, 0x02, 0xc4, 0x2a, 0xbf, 0x8b, - 0x1b, 0xf1, 0x41, 0xbb, 0x37, 0x77, 0xe1, 0x18, 0xa7, 0x5f, 0x2a, 0x30, 0x37, 0xf6, 0xf4, 0x2a, 0x4b, 0x77, 0xf8, 0x15, - 0xc5, 0xb9, 0xb5, 0xdd, 0x93, 0x4f, 0x59, 0x97, 0x6b, 0xf2, 0xe8, 0x6e, 0xf5, 0x7e, 0x21, 0x20, 0x64, 0xac, 0xe8, 0x8d, - 0x60, 0xcb, 0xd2, 0xdc, 0xa7, 0xc8, 0x16, 0xb2, 0x7c, 0xf3, 0xbe, 0x88, 0x5b, 0x75, 0xcb, 0xf7, 0x38, 0x79, 0xa5, 0x32, - 0x5f, 0xa7, 0xf2, 0xfd, 0x6a, 0x21, 0x71, 0x16, 0x1b, 0xe9, 0xde, 0xd9, 0x88, 0xf2, 0x89, 0xef, 0x4f, 0x9a, 0xc4, 0x9b, - 0x04, 0xa0, 0x16, 0xab, 0x39, 0x62, 0x3f, 0x1f, 0x06, 0x2a, 0x88, 0x04, 0x68, 0x63, 0xb1, 0x21, 0x87, 0x25, 0xfb, 0xc3, - 0xb5, 0xe0, 0xc8, 0x48, 0x42, 0x4e, 0x3a, 0xc9, 0x90, 0x4c, 0xc1, 0xa5, 0x69, 0x62, 0xd6, 0x25, 0xdc, 0xc9, 0x51, 0xeb, - 0x6f, 0x00, 0x70, 0x91, 0x86, 0x57, 0x36, 0x23, 0x1f, 0x29, 0x8b, 0x52, 0xb2, 0x31, 0xd5, 0x8d, 0xc5, 0xa3, 0x5f, 0xd3, - 0x7a, 0xe4, 0x2e, 0x3a -}; - -/* Random data for hash agility attribute */ -uint8_t attribute[32] = { - 0x2e, 0xd0, 0xd3, 0x8f, 0xfd, 0xab, 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3, - 0x87, 0xa0, 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6 -}; - -/* Random data for hash agility V2 attribute */ -unsigned char _attributev2[64] = { - 0x28, 0x4f, 0x7f, 0xf5, 0xf8, 0x14, 0x80, 0xa6, 0x6b, 0x37, 0x44, 0xeb, 0xed, 0x1e, 0xf1, 0x3d, - 0x35, 0x4e, 0x02, 0x21, 0xdc, 0x26, 0x61, 0x33, 0x71, 0x57, 0x18, 0xc7, 0xdd, 0xc2, 0x50, 0xbf, - 0xfc, 0x9d, 0x6f, 0x8e, 0x8b, 0xe2, 0x3d, 0x1d, 0x41, 0xbf, 0xe6, 0xd1, 0x7a, 0xc9, 0x3f, 0xc9, - 0x4d, 0xdd, 0x38, 0x35, 0xbd, 0xdf, 0x98, 0x95, 0x0a, 0x00, 0xc6, 0x6d, 0x30, 0xe2, 0x37, 0x3b -}; - -/* Valid CMS message on content with hash agility attribute */ -uint8_t valid_message[] = { - 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, - 0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x07, 0x01, 0x00, 0x00, 0xa0, 0x82, 0x06, 0xb4, 0x30, 0x82, 0x06, 0xb0, 0x30, 0x82, 0x04, 0x98, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, - 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, - 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, - 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, - 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x18, - 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, - 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, - 0x32, 0x39, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x30, 0x32, - 0x38, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, - 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, - 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, - 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, - 0x01, 0x00, 0xc4, 0x2a, 0x38, 0x4b, 0xdd, 0x1c, 0xc7, 0x39, 0x47, 0xba, 0xbc, 0x5d, 0xd2, 0xcc, - 0x6e, 0x9e, 0x2c, 0x81, 0x26, 0x18, 0x59, 0x18, 0xb8, 0x45, 0x0c, 0xde, 0x5b, 0xbc, 0x25, 0xa4, - 0x78, 0x0b, 0x16, 0x3d, 0x3d, 0x10, 0x34, 0x48, 0xcf, 0x1f, 0x40, 0xaa, 0x4b, 0xb5, 0xbc, 0xf0, - 0x81, 0x5e, 0xa8, 0x72, 0xed, 0x6a, 0x8c, 0xf0, 0x4a, 0x9a, 0x80, 0x09, 0x3b, 0x89, 0xed, 0xad, - 0x2b, 0xb5, 0x5b, 0x0f, 0xe4, 0x3f, 0x6b, 0xc5, 0x15, 0x33, 0x5e, 0xdd, 0xa4, 0xac, 0x2f, 0xa5, - 0x13, 0x0f, 0x3c, 0xfc, 0xd8, 0xca, 0xb8, 0x88, 0x67, 0x75, 0xc4, 0x9a, 0x4c, 0x18, 0x9a, 0x38, - 0x68, 0xaa, 0x4c, 0x94, 0x35, 0xed, 0xa4, 0x0b, 0x80, 0x2b, 0xa9, 0x4d, 0xa4, 0x57, 0x22, 0xfc, - 0xd2, 0xc3, 0x12, 0x0b, 0x8a, 0x3c, 0xd7, 0x6d, 0x8b, 0x47, 0x4f, 0x24, 0xe5, 0xea, 0x1b, 0x03, - 0x78, 0xa2, 0x12, 0x36, 0x3f, 0x92, 0x16, 0x36, 0xff, 0xc5, 0xaf, 0xc3, 0xec, 0x4b, 0x6c, 0x23, - 0x04, 0x1b, 0xa9, 0xce, 0x3a, 0xa1, 0xa5, 0xe0, 0x54, 0x13, 0x43, 0x13, 0x29, 0x95, 0x5b, 0xcb, - 0x97, 0x74, 0x01, 0xbc, 0x3c, 0xb8, 0xa1, 0xb0, 0xf3, 0x3c, 0xfa, 0x21, 0x7a, 0x89, 0x90, 0x2b, - 0x1f, 0x20, 0x3f, 0xc1, 0x22, 0xda, 0x8d, 0xa5, 0x30, 0x57, 0x6d, 0xd4, 0x40, 0x99, 0x08, 0x0d, - 0xef, 0x36, 0x16, 0xa6, 0xec, 0xcf, 0x26, 0x78, 0x7c, 0x77, 0x7e, 0x50, 0x2a, 0xe3, 0xdf, 0x28, - 0xff, 0xd0, 0xc7, 0x0e, 0x8b, 0x6b, 0x56, 0x62, 0x53, 0x37, 0x5a, 0x1a, 0x85, 0x50, 0xec, 0x6a, - 0x6b, 0x2e, 0xd1, 0x35, 0x6e, 0x5d, 0x92, 0x30, 0x39, 0x82, 0x40, 0x7b, 0x6d, 0x89, 0x5b, 0x4d, - 0x30, 0x6d, 0x2e, 0x68, 0x16, 0x24, 0x63, 0x32, 0x24, 0xdc, 0x3e, 0x5b, 0x4a, 0xc4, 0x41, 0xfc, - 0x76, 0x07, 0xe6, 0xa3, 0x1b, 0x18, 0xec, 0x59, 0xed, 0x13, 0x0b, 0x2d, 0xe9, 0x86, 0x89, 0x2c, - 0x0a, 0xb0, 0x19, 0x97, 0x4d, 0x1b, 0xfb, 0xd4, 0xef, 0x54, 0xcd, 0xe5, 0xb2, 0x22, 0x70, 0x3a, - 0x50, 0x03, 0xaa, 0xc0, 0xf8, 0xb4, 0x8e, 0x16, 0xd8, 0x2a, 0xc1, 0xd1, 0x2d, 0xa0, 0x27, 0x59, - 0x63, 0x70, 0xc3, 0x74, 0x14, 0xee, 0xde, 0xa9, 0xd9, 0x73, 0xdb, 0x16, 0x6d, 0xef, 0x7f, 0x50, - 0xb6, 0xd2, 0x54, 0x0d, 0x4d, 0x31, 0x5f, 0x23, 0x2c, 0xfd, 0x8f, 0x67, 0x7c, 0xe9, 0xaa, 0x1c, - 0x29, 0xf5, 0x83, 0x1b, 0x2b, 0x0e, 0x66, 0x0e, 0x5c, 0xfe, 0xc9, 0x38, 0xb0, 0x90, 0xfa, 0x31, - 0x4c, 0xb1, 0xef, 0xea, 0xd0, 0x47, 0x17, 0xde, 0x45, 0xc1, 0x93, 0xef, 0xba, 0xde, 0x9f, 0x69, - 0xc7, 0xa6, 0x14, 0x23, 0xb1, 0x8b, 0xaa, 0xbf, 0x61, 0x37, 0x57, 0x11, 0x6a, 0xb2, 0xf7, 0xec, - 0x52, 0x7e, 0x65, 0x80, 0xff, 0xa1, 0xa8, 0x20, 0x7e, 0x0b, 0xae, 0x21, 0xfa, 0xe8, 0x20, 0x52, - 0x93, 0xc5, 0xe9, 0x39, 0x5b, 0x8e, 0xab, 0xef, 0x86, 0xa6, 0xd8, 0x43, 0x7e, 0xa9, 0x5c, 0x6d, - 0x91, 0xd8, 0x5c, 0xa4, 0x2a, 0xed, 0x26, 0xa8, 0x1b, 0xaa, 0x3b, 0xfa, 0x86, 0x75, 0x37, 0xc6, - 0x70, 0x12, 0x2b, 0x8c, 0x55, 0x96, 0x76, 0x04, 0xf6, 0xe3, 0xf9, 0xe2, 0x0d, 0x2e, 0xe0, 0x23, - 0xdf, 0xfa, 0xe0, 0x9c, 0x11, 0xf9, 0xd4, 0x51, 0x05, 0xed, 0x2b, 0x3f, 0xa3, 0x3f, 0xa2, 0xe6, - 0x30, 0x81, 0x17, 0x00, 0x8f, 0x15, 0x91, 0xfb, 0x21, 0x62, 0xf4, 0xff, 0x93, 0x1a, 0x2e, 0xfe, - 0x1a, 0xcb, 0x93, 0x3d, 0xd4, 0x6e, 0x3a, 0xb8, 0x70, 0xdf, 0x93, 0xb4, 0x02, 0xc4, 0x8c, 0x54, - 0x92, 0xde, 0xa7, 0x32, 0x65, 0x1c, 0x85, 0x95, 0x34, 0xf8, 0x8d, 0x06, 0x5b, 0x7d, 0x72, 0x00, - 0xd8, 0x31, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfe, 0x30, 0x81, 0xfb, 0x30, 0x1d, 0x06, - 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xee, 0x16, 0xde, 0xfd, 0x11, 0xd3, 0x88, 0xfb, - 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, 0x30, 0x81, 0xcb, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xc3, 0x30, 0x81, 0xc0, 0x80, 0x14, 0xee, 0x16, 0xde, 0xfd, - 0x11, 0xd3, 0x88, 0xfb, 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, - 0xa1, 0x81, 0x9c, 0xa4, 0x81, 0x99, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, - 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, - 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, - 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x82, - 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x0c, 0x0f, 0x08, 0x79, - 0x6f, 0x56, 0x21, 0xdf, 0xdd, 0xf5, 0x97, 0x8d, 0xdc, 0x97, 0x06, 0xfb, 0x2e, 0xe0, 0x21, 0x60, - 0xc3, 0x02, 0xf4, 0x41, 0x79, 0x79, 0xc2, 0x23, 0x9a, 0x8a, 0x54, 0x2e, 0x66, 0xab, 0xc0, 0x21, - 0xf6, 0x9f, 0xc5, 0x2e, 0x41, 0xb8, 0xa3, 0x32, 0x9f, 0x3d, 0x4e, 0xf4, 0x83, 0xee, 0xcc, 0x60, - 0xf6, 0x82, 0x3d, 0xb4, 0xa9, 0x9d, 0xcd, 0xa0, 0x02, 0x89, 0xb0, 0x32, 0x1b, 0xb5, 0x7c, 0xf4, - 0x8f, 0xbc, 0x9b, 0x24, 0xc2, 0xe2, 0x81, 0xd6, 0x6f, 0x0e, 0x22, 0x5e, 0x50, 0xd9, 0x5b, 0x2e, - 0x89, 0xbf, 0xa4, 0xfe, 0xa8, 0xc2, 0x9a, 0xf4, 0xec, 0x70, 0x66, 0x01, 0x4b, 0x50, 0x30, 0x97, - 0x0a, 0xcc, 0x9f, 0xac, 0xe4, 0x89, 0x1c, 0x8d, 0x88, 0x0d, 0xdb, 0x21, 0xbd, 0x2f, 0x24, 0x8e, - 0x83, 0xf9, 0xe6, 0x71, 0xed, 0x71, 0x26, 0x31, 0x99, 0x9d, 0x04, 0xeb, 0x34, 0xea, 0x6d, 0x65, - 0xb8, 0x02, 0x83, 0x57, 0x78, 0x36, 0x3a, 0x0b, 0xc7, 0x41, 0x63, 0xb5, 0xf6, 0x1c, 0xd2, 0x01, - 0x86, 0x04, 0x58, 0x40, 0x3e, 0x91, 0x98, 0x39, 0x72, 0x75, 0x11, 0xca, 0x14, 0x73, 0x90, 0x34, - 0x8b, 0x21, 0xa4, 0xd0, 0xba, 0xe7, 0x33, 0x03, 0x22, 0x0f, 0x1a, 0xf7, 0x10, 0x2b, 0x69, 0x4c, - 0x73, 0xef, 0x04, 0x18, 0xf9, 0xe1, 0x11, 0xa8, 0xb8, 0x1b, 0x57, 0x0b, 0x03, 0x10, 0x1c, 0xce, - 0x13, 0xca, 0xe4, 0xde, 0x8c, 0xf4, 0xcf, 0xf5, 0xb7, 0x80, 0x3e, 0xbc, 0x1f, 0x51, 0x9b, 0x20, - 0x8c, 0xb0, 0x2d, 0x67, 0x1c, 0x84, 0x25, 0x4c, 0x8b, 0xd3, 0xa7, 0x09, 0x8e, 0x60, 0xe2, 0x99, - 0x0d, 0x10, 0x12, 0x14, 0xfc, 0x17, 0x62, 0x69, 0xcd, 0xa4, 0x64, 0xf0, 0x7e, 0xba, 0xe0, 0xc9, - 0x51, 0x78, 0xf8, 0xb4, 0x0d, 0x7d, 0xb8, 0xa0, 0xee, 0x9c, 0x9e, 0x84, 0xd5, 0xa4, 0x02, 0xe5, - 0x7a, 0x1c, 0x65, 0xe1, 0x20, 0xfb, 0x4d, 0x61, 0x7a, 0x47, 0x25, 0x06, 0x95, 0x17, 0x62, 0x60, - 0x4b, 0x0b, 0xc6, 0xca, 0xa7, 0x35, 0x8f, 0xd4, 0x63, 0x3e, 0x5e, 0x92, 0x1a, 0x08, 0x7c, 0x6b, - 0x15, 0x41, 0x95, 0x76, 0x7d, 0x39, 0x28, 0xec, 0x3e, 0x1f, 0x49, 0xd5, 0xd5, 0x89, 0xf9, 0x5f, - 0x14, 0x02, 0x2f, 0x27, 0xb0, 0x39, 0xba, 0xf7, 0x91, 0x53, 0x75, 0x77, 0xab, 0x88, 0x40, 0x1d, - 0x77, 0xaf, 0x79, 0xfd, 0xdc, 0xac, 0x99, 0x82, 0xf2, 0x46, 0x05, 0x97, 0x60, 0xef, 0x7b, 0xf5, - 0x34, 0x38, 0xbf, 0xd7, 0x42, 0x3e, 0x8b, 0x5a, 0x4a, 0x0c, 0x22, 0x7e, 0x4d, 0x4e, 0xf6, 0xf7, - 0xcc, 0x6e, 0x31, 0x33, 0x1a, 0x84, 0xbe, 0x07, 0xf7, 0xe8, 0xe2, 0x43, 0x00, 0x54, 0x4a, 0x38, - 0xda, 0x98, 0xe3, 0x84, 0xb2, 0xd0, 0x76, 0x79, 0x94, 0x11, 0x7e, 0xa8, 0xca, 0x56, 0xa0, 0xfd, - 0x4b, 0xba, 0x7c, 0x0a, 0xa4, 0x34, 0x01, 0xad, 0xf4, 0x37, 0x4f, 0x38, 0x33, 0x9f, 0x71, 0xdc, - 0xc4, 0x4c, 0x96, 0xb0, 0x8a, 0x86, 0xe5, 0x8d, 0xd2, 0x44, 0xe3, 0x18, 0xcb, 0x81, 0xa6, 0x7c, - 0xaf, 0x8e, 0xfb, 0x41, 0x6e, 0xc5, 0x82, 0xf0, 0x51, 0xb7, 0x0f, 0x23, 0x9b, 0x77, 0xed, 0x9a, - 0x06, 0x6b, 0x77, 0x7c, 0x8e, 0xc4, 0xdf, 0x50, 0xa0, 0xd2, 0x81, 0x3e, 0x65, 0xbe, 0xe5, 0x51, - 0x79, 0x93, 0x24, 0x8e, 0xb3, 0xb5, 0x25, 0x48, 0x76, 0x0e, 0x75, 0x94, 0xef, 0x9a, 0x9d, 0xc7, - 0x95, 0x08, 0xca, 0x35, 0x6b, 0x73, 0xbc, 0x4b, 0x93, 0x7a, 0x93, 0x55, 0x2d, 0xe4, 0x5f, 0xcf, - 0x11, 0x31, 0x94, 0xb2, 0x5a, 0x05, 0x80, 0xd7, 0x59, 0x79, 0x14, 0x8a, 0x2a, 0xb9, 0xd7, 0x3d, - 0x33, 0x69, 0xa9, 0xab, 0xaa, 0xb8, 0x4c, 0x73, 0xb6, 0x71, 0x2c, 0x6f, 0x31, 0x82, 0x03, 0x6d, - 0x30, 0x82, 0x03, 0x69, 0x02, 0x01, 0x01, 0x30, 0x81, 0xa4, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, - 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, - 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, - 0x6e, 0x65, 0x72, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0d, - 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x81, 0x9a, - 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x31, 0x30, - 0x34, 0x30, 0x31, 0x35, 0x36, 0x34, 0x30, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x30, 0x9e, 0x11, 0x91, 0x83, 0x14, 0xd8, - 0xb9, 0xd6, 0x24, 0x8e, 0x04, 0x7e, 0x31, 0xa7, 0x66, 0xf7, 0x3c, 0x96, 0xc6, 0x23, 0x60, 0x2e, - 0xec, 0x9e, 0x0c, 0xda, 0xab, 0x25, 0x58, 0x02, 0xf2, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x22, 0x04, 0x20, 0x2e, 0xd0, 0xd3, 0x8f, 0xfd, 0xab, - 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3, 0x87, 0xa0, - 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x89, 0xd3, 0x00, - 0x9b, 0xd0, 0x99, 0x21, 0x21, 0x47, 0xff, 0xa3, 0x4c, 0xef, 0xa7, 0x6e, 0x03, 0x1e, 0xbf, 0x6d, - 0x10, 0x3e, 0xf7, 0x36, 0x7e, 0x98, 0xb4, 0xb6, 0x74, 0xa0, 0xa6, 0x2c, 0x83, 0x33, 0xec, 0xeb, - 0xb5, 0x69, 0x3b, 0x10, 0x80, 0x60, 0x2b, 0xf4, 0x71, 0x84, 0x2a, 0x22, 0xfa, 0xbe, 0x51, 0x3d, - 0x69, 0xdc, 0x2b, 0x94, 0xf6, 0x8a, 0x82, 0xee, 0x88, 0xa3, 0xa4, 0x8a, 0x4d, 0x13, 0xee, 0x4b, - 0xf2, 0xd0, 0xef, 0x3a, 0x2d, 0xe0, 0x3e, 0x52, 0xe9, 0x75, 0xf3, 0xf1, 0x8a, 0xc6, 0x68, 0xab, - 0x5f, 0x97, 0x7c, 0xef, 0x2e, 0x06, 0xe4, 0x53, 0x2e, 0xa5, 0x20, 0x8b, 0x8a, 0x1f, 0x0b, 0x8a, - 0xb2, 0x0e, 0xe0, 0x77, 0xbf, 0x4d, 0x0f, 0x45, 0x15, 0x7f, 0x03, 0xdc, 0x0a, 0x5c, 0xcc, 0x88, - 0x49, 0x0b, 0x19, 0xde, 0xd8, 0xdd, 0x62, 0xc6, 0xad, 0x77, 0xaa, 0x37, 0x19, 0x31, 0x6d, 0x57, - 0x7f, 0x29, 0xc1, 0xe2, 0x7a, 0x15, 0xf9, 0xb9, 0xa5, 0xe2, 0xf3, 0xeb, 0x3f, 0x27, 0x5d, 0xac, - 0x02, 0xb8, 0xf7, 0x6d, 0xfe, 0x0f, 0x22, 0x89, 0xe3, 0x5d, 0xcc, 0xf3, 0x6a, 0x8f, 0x1a, 0xe5, - 0x94, 0xfd, 0xad, 0x9a, 0xc2, 0x5d, 0xb5, 0x1b, 0x48, 0xd8, 0x0b, 0x77, 0x9c, 0x27, 0x24, 0x55, - 0xf3, 0x8f, 0x5b, 0x7e, 0x0a, 0x73, 0x35, 0xb4, 0x6c, 0xc7, 0x84, 0xc3, 0x0b, 0x22, 0x57, 0x4d, - 0xff, 0x45, 0x4d, 0x78, 0xa7, 0xd0, 0x7d, 0xcf, 0x74, 0x5c, 0xe8, 0xa6, 0x26, 0x76, 0xda, 0xf1, - 0x4f, 0x75, 0x89, 0xd1, 0x6c, 0x7e, 0x52, 0x8c, 0x6e, 0xa8, 0x6e, 0x4c, 0x5b, 0x54, 0x94, 0x35, - 0x92, 0xec, 0x22, 0x5c, 0xdd, 0x97, 0x41, 0xef, 0x9f, 0x6d, 0xa2, 0x63, 0xaa, 0x22, 0x81, 0xab, - 0xfa, 0x0d, 0x2d, 0xed, 0xe6, 0x45, 0xe4, 0x2a, 0x51, 0x1d, 0xa6, 0x8d, 0x24, 0x99, 0xda, 0xb6, - 0xe3, 0xeb, 0x56, 0xf8, 0x6d, 0xe7, 0xbf, 0x14, 0xfa, 0x41, 0x82, 0x93, 0x28, 0xb0, 0x3f, 0x83, - 0x3a, 0x10, 0x79, 0x18, 0x4f, 0x21, 0xc7, 0xd1, 0x5f, 0x80, 0x77, 0x98, 0x0e, 0x26, 0xdd, 0x36, - 0xc7, 0xc6, 0x6b, 0xd2, 0x42, 0xd8, 0xa1, 0xfc, 0x69, 0x90, 0xa6, 0xea, 0xe6, 0xf2, 0x5b, 0x78, - 0xb7, 0x27, 0xe2, 0x13, 0xc2, 0xe7, 0xdf, 0x37, 0x30, 0x94, 0xaf, 0xbf, 0x88, 0x63, 0x3d, 0xad, - 0xfc, 0xdb, 0xf4, 0x5f, 0x5c, 0x4b, 0x07, 0x36, 0xc2, 0xc2, 0xca, 0xe3, 0x3d, 0xd9, 0x51, 0x88, - 0x37, 0xb5, 0xd6, 0x36, 0x63, 0x42, 0x8b, 0xd3, 0x86, 0xc3, 0xc0, 0x1c, 0x08, 0x2c, 0x5c, 0x93, - 0x21, 0x3e, 0x7a, 0x54, 0x21, 0xa4, 0xbc, 0x78, 0xdc, 0x41, 0x78, 0x18, 0x83, 0xf6, 0x4d, 0x2d, - 0x3a, 0xa1, 0xf3, 0xd2, 0x3e, 0x31, 0x91, 0x6f, 0xf9, 0xd3, 0xd6, 0xe1, 0xef, 0x83, 0xd7, 0x59, - 0xc9, 0xa3, 0x36, 0xcc, 0x26, 0xfd, 0x7c, 0x93, 0x0a, 0x4e, 0xae, 0x45, 0x4b, 0xb0, 0x58, 0xd0, - 0xb0, 0xca, 0x70, 0x35, 0x2f, 0x63, 0x28, 0x9d, 0x5a, 0xc8, 0x02, 0xf9, 0x8b, 0xaa, 0xcf, 0x6d, - 0x8b, 0xbb, 0xb5, 0xf6, 0x44, 0xe4, 0xcb, 0x3d, 0xbe, 0xd2, 0x70, 0x2d, 0xb3, 0xe9, 0x05, 0x6c, - 0xfe, 0x41, 0xa3, 0x05, 0xec, 0xe4, 0xf1, 0x9e, 0x37, 0x04, 0xd1, 0x9a, 0x60, 0xf9, 0x95, 0xc4, - 0x11, 0xb3, 0xbf, 0x17, 0xa4, 0x72, 0x2a, 0x03, 0x2d, 0x9a, 0x2b, 0xed, 0x97, 0xc9, 0x29, 0x05, - 0x23, 0xbb, 0xd2, 0xfe, 0x0b, 0x91, 0x5b, 0x93, 0x3f, 0x93, 0x10, 0x69, 0xcb, 0x92, 0x14, 0x8c, - 0xd4, 0xf3, 0x4f, 0x51, 0xc4, 0x78, 0x52, 0xc1, 0xea, 0x20, 0xa9, 0x16, 0x9b, 0x51, 0xb3, 0x69, - 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 -}; - -/* - * Invalid CMS message on content with hash agility attribute. - * Only the hash agility attribute value has been changed from the valid message. - */ -uint8_t invalid_message[] = { - 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, - 0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x07, 0x01, 0x00, 0x00, 0xa0, 0x82, 0x06, 0xb4, 0x30, 0x82, 0x06, 0xb0, 0x30, 0x82, 0x04, 0x98, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, - 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, - 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, - 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, - 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x18, - 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, - 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, - 0x32, 0x39, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x30, 0x32, - 0x38, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, - 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, - 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, - 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, - 0x01, 0x00, 0xc4, 0x2a, 0x38, 0x4b, 0xdd, 0x1c, 0xc7, 0x39, 0x47, 0xba, 0xbc, 0x5d, 0xd2, 0xcc, - 0x6e, 0x9e, 0x2c, 0x81, 0x26, 0x18, 0x59, 0x18, 0xb8, 0x45, 0x0c, 0xde, 0x5b, 0xbc, 0x25, 0xa4, - 0x78, 0x0b, 0x16, 0x3d, 0x3d, 0x10, 0x34, 0x48, 0xcf, 0x1f, 0x40, 0xaa, 0x4b, 0xb5, 0xbc, 0xf0, - 0x81, 0x5e, 0xa8, 0x72, 0xed, 0x6a, 0x8c, 0xf0, 0x4a, 0x9a, 0x80, 0x09, 0x3b, 0x89, 0xed, 0xad, - 0x2b, 0xb5, 0x5b, 0x0f, 0xe4, 0x3f, 0x6b, 0xc5, 0x15, 0x33, 0x5e, 0xdd, 0xa4, 0xac, 0x2f, 0xa5, - 0x13, 0x0f, 0x3c, 0xfc, 0xd8, 0xca, 0xb8, 0x88, 0x67, 0x75, 0xc4, 0x9a, 0x4c, 0x18, 0x9a, 0x38, - 0x68, 0xaa, 0x4c, 0x94, 0x35, 0xed, 0xa4, 0x0b, 0x80, 0x2b, 0xa9, 0x4d, 0xa4, 0x57, 0x22, 0xfc, - 0xd2, 0xc3, 0x12, 0x0b, 0x8a, 0x3c, 0xd7, 0x6d, 0x8b, 0x47, 0x4f, 0x24, 0xe5, 0xea, 0x1b, 0x03, - 0x78, 0xa2, 0x12, 0x36, 0x3f, 0x92, 0x16, 0x36, 0xff, 0xc5, 0xaf, 0xc3, 0xec, 0x4b, 0x6c, 0x23, - 0x04, 0x1b, 0xa9, 0xce, 0x3a, 0xa1, 0xa5, 0xe0, 0x54, 0x13, 0x43, 0x13, 0x29, 0x95, 0x5b, 0xcb, - 0x97, 0x74, 0x01, 0xbc, 0x3c, 0xb8, 0xa1, 0xb0, 0xf3, 0x3c, 0xfa, 0x21, 0x7a, 0x89, 0x90, 0x2b, - 0x1f, 0x20, 0x3f, 0xc1, 0x22, 0xda, 0x8d, 0xa5, 0x30, 0x57, 0x6d, 0xd4, 0x40, 0x99, 0x08, 0x0d, - 0xef, 0x36, 0x16, 0xa6, 0xec, 0xcf, 0x26, 0x78, 0x7c, 0x77, 0x7e, 0x50, 0x2a, 0xe3, 0xdf, 0x28, - 0xff, 0xd0, 0xc7, 0x0e, 0x8b, 0x6b, 0x56, 0x62, 0x53, 0x37, 0x5a, 0x1a, 0x85, 0x50, 0xec, 0x6a, - 0x6b, 0x2e, 0xd1, 0x35, 0x6e, 0x5d, 0x92, 0x30, 0x39, 0x82, 0x40, 0x7b, 0x6d, 0x89, 0x5b, 0x4d, - 0x30, 0x6d, 0x2e, 0x68, 0x16, 0x24, 0x63, 0x32, 0x24, 0xdc, 0x3e, 0x5b, 0x4a, 0xc4, 0x41, 0xfc, - 0x76, 0x07, 0xe6, 0xa3, 0x1b, 0x18, 0xec, 0x59, 0xed, 0x13, 0x0b, 0x2d, 0xe9, 0x86, 0x89, 0x2c, - 0x0a, 0xb0, 0x19, 0x97, 0x4d, 0x1b, 0xfb, 0xd4, 0xef, 0x54, 0xcd, 0xe5, 0xb2, 0x22, 0x70, 0x3a, - 0x50, 0x03, 0xaa, 0xc0, 0xf8, 0xb4, 0x8e, 0x16, 0xd8, 0x2a, 0xc1, 0xd1, 0x2d, 0xa0, 0x27, 0x59, - 0x63, 0x70, 0xc3, 0x74, 0x14, 0xee, 0xde, 0xa9, 0xd9, 0x73, 0xdb, 0x16, 0x6d, 0xef, 0x7f, 0x50, - 0xb6, 0xd2, 0x54, 0x0d, 0x4d, 0x31, 0x5f, 0x23, 0x2c, 0xfd, 0x8f, 0x67, 0x7c, 0xe9, 0xaa, 0x1c, - 0x29, 0xf5, 0x83, 0x1b, 0x2b, 0x0e, 0x66, 0x0e, 0x5c, 0xfe, 0xc9, 0x38, 0xb0, 0x90, 0xfa, 0x31, - 0x4c, 0xb1, 0xef, 0xea, 0xd0, 0x47, 0x17, 0xde, 0x45, 0xc1, 0x93, 0xef, 0xba, 0xde, 0x9f, 0x69, - 0xc7, 0xa6, 0x14, 0x23, 0xb1, 0x8b, 0xaa, 0xbf, 0x61, 0x37, 0x57, 0x11, 0x6a, 0xb2, 0xf7, 0xec, - 0x52, 0x7e, 0x65, 0x80, 0xff, 0xa1, 0xa8, 0x20, 0x7e, 0x0b, 0xae, 0x21, 0xfa, 0xe8, 0x20, 0x52, - 0x93, 0xc5, 0xe9, 0x39, 0x5b, 0x8e, 0xab, 0xef, 0x86, 0xa6, 0xd8, 0x43, 0x7e, 0xa9, 0x5c, 0x6d, - 0x91, 0xd8, 0x5c, 0xa4, 0x2a, 0xed, 0x26, 0xa8, 0x1b, 0xaa, 0x3b, 0xfa, 0x86, 0x75, 0x37, 0xc6, - 0x70, 0x12, 0x2b, 0x8c, 0x55, 0x96, 0x76, 0x04, 0xf6, 0xe3, 0xf9, 0xe2, 0x0d, 0x2e, 0xe0, 0x23, - 0xdf, 0xfa, 0xe0, 0x9c, 0x11, 0xf9, 0xd4, 0x51, 0x05, 0xed, 0x2b, 0x3f, 0xa3, 0x3f, 0xa2, 0xe6, - 0x30, 0x81, 0x17, 0x00, 0x8f, 0x15, 0x91, 0xfb, 0x21, 0x62, 0xf4, 0xff, 0x93, 0x1a, 0x2e, 0xfe, - 0x1a, 0xcb, 0x93, 0x3d, 0xd4, 0x6e, 0x3a, 0xb8, 0x70, 0xdf, 0x93, 0xb4, 0x02, 0xc4, 0x8c, 0x54, - 0x92, 0xde, 0xa7, 0x32, 0x65, 0x1c, 0x85, 0x95, 0x34, 0xf8, 0x8d, 0x06, 0x5b, 0x7d, 0x72, 0x00, - 0xd8, 0x31, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfe, 0x30, 0x81, 0xfb, 0x30, 0x1d, 0x06, - 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xee, 0x16, 0xde, 0xfd, 0x11, 0xd3, 0x88, 0xfb, - 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, 0x30, 0x81, 0xcb, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xc3, 0x30, 0x81, 0xc0, 0x80, 0x14, 0xee, 0x16, 0xde, 0xfd, - 0x11, 0xd3, 0x88, 0xfb, 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, - 0xa1, 0x81, 0x9c, 0xa4, 0x81, 0x99, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, - 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, - 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, - 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x82, - 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x0c, 0x0f, 0x08, 0x79, - 0x6f, 0x56, 0x21, 0xdf, 0xdd, 0xf5, 0x97, 0x8d, 0xdc, 0x97, 0x06, 0xfb, 0x2e, 0xe0, 0x21, 0x60, - 0xc3, 0x02, 0xf4, 0x41, 0x79, 0x79, 0xc2, 0x23, 0x9a, 0x8a, 0x54, 0x2e, 0x66, 0xab, 0xc0, 0x21, - 0xf6, 0x9f, 0xc5, 0x2e, 0x41, 0xb8, 0xa3, 0x32, 0x9f, 0x3d, 0x4e, 0xf4, 0x83, 0xee, 0xcc, 0x60, - 0xf6, 0x82, 0x3d, 0xb4, 0xa9, 0x9d, 0xcd, 0xa0, 0x02, 0x89, 0xb0, 0x32, 0x1b, 0xb5, 0x7c, 0xf4, - 0x8f, 0xbc, 0x9b, 0x24, 0xc2, 0xe2, 0x81, 0xd6, 0x6f, 0x0e, 0x22, 0x5e, 0x50, 0xd9, 0x5b, 0x2e, - 0x89, 0xbf, 0xa4, 0xfe, 0xa8, 0xc2, 0x9a, 0xf4, 0xec, 0x70, 0x66, 0x01, 0x4b, 0x50, 0x30, 0x97, - 0x0a, 0xcc, 0x9f, 0xac, 0xe4, 0x89, 0x1c, 0x8d, 0x88, 0x0d, 0xdb, 0x21, 0xbd, 0x2f, 0x24, 0x8e, - 0x83, 0xf9, 0xe6, 0x71, 0xed, 0x71, 0x26, 0x31, 0x99, 0x9d, 0x04, 0xeb, 0x34, 0xea, 0x6d, 0x65, - 0xb8, 0x02, 0x83, 0x57, 0x78, 0x36, 0x3a, 0x0b, 0xc7, 0x41, 0x63, 0xb5, 0xf6, 0x1c, 0xd2, 0x01, - 0x86, 0x04, 0x58, 0x40, 0x3e, 0x91, 0x98, 0x39, 0x72, 0x75, 0x11, 0xca, 0x14, 0x73, 0x90, 0x34, - 0x8b, 0x21, 0xa4, 0xd0, 0xba, 0xe7, 0x33, 0x03, 0x22, 0x0f, 0x1a, 0xf7, 0x10, 0x2b, 0x69, 0x4c, - 0x73, 0xef, 0x04, 0x18, 0xf9, 0xe1, 0x11, 0xa8, 0xb8, 0x1b, 0x57, 0x0b, 0x03, 0x10, 0x1c, 0xce, - 0x13, 0xca, 0xe4, 0xde, 0x8c, 0xf4, 0xcf, 0xf5, 0xb7, 0x80, 0x3e, 0xbc, 0x1f, 0x51, 0x9b, 0x20, - 0x8c, 0xb0, 0x2d, 0x67, 0x1c, 0x84, 0x25, 0x4c, 0x8b, 0xd3, 0xa7, 0x09, 0x8e, 0x60, 0xe2, 0x99, - 0x0d, 0x10, 0x12, 0x14, 0xfc, 0x17, 0x62, 0x69, 0xcd, 0xa4, 0x64, 0xf0, 0x7e, 0xba, 0xe0, 0xc9, - 0x51, 0x78, 0xf8, 0xb4, 0x0d, 0x7d, 0xb8, 0xa0, 0xee, 0x9c, 0x9e, 0x84, 0xd5, 0xa4, 0x02, 0xe5, - 0x7a, 0x1c, 0x65, 0xe1, 0x20, 0xfb, 0x4d, 0x61, 0x7a, 0x47, 0x25, 0x06, 0x95, 0x17, 0x62, 0x60, - 0x4b, 0x0b, 0xc6, 0xca, 0xa7, 0x35, 0x8f, 0xd4, 0x63, 0x3e, 0x5e, 0x92, 0x1a, 0x08, 0x7c, 0x6b, - 0x15, 0x41, 0x95, 0x76, 0x7d, 0x39, 0x28, 0xec, 0x3e, 0x1f, 0x49, 0xd5, 0xd5, 0x89, 0xf9, 0x5f, - 0x14, 0x02, 0x2f, 0x27, 0xb0, 0x39, 0xba, 0xf7, 0x91, 0x53, 0x75, 0x77, 0xab, 0x88, 0x40, 0x1d, - 0x77, 0xaf, 0x79, 0xfd, 0xdc, 0xac, 0x99, 0x82, 0xf2, 0x46, 0x05, 0x97, 0x60, 0xef, 0x7b, 0xf5, - 0x34, 0x38, 0xbf, 0xd7, 0x42, 0x3e, 0x8b, 0x5a, 0x4a, 0x0c, 0x22, 0x7e, 0x4d, 0x4e, 0xf6, 0xf7, - 0xcc, 0x6e, 0x31, 0x33, 0x1a, 0x84, 0xbe, 0x07, 0xf7, 0xe8, 0xe2, 0x43, 0x00, 0x54, 0x4a, 0x38, - 0xda, 0x98, 0xe3, 0x84, 0xb2, 0xd0, 0x76, 0x79, 0x94, 0x11, 0x7e, 0xa8, 0xca, 0x56, 0xa0, 0xfd, - 0x4b, 0xba, 0x7c, 0x0a, 0xa4, 0x34, 0x01, 0xad, 0xf4, 0x37, 0x4f, 0x38, 0x33, 0x9f, 0x71, 0xdc, - 0xc4, 0x4c, 0x96, 0xb0, 0x8a, 0x86, 0xe5, 0x8d, 0xd2, 0x44, 0xe3, 0x18, 0xcb, 0x81, 0xa6, 0x7c, - 0xaf, 0x8e, 0xfb, 0x41, 0x6e, 0xc5, 0x82, 0xf0, 0x51, 0xb7, 0x0f, 0x23, 0x9b, 0x77, 0xed, 0x9a, - 0x06, 0x6b, 0x77, 0x7c, 0x8e, 0xc4, 0xdf, 0x50, 0xa0, 0xd2, 0x81, 0x3e, 0x65, 0xbe, 0xe5, 0x51, - 0x79, 0x93, 0x24, 0x8e, 0xb3, 0xb5, 0x25, 0x48, 0x76, 0x0e, 0x75, 0x94, 0xef, 0x9a, 0x9d, 0xc7, - 0x95, 0x08, 0xca, 0x35, 0x6b, 0x73, 0xbc, 0x4b, 0x93, 0x7a, 0x93, 0x55, 0x2d, 0xe4, 0x5f, 0xcf, - 0x11, 0x31, 0x94, 0xb2, 0x5a, 0x05, 0x80, 0xd7, 0x59, 0x79, 0x14, 0x8a, 0x2a, 0xb9, 0xd7, 0x3d, - 0x33, 0x69, 0xa9, 0xab, 0xaa, 0xb8, 0x4c, 0x73, 0xb6, 0x71, 0x2c, 0x6f, 0x31, 0x82, 0x03, 0x6d, - 0x30, 0x82, 0x03, 0x69, 0x02, 0x01, 0x01, 0x30, 0x81, 0xa4, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, - 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, - 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, - 0x6e, 0x65, 0x72, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0d, - 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x81, 0x9a, - 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x31, 0x30, - 0x34, 0x30, 0x31, 0x35, 0x36, 0x34, 0x30, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x30, 0x9e, 0x11, 0x91, 0x83, 0x14, 0xd8, - 0xb9, 0xd6, 0x24, 0x8e, 0x04, 0x7e, 0x31, 0xa7, 0x66, 0xf7, 0x3c, 0x96, 0xc6, 0x23, 0x60, 0x2e, - 0xec, 0x9e, 0x0c, 0xda, 0xab, 0x25, 0x58, 0x02, 0xf2, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x22, 0x04, 0x20, 0x2e, 0xd0, 0xd0, 0x8f, 0xfd, 0xab, - 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3, 0x87, 0xa0, - 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x89, 0xd3, 0x00, - 0x9b, 0xd0, 0x99, 0x21, 0x21, 0x47, 0xff, 0xa3, 0x4c, 0xef, 0xa7, 0x6e, 0x03, 0x1e, 0xbf, 0x6d, - 0x10, 0x3e, 0xf7, 0x36, 0x7e, 0x98, 0xb4, 0xb6, 0x74, 0xa0, 0xa6, 0x2c, 0x83, 0x33, 0xec, 0xeb, - 0xb5, 0x69, 0x3b, 0x10, 0x80, 0x60, 0x2b, 0xf4, 0x71, 0x84, 0x2a, 0x22, 0xfa, 0xbe, 0x51, 0x3d, - 0x69, 0xdc, 0x2b, 0x94, 0xf6, 0x8a, 0x82, 0xee, 0x88, 0xa3, 0xa4, 0x8a, 0x4d, 0x13, 0xee, 0x4b, - 0xf2, 0xd0, 0xef, 0x3a, 0x2d, 0xe0, 0x3e, 0x52, 0xe9, 0x75, 0xf3, 0xf1, 0x8a, 0xc6, 0x68, 0xab, - 0x5f, 0x97, 0x7c, 0xef, 0x2e, 0x06, 0xe4, 0x53, 0x2e, 0xa5, 0x20, 0x8b, 0x8a, 0x1f, 0x0b, 0x8a, - 0xb2, 0x0e, 0xe0, 0x77, 0xbf, 0x4d, 0x0f, 0x45, 0x15, 0x7f, 0x03, 0xdc, 0x0a, 0x5c, 0xcc, 0x88, - 0x49, 0x0b, 0x19, 0xde, 0xd8, 0xdd, 0x62, 0xc6, 0xad, 0x77, 0xaa, 0x37, 0x19, 0x31, 0x6d, 0x57, - 0x7f, 0x29, 0xc1, 0xe2, 0x7a, 0x15, 0xf9, 0xb9, 0xa5, 0xe2, 0xf3, 0xeb, 0x3f, 0x27, 0x5d, 0xac, - 0x02, 0xb8, 0xf7, 0x6d, 0xfe, 0x0f, 0x22, 0x89, 0xe3, 0x5d, 0xcc, 0xf3, 0x6a, 0x8f, 0x1a, 0xe5, - 0x94, 0xfd, 0xad, 0x9a, 0xc2, 0x5d, 0xb5, 0x1b, 0x48, 0xd8, 0x0b, 0x77, 0x9c, 0x27, 0x24, 0x55, - 0xf3, 0x8f, 0x5b, 0x7e, 0x0a, 0x73, 0x35, 0xb4, 0x6c, 0xc7, 0x84, 0xc3, 0x0b, 0x22, 0x57, 0x4d, - 0xff, 0x45, 0x4d, 0x78, 0xa7, 0xd0, 0x7d, 0xcf, 0x74, 0x5c, 0xe8, 0xa6, 0x26, 0x76, 0xda, 0xf1, - 0x4f, 0x75, 0x89, 0xd1, 0x6c, 0x7e, 0x52, 0x8c, 0x6e, 0xa8, 0x6e, 0x4c, 0x5b, 0x54, 0x94, 0x35, - 0x92, 0xec, 0x22, 0x5c, 0xdd, 0x97, 0x41, 0xef, 0x9f, 0x6d, 0xa2, 0x63, 0xaa, 0x22, 0x81, 0xab, - 0xfa, 0x0d, 0x2d, 0xed, 0xe6, 0x45, 0xe4, 0x2a, 0x51, 0x1d, 0xa6, 0x8d, 0x24, 0x99, 0xda, 0xb6, - 0xe3, 0xeb, 0x56, 0xf8, 0x6d, 0xe7, 0xbf, 0x14, 0xfa, 0x41, 0x82, 0x93, 0x28, 0xb0, 0x3f, 0x83, - 0x3a, 0x10, 0x79, 0x18, 0x4f, 0x21, 0xc7, 0xd1, 0x5f, 0x80, 0x77, 0x98, 0x0e, 0x26, 0xdd, 0x36, - 0xc7, 0xc6, 0x6b, 0xd2, 0x42, 0xd8, 0xa1, 0xfc, 0x69, 0x90, 0xa6, 0xea, 0xe6, 0xf2, 0x5b, 0x78, - 0xb7, 0x27, 0xe2, 0x13, 0xc2, 0xe7, 0xdf, 0x37, 0x30, 0x94, 0xaf, 0xbf, 0x88, 0x63, 0x3d, 0xad, - 0xfc, 0xdb, 0xf4, 0x5f, 0x5c, 0x4b, 0x07, 0x36, 0xc2, 0xc2, 0xca, 0xe3, 0x3d, 0xd9, 0x51, 0x88, - 0x37, 0xb5, 0xd6, 0x36, 0x63, 0x42, 0x8b, 0xd3, 0x86, 0xc3, 0xc0, 0x1c, 0x08, 0x2c, 0x5c, 0x93, - 0x21, 0x3e, 0x7a, 0x54, 0x21, 0xa4, 0xbc, 0x78, 0xdc, 0x41, 0x78, 0x18, 0x83, 0xf6, 0x4d, 0x2d, - 0x3a, 0xa1, 0xf3, 0xd2, 0x3e, 0x31, 0x91, 0x6f, 0xf9, 0xd3, 0xd6, 0xe1, 0xef, 0x83, 0xd7, 0x59, - 0xc9, 0xa3, 0x36, 0xcc, 0x26, 0xfd, 0x7c, 0x93, 0x0a, 0x4e, 0xae, 0x45, 0x4b, 0xb0, 0x58, 0xd0, - 0xb0, 0xca, 0x70, 0x35, 0x2f, 0x63, 0x28, 0x9d, 0x5a, 0xc8, 0x02, 0xf9, 0x8b, 0xaa, 0xcf, 0x6d, - 0x8b, 0xbb, 0xb5, 0xf6, 0x44, 0xe4, 0xcb, 0x3d, 0xbe, 0xd2, 0x70, 0x2d, 0xb3, 0xe9, 0x05, 0x6c, - 0xfe, 0x41, 0xa3, 0x05, 0xec, 0xe4, 0xf1, 0x9e, 0x37, 0x04, 0xd1, 0x9a, 0x60, 0xf9, 0x95, 0xc4, - 0x11, 0xb3, 0xbf, 0x17, 0xa4, 0x72, 0x2a, 0x03, 0x2d, 0x9a, 0x2b, 0xed, 0x97, 0xc9, 0x29, 0x05, - 0x23, 0xbb, 0xd2, 0xfe, 0x0b, 0x91, 0x5b, 0x93, 0x3f, 0x93, 0x10, 0x69, 0xcb, 0x92, 0x14, 0x8c, - 0xd4, 0xf3, 0x4f, 0x51, 0xc4, 0x78, 0x52, 0xc1, 0xea, 0x20, 0xa9, 0x16, 0x9b, 0x51, 0xb3, 0x69, - 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 -}; - -/* Valid CMS message with no hash agility attribute */ -unsigned char valid_no_attr[] = { - 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, - 0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x07, 0x01, 0x00, 0x00, 0xa0, 0x82, 0x06, 0xb4, 0x30, 0x82, 0x06, 0xb0, 0x30, 0x82, 0x04, 0x98, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, - 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, - 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, - 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, - 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x18, - 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, - 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, - 0x32, 0x39, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x30, 0x32, - 0x38, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, - 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, - 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, - 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, - 0x01, 0x00, 0xc4, 0x2a, 0x38, 0x4b, 0xdd, 0x1c, 0xc7, 0x39, 0x47, 0xba, 0xbc, 0x5d, 0xd2, 0xcc, - 0x6e, 0x9e, 0x2c, 0x81, 0x26, 0x18, 0x59, 0x18, 0xb8, 0x45, 0x0c, 0xde, 0x5b, 0xbc, 0x25, 0xa4, - 0x78, 0x0b, 0x16, 0x3d, 0x3d, 0x10, 0x34, 0x48, 0xcf, 0x1f, 0x40, 0xaa, 0x4b, 0xb5, 0xbc, 0xf0, - 0x81, 0x5e, 0xa8, 0x72, 0xed, 0x6a, 0x8c, 0xf0, 0x4a, 0x9a, 0x80, 0x09, 0x3b, 0x89, 0xed, 0xad, - 0x2b, 0xb5, 0x5b, 0x0f, 0xe4, 0x3f, 0x6b, 0xc5, 0x15, 0x33, 0x5e, 0xdd, 0xa4, 0xac, 0x2f, 0xa5, - 0x13, 0x0f, 0x3c, 0xfc, 0xd8, 0xca, 0xb8, 0x88, 0x67, 0x75, 0xc4, 0x9a, 0x4c, 0x18, 0x9a, 0x38, - 0x68, 0xaa, 0x4c, 0x94, 0x35, 0xed, 0xa4, 0x0b, 0x80, 0x2b, 0xa9, 0x4d, 0xa4, 0x57, 0x22, 0xfc, - 0xd2, 0xc3, 0x12, 0x0b, 0x8a, 0x3c, 0xd7, 0x6d, 0x8b, 0x47, 0x4f, 0x24, 0xe5, 0xea, 0x1b, 0x03, - 0x78, 0xa2, 0x12, 0x36, 0x3f, 0x92, 0x16, 0x36, 0xff, 0xc5, 0xaf, 0xc3, 0xec, 0x4b, 0x6c, 0x23, - 0x04, 0x1b, 0xa9, 0xce, 0x3a, 0xa1, 0xa5, 0xe0, 0x54, 0x13, 0x43, 0x13, 0x29, 0x95, 0x5b, 0xcb, - 0x97, 0x74, 0x01, 0xbc, 0x3c, 0xb8, 0xa1, 0xb0, 0xf3, 0x3c, 0xfa, 0x21, 0x7a, 0x89, 0x90, 0x2b, - 0x1f, 0x20, 0x3f, 0xc1, 0x22, 0xda, 0x8d, 0xa5, 0x30, 0x57, 0x6d, 0xd4, 0x40, 0x99, 0x08, 0x0d, - 0xef, 0x36, 0x16, 0xa6, 0xec, 0xcf, 0x26, 0x78, 0x7c, 0x77, 0x7e, 0x50, 0x2a, 0xe3, 0xdf, 0x28, - 0xff, 0xd0, 0xc7, 0x0e, 0x8b, 0x6b, 0x56, 0x62, 0x53, 0x37, 0x5a, 0x1a, 0x85, 0x50, 0xec, 0x6a, - 0x6b, 0x2e, 0xd1, 0x35, 0x6e, 0x5d, 0x92, 0x30, 0x39, 0x82, 0x40, 0x7b, 0x6d, 0x89, 0x5b, 0x4d, - 0x30, 0x6d, 0x2e, 0x68, 0x16, 0x24, 0x63, 0x32, 0x24, 0xdc, 0x3e, 0x5b, 0x4a, 0xc4, 0x41, 0xfc, - 0x76, 0x07, 0xe6, 0xa3, 0x1b, 0x18, 0xec, 0x59, 0xed, 0x13, 0x0b, 0x2d, 0xe9, 0x86, 0x89, 0x2c, - 0x0a, 0xb0, 0x19, 0x97, 0x4d, 0x1b, 0xfb, 0xd4, 0xef, 0x54, 0xcd, 0xe5, 0xb2, 0x22, 0x70, 0x3a, - 0x50, 0x03, 0xaa, 0xc0, 0xf8, 0xb4, 0x8e, 0x16, 0xd8, 0x2a, 0xc1, 0xd1, 0x2d, 0xa0, 0x27, 0x59, - 0x63, 0x70, 0xc3, 0x74, 0x14, 0xee, 0xde, 0xa9, 0xd9, 0x73, 0xdb, 0x16, 0x6d, 0xef, 0x7f, 0x50, - 0xb6, 0xd2, 0x54, 0x0d, 0x4d, 0x31, 0x5f, 0x23, 0x2c, 0xfd, 0x8f, 0x67, 0x7c, 0xe9, 0xaa, 0x1c, - 0x29, 0xf5, 0x83, 0x1b, 0x2b, 0x0e, 0x66, 0x0e, 0x5c, 0xfe, 0xc9, 0x38, 0xb0, 0x90, 0xfa, 0x31, - 0x4c, 0xb1, 0xef, 0xea, 0xd0, 0x47, 0x17, 0xde, 0x45, 0xc1, 0x93, 0xef, 0xba, 0xde, 0x9f, 0x69, - 0xc7, 0xa6, 0x14, 0x23, 0xb1, 0x8b, 0xaa, 0xbf, 0x61, 0x37, 0x57, 0x11, 0x6a, 0xb2, 0xf7, 0xec, - 0x52, 0x7e, 0x65, 0x80, 0xff, 0xa1, 0xa8, 0x20, 0x7e, 0x0b, 0xae, 0x21, 0xfa, 0xe8, 0x20, 0x52, - 0x93, 0xc5, 0xe9, 0x39, 0x5b, 0x8e, 0xab, 0xef, 0x86, 0xa6, 0xd8, 0x43, 0x7e, 0xa9, 0x5c, 0x6d, - 0x91, 0xd8, 0x5c, 0xa4, 0x2a, 0xed, 0x26, 0xa8, 0x1b, 0xaa, 0x3b, 0xfa, 0x86, 0x75, 0x37, 0xc6, - 0x70, 0x12, 0x2b, 0x8c, 0x55, 0x96, 0x76, 0x04, 0xf6, 0xe3, 0xf9, 0xe2, 0x0d, 0x2e, 0xe0, 0x23, - 0xdf, 0xfa, 0xe0, 0x9c, 0x11, 0xf9, 0xd4, 0x51, 0x05, 0xed, 0x2b, 0x3f, 0xa3, 0x3f, 0xa2, 0xe6, - 0x30, 0x81, 0x17, 0x00, 0x8f, 0x15, 0x91, 0xfb, 0x21, 0x62, 0xf4, 0xff, 0x93, 0x1a, 0x2e, 0xfe, - 0x1a, 0xcb, 0x93, 0x3d, 0xd4, 0x6e, 0x3a, 0xb8, 0x70, 0xdf, 0x93, 0xb4, 0x02, 0xc4, 0x8c, 0x54, - 0x92, 0xde, 0xa7, 0x32, 0x65, 0x1c, 0x85, 0x95, 0x34, 0xf8, 0x8d, 0x06, 0x5b, 0x7d, 0x72, 0x00, - 0xd8, 0x31, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfe, 0x30, 0x81, 0xfb, 0x30, 0x1d, 0x06, - 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xee, 0x16, 0xde, 0xfd, 0x11, 0xd3, 0x88, 0xfb, - 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, 0x30, 0x81, 0xcb, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xc3, 0x30, 0x81, 0xc0, 0x80, 0x14, 0xee, 0x16, 0xde, 0xfd, - 0x11, 0xd3, 0x88, 0xfb, 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, - 0xa1, 0x81, 0x9c, 0xa4, 0x81, 0x99, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, - 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, - 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, - 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x82, - 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x0c, 0x0f, 0x08, 0x79, - 0x6f, 0x56, 0x21, 0xdf, 0xdd, 0xf5, 0x97, 0x8d, 0xdc, 0x97, 0x06, 0xfb, 0x2e, 0xe0, 0x21, 0x60, - 0xc3, 0x02, 0xf4, 0x41, 0x79, 0x79, 0xc2, 0x23, 0x9a, 0x8a, 0x54, 0x2e, 0x66, 0xab, 0xc0, 0x21, - 0xf6, 0x9f, 0xc5, 0x2e, 0x41, 0xb8, 0xa3, 0x32, 0x9f, 0x3d, 0x4e, 0xf4, 0x83, 0xee, 0xcc, 0x60, - 0xf6, 0x82, 0x3d, 0xb4, 0xa9, 0x9d, 0xcd, 0xa0, 0x02, 0x89, 0xb0, 0x32, 0x1b, 0xb5, 0x7c, 0xf4, - 0x8f, 0xbc, 0x9b, 0x24, 0xc2, 0xe2, 0x81, 0xd6, 0x6f, 0x0e, 0x22, 0x5e, 0x50, 0xd9, 0x5b, 0x2e, - 0x89, 0xbf, 0xa4, 0xfe, 0xa8, 0xc2, 0x9a, 0xf4, 0xec, 0x70, 0x66, 0x01, 0x4b, 0x50, 0x30, 0x97, - 0x0a, 0xcc, 0x9f, 0xac, 0xe4, 0x89, 0x1c, 0x8d, 0x88, 0x0d, 0xdb, 0x21, 0xbd, 0x2f, 0x24, 0x8e, - 0x83, 0xf9, 0xe6, 0x71, 0xed, 0x71, 0x26, 0x31, 0x99, 0x9d, 0x04, 0xeb, 0x34, 0xea, 0x6d, 0x65, - 0xb8, 0x02, 0x83, 0x57, 0x78, 0x36, 0x3a, 0x0b, 0xc7, 0x41, 0x63, 0xb5, 0xf6, 0x1c, 0xd2, 0x01, - 0x86, 0x04, 0x58, 0x40, 0x3e, 0x91, 0x98, 0x39, 0x72, 0x75, 0x11, 0xca, 0x14, 0x73, 0x90, 0x34, - 0x8b, 0x21, 0xa4, 0xd0, 0xba, 0xe7, 0x33, 0x03, 0x22, 0x0f, 0x1a, 0xf7, 0x10, 0x2b, 0x69, 0x4c, - 0x73, 0xef, 0x04, 0x18, 0xf9, 0xe1, 0x11, 0xa8, 0xb8, 0x1b, 0x57, 0x0b, 0x03, 0x10, 0x1c, 0xce, - 0x13, 0xca, 0xe4, 0xde, 0x8c, 0xf4, 0xcf, 0xf5, 0xb7, 0x80, 0x3e, 0xbc, 0x1f, 0x51, 0x9b, 0x20, - 0x8c, 0xb0, 0x2d, 0x67, 0x1c, 0x84, 0x25, 0x4c, 0x8b, 0xd3, 0xa7, 0x09, 0x8e, 0x60, 0xe2, 0x99, - 0x0d, 0x10, 0x12, 0x14, 0xfc, 0x17, 0x62, 0x69, 0xcd, 0xa4, 0x64, 0xf0, 0x7e, 0xba, 0xe0, 0xc9, - 0x51, 0x78, 0xf8, 0xb4, 0x0d, 0x7d, 0xb8, 0xa0, 0xee, 0x9c, 0x9e, 0x84, 0xd5, 0xa4, 0x02, 0xe5, - 0x7a, 0x1c, 0x65, 0xe1, 0x20, 0xfb, 0x4d, 0x61, 0x7a, 0x47, 0x25, 0x06, 0x95, 0x17, 0x62, 0x60, - 0x4b, 0x0b, 0xc6, 0xca, 0xa7, 0x35, 0x8f, 0xd4, 0x63, 0x3e, 0x5e, 0x92, 0x1a, 0x08, 0x7c, 0x6b, - 0x15, 0x41, 0x95, 0x76, 0x7d, 0x39, 0x28, 0xec, 0x3e, 0x1f, 0x49, 0xd5, 0xd5, 0x89, 0xf9, 0x5f, - 0x14, 0x02, 0x2f, 0x27, 0xb0, 0x39, 0xba, 0xf7, 0x91, 0x53, 0x75, 0x77, 0xab, 0x88, 0x40, 0x1d, - 0x77, 0xaf, 0x79, 0xfd, 0xdc, 0xac, 0x99, 0x82, 0xf2, 0x46, 0x05, 0x97, 0x60, 0xef, 0x7b, 0xf5, - 0x34, 0x38, 0xbf, 0xd7, 0x42, 0x3e, 0x8b, 0x5a, 0x4a, 0x0c, 0x22, 0x7e, 0x4d, 0x4e, 0xf6, 0xf7, - 0xcc, 0x6e, 0x31, 0x33, 0x1a, 0x84, 0xbe, 0x07, 0xf7, 0xe8, 0xe2, 0x43, 0x00, 0x54, 0x4a, 0x38, - 0xda, 0x98, 0xe3, 0x84, 0xb2, 0xd0, 0x76, 0x79, 0x94, 0x11, 0x7e, 0xa8, 0xca, 0x56, 0xa0, 0xfd, - 0x4b, 0xba, 0x7c, 0x0a, 0xa4, 0x34, 0x01, 0xad, 0xf4, 0x37, 0x4f, 0x38, 0x33, 0x9f, 0x71, 0xdc, - 0xc4, 0x4c, 0x96, 0xb0, 0x8a, 0x86, 0xe5, 0x8d, 0xd2, 0x44, 0xe3, 0x18, 0xcb, 0x81, 0xa6, 0x7c, - 0xaf, 0x8e, 0xfb, 0x41, 0x6e, 0xc5, 0x82, 0xf0, 0x51, 0xb7, 0x0f, 0x23, 0x9b, 0x77, 0xed, 0x9a, - 0x06, 0x6b, 0x77, 0x7c, 0x8e, 0xc4, 0xdf, 0x50, 0xa0, 0xd2, 0x81, 0x3e, 0x65, 0xbe, 0xe5, 0x51, - 0x79, 0x93, 0x24, 0x8e, 0xb3, 0xb5, 0x25, 0x48, 0x76, 0x0e, 0x75, 0x94, 0xef, 0x9a, 0x9d, 0xc7, - 0x95, 0x08, 0xca, 0x35, 0x6b, 0x73, 0xbc, 0x4b, 0x93, 0x7a, 0x93, 0x55, 0x2d, 0xe4, 0x5f, 0xcf, - 0x11, 0x31, 0x94, 0xb2, 0x5a, 0x05, 0x80, 0xd7, 0x59, 0x79, 0x14, 0x8a, 0x2a, 0xb9, 0xd7, 0x3d, - 0x33, 0x69, 0xa9, 0xab, 0xaa, 0xb8, 0x4c, 0x73, 0xb6, 0x71, 0x2c, 0x6f, 0x31, 0x82, 0x03, 0x3b, - 0x30, 0x82, 0x03, 0x37, 0x02, 0x01, 0x01, 0x30, 0x81, 0xa4, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, - 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, - 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, - 0x6e, 0x65, 0x72, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0d, - 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x69, 0x30, - 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x31, 0x30, 0x34, - 0x30, 0x31, 0x35, 0x36, 0x34, 0x30, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x30, 0x9e, 0x11, 0x91, 0x83, 0x14, 0xd8, 0xb9, - 0xd6, 0x24, 0x8e, 0x04, 0x7e, 0x31, 0xa7, 0x66, 0xf7, 0x3c, 0x96, 0xc6, 0x23, 0x60, 0x2e, 0xec, - 0x9e, 0x0c, 0xda, 0xab, 0x25, 0x58, 0x02, 0xf2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0xbc, 0x5a, 0x74, 0xac, 0x24, - 0x13, 0xa5, 0xa3, 0xfb, 0x61, 0xfb, 0x19, 0x7a, 0x3f, 0x7b, 0x46, 0x5a, 0xcd, 0x8a, 0x92, 0x23, - 0xeb, 0xd0, 0xdf, 0xf2, 0x05, 0xbe, 0x02, 0xf9, 0xd5, 0x81, 0xca, 0x16, 0xf9, 0xd9, 0x63, 0x9e, - 0x19, 0xb8, 0xea, 0x1d, 0x51, 0x2c, 0xfc, 0x65, 0x0c, 0x67, 0x31, 0x5d, 0xa2, 0x87, 0x40, 0xa2, - 0x58, 0x57, 0x35, 0xe1, 0xa2, 0xc8, 0x25, 0xe4, 0x79, 0xd1, 0xc2, 0x76, 0x26, 0x20, 0x11, 0x76, - 0x38, 0xc8, 0xa1, 0x08, 0x98, 0x7c, 0x28, 0x8a, 0x14, 0x23, 0x89, 0xfa, 0xe6, 0x55, 0xaf, 0x47, - 0x1f, 0xe8, 0x5c, 0xc4, 0x0b, 0x88, 0x27, 0x75, 0xf5, 0x2d, 0x2c, 0x63, 0x63, 0x7b, 0xd3, 0x2b, - 0xd2, 0xb1, 0x4d, 0xf5, 0xd3, 0xa9, 0xdc, 0xc1, 0x34, 0x9d, 0xb8, 0x44, 0xae, 0xa3, 0x41, 0xd7, - 0x1e, 0x02, 0xff, 0x06, 0x3d, 0x8b, 0x3b, 0x01, 0xc6, 0xa9, 0x0f, 0x7a, 0x59, 0x03, 0x05, 0x2a, - 0xcf, 0x19, 0xc1, 0xd2, 0xea, 0x30, 0x3f, 0xbd, 0x83, 0x80, 0x26, 0xd7, 0x73, 0x32, 0x00, 0x8d, - 0x4f, 0x69, 0xaa, 0xf0, 0x39, 0x3f, 0xae, 0x46, 0xfc, 0x19, 0x7e, 0x62, 0xd2, 0xc8, 0x59, 0xa2, - 0xd1, 0x23, 0xa2, 0xab, 0xdd, 0x5b, 0xbc, 0xa9, 0x4d, 0x8c, 0x3a, 0xa4, 0x9d, 0x8e, 0x80, 0x0c, - 0x2b, 0x2d, 0x26, 0x27, 0xb7, 0xf2, 0xb9, 0x19, 0xc5, 0x8e, 0x17, 0x44, 0xb2, 0x19, 0x29, 0x3b, - 0x25, 0x7e, 0x76, 0xf8, 0x97, 0x85, 0xbc, 0x78, 0xa4, 0x41, 0xcb, 0x10, 0xed, 0xd7, 0x8c, 0x4c, - 0x56, 0x44, 0xfc, 0x7c, 0xa8, 0x98, 0xff, 0xa5, 0xef, 0x21, 0xe4, 0xc2, 0x2b, 0xaf, 0xfb, 0xb2, - 0xcb, 0x4c, 0x63, 0x19, 0x53, 0xae, 0xc4, 0xbc, 0x44, 0x31, 0xcb, 0x06, 0x2f, 0x01, 0x2b, 0x6b, - 0x7e, 0xd8, 0x24, 0x76, 0x16, 0x74, 0xa5, 0xb2, 0x46, 0xff, 0x14, 0xde, 0xc8, 0xe5, 0xfc, 0xeb, - 0xfa, 0xb8, 0xc2, 0x39, 0x9d, 0xf6, 0xdd, 0xbb, 0xba, 0x7d, 0x2d, 0x49, 0x4c, 0x7d, 0x87, 0xe2, - 0x0a, 0xb7, 0x52, 0xb5, 0x3d, 0x9d, 0x02, 0xf2, 0x04, 0x3d, 0x9b, 0x8b, 0x04, 0xe8, 0x84, 0x50, - 0x19, 0xb7, 0xfa, 0x4f, 0x9f, 0xa6, 0x00, 0x06, 0x2a, 0x44, 0xb2, 0x58, 0x91, 0x2f, 0xde, 0xd6, - 0x25, 0xcc, 0xd5, 0x68, 0x04, 0x51, 0xb1, 0x0f, 0x08, 0x41, 0xdd, 0xea, 0x16, 0x70, 0xbd, 0x5a, - 0xbc, 0x05, 0x60, 0xbc, 0xd4, 0x67, 0x62, 0xe2, 0xc3, 0xc0, 0x79, 0xdf, 0x49, 0xd7, 0x52, 0x62, - 0xde, 0xce, 0x68, 0x5c, 0x32, 0x9b, 0xd3, 0xb8, 0xef, 0x62, 0x7b, 0x4b, 0x0e, 0x15, 0xae, 0x92, - 0xfb, 0x06, 0x36, 0xb9, 0x05, 0x72, 0x2f, 0x01, 0x55, 0x70, 0x2b, 0x09, 0x54, 0xe1, 0x70, 0x15, - 0xab, 0x24, 0xcb, 0x07, 0x4c, 0x7e, 0xde, 0x38, 0xb2, 0x03, 0x56, 0xdb, 0x2f, 0x8c, 0x3b, 0xe5, - 0x5e, 0x1a, 0xbb, 0x90, 0x08, 0x55, 0xb2, 0x3d, 0xd9, 0x6f, 0xe8, 0x81, 0x08, 0x04, 0x5e, 0x82, - 0x84, 0x7e, 0x9c, 0x3f, 0x5a, 0x66, 0x6f, 0x6c, 0xc6, 0x98, 0x82, 0x27, 0xb6, 0x49, 0x7b, 0x14, - 0x07, 0x9d, 0x20, 0x61, 0x9d, 0xd9, 0x3d, 0xd0, 0x71, 0x0c, 0x72, 0x82, 0x50, 0xac, 0x61, 0xcd, - 0xc5, 0xc6, 0xc9, 0x90, 0xe2, 0x92, 0x5b, 0x02, 0x73, 0xda, 0x98, 0x2e, 0x21, 0x1e, 0x66, 0x79, - 0x83, 0x2e, 0x1d, 0x66, 0x0e, 0x2b, 0x6d, 0x42, 0x7d, 0xf4, 0x0a, 0xd3, 0xa1, 0x9b, 0x7f, 0x61, - 0xa7, 0x13, 0x3a, 0xa4, 0x6e, 0x0d, 0x0b, 0xbf, 0x42, 0x32, 0xf7, 0xca, 0x0e, 0x96, 0x0a, 0xcb, - 0x9a, 0x0a, 0x6a, 0x24, 0x8c, 0x43, 0x76, 0x0e, 0xa8, 0x71, 0xcd, 0x3f, 0xc4, 0x85, 0x46, 0x50, - 0xb9, 0x65, 0x43, 0x49, 0xae, 0x31, 0x25, 0x76, 0x4b, 0xfb, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00 -}; - -unsigned char _V2_valid_message[] = { - 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, - 0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x07, 0x01, 0x00, 0x00, 0xa0, 0x82, 0x06, 0xb4, 0x30, 0x82, 0x06, 0xb0, 0x30, 0x82, 0x04, 0x98, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, - 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, - 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, - 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, - 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x18, - 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, - 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, - 0x32, 0x39, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x30, 0x32, - 0x38, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, - 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, - 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, - 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, - 0x01, 0x00, 0xc4, 0x2a, 0x38, 0x4b, 0xdd, 0x1c, 0xc7, 0x39, 0x47, 0xba, 0xbc, 0x5d, 0xd2, 0xcc, - 0x6e, 0x9e, 0x2c, 0x81, 0x26, 0x18, 0x59, 0x18, 0xb8, 0x45, 0x0c, 0xde, 0x5b, 0xbc, 0x25, 0xa4, - 0x78, 0x0b, 0x16, 0x3d, 0x3d, 0x10, 0x34, 0x48, 0xcf, 0x1f, 0x40, 0xaa, 0x4b, 0xb5, 0xbc, 0xf0, - 0x81, 0x5e, 0xa8, 0x72, 0xed, 0x6a, 0x8c, 0xf0, 0x4a, 0x9a, 0x80, 0x09, 0x3b, 0x89, 0xed, 0xad, - 0x2b, 0xb5, 0x5b, 0x0f, 0xe4, 0x3f, 0x6b, 0xc5, 0x15, 0x33, 0x5e, 0xdd, 0xa4, 0xac, 0x2f, 0xa5, - 0x13, 0x0f, 0x3c, 0xfc, 0xd8, 0xca, 0xb8, 0x88, 0x67, 0x75, 0xc4, 0x9a, 0x4c, 0x18, 0x9a, 0x38, - 0x68, 0xaa, 0x4c, 0x94, 0x35, 0xed, 0xa4, 0x0b, 0x80, 0x2b, 0xa9, 0x4d, 0xa4, 0x57, 0x22, 0xfc, - 0xd2, 0xc3, 0x12, 0x0b, 0x8a, 0x3c, 0xd7, 0x6d, 0x8b, 0x47, 0x4f, 0x24, 0xe5, 0xea, 0x1b, 0x03, - 0x78, 0xa2, 0x12, 0x36, 0x3f, 0x92, 0x16, 0x36, 0xff, 0xc5, 0xaf, 0xc3, 0xec, 0x4b, 0x6c, 0x23, - 0x04, 0x1b, 0xa9, 0xce, 0x3a, 0xa1, 0xa5, 0xe0, 0x54, 0x13, 0x43, 0x13, 0x29, 0x95, 0x5b, 0xcb, - 0x97, 0x74, 0x01, 0xbc, 0x3c, 0xb8, 0xa1, 0xb0, 0xf3, 0x3c, 0xfa, 0x21, 0x7a, 0x89, 0x90, 0x2b, - 0x1f, 0x20, 0x3f, 0xc1, 0x22, 0xda, 0x8d, 0xa5, 0x30, 0x57, 0x6d, 0xd4, 0x40, 0x99, 0x08, 0x0d, - 0xef, 0x36, 0x16, 0xa6, 0xec, 0xcf, 0x26, 0x78, 0x7c, 0x77, 0x7e, 0x50, 0x2a, 0xe3, 0xdf, 0x28, - 0xff, 0xd0, 0xc7, 0x0e, 0x8b, 0x6b, 0x56, 0x62, 0x53, 0x37, 0x5a, 0x1a, 0x85, 0x50, 0xec, 0x6a, - 0x6b, 0x2e, 0xd1, 0x35, 0x6e, 0x5d, 0x92, 0x30, 0x39, 0x82, 0x40, 0x7b, 0x6d, 0x89, 0x5b, 0x4d, - 0x30, 0x6d, 0x2e, 0x68, 0x16, 0x24, 0x63, 0x32, 0x24, 0xdc, 0x3e, 0x5b, 0x4a, 0xc4, 0x41, 0xfc, - 0x76, 0x07, 0xe6, 0xa3, 0x1b, 0x18, 0xec, 0x59, 0xed, 0x13, 0x0b, 0x2d, 0xe9, 0x86, 0x89, 0x2c, - 0x0a, 0xb0, 0x19, 0x97, 0x4d, 0x1b, 0xfb, 0xd4, 0xef, 0x54, 0xcd, 0xe5, 0xb2, 0x22, 0x70, 0x3a, - 0x50, 0x03, 0xaa, 0xc0, 0xf8, 0xb4, 0x8e, 0x16, 0xd8, 0x2a, 0xc1, 0xd1, 0x2d, 0xa0, 0x27, 0x59, - 0x63, 0x70, 0xc3, 0x74, 0x14, 0xee, 0xde, 0xa9, 0xd9, 0x73, 0xdb, 0x16, 0x6d, 0xef, 0x7f, 0x50, - 0xb6, 0xd2, 0x54, 0x0d, 0x4d, 0x31, 0x5f, 0x23, 0x2c, 0xfd, 0x8f, 0x67, 0x7c, 0xe9, 0xaa, 0x1c, - 0x29, 0xf5, 0x83, 0x1b, 0x2b, 0x0e, 0x66, 0x0e, 0x5c, 0xfe, 0xc9, 0x38, 0xb0, 0x90, 0xfa, 0x31, - 0x4c, 0xb1, 0xef, 0xea, 0xd0, 0x47, 0x17, 0xde, 0x45, 0xc1, 0x93, 0xef, 0xba, 0xde, 0x9f, 0x69, - 0xc7, 0xa6, 0x14, 0x23, 0xb1, 0x8b, 0xaa, 0xbf, 0x61, 0x37, 0x57, 0x11, 0x6a, 0xb2, 0xf7, 0xec, - 0x52, 0x7e, 0x65, 0x80, 0xff, 0xa1, 0xa8, 0x20, 0x7e, 0x0b, 0xae, 0x21, 0xfa, 0xe8, 0x20, 0x52, - 0x93, 0xc5, 0xe9, 0x39, 0x5b, 0x8e, 0xab, 0xef, 0x86, 0xa6, 0xd8, 0x43, 0x7e, 0xa9, 0x5c, 0x6d, - 0x91, 0xd8, 0x5c, 0xa4, 0x2a, 0xed, 0x26, 0xa8, 0x1b, 0xaa, 0x3b, 0xfa, 0x86, 0x75, 0x37, 0xc6, - 0x70, 0x12, 0x2b, 0x8c, 0x55, 0x96, 0x76, 0x04, 0xf6, 0xe3, 0xf9, 0xe2, 0x0d, 0x2e, 0xe0, 0x23, - 0xdf, 0xfa, 0xe0, 0x9c, 0x11, 0xf9, 0xd4, 0x51, 0x05, 0xed, 0x2b, 0x3f, 0xa3, 0x3f, 0xa2, 0xe6, - 0x30, 0x81, 0x17, 0x00, 0x8f, 0x15, 0x91, 0xfb, 0x21, 0x62, 0xf4, 0xff, 0x93, 0x1a, 0x2e, 0xfe, - 0x1a, 0xcb, 0x93, 0x3d, 0xd4, 0x6e, 0x3a, 0xb8, 0x70, 0xdf, 0x93, 0xb4, 0x02, 0xc4, 0x8c, 0x54, - 0x92, 0xde, 0xa7, 0x32, 0x65, 0x1c, 0x85, 0x95, 0x34, 0xf8, 0x8d, 0x06, 0x5b, 0x7d, 0x72, 0x00, - 0xd8, 0x31, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfe, 0x30, 0x81, 0xfb, 0x30, 0x1d, 0x06, - 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xee, 0x16, 0xde, 0xfd, 0x11, 0xd3, 0x88, 0xfb, - 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, 0x30, 0x81, 0xcb, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xc3, 0x30, 0x81, 0xc0, 0x80, 0x14, 0xee, 0x16, 0xde, 0xfd, - 0x11, 0xd3, 0x88, 0xfb, 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, - 0xa1, 0x81, 0x9c, 0xa4, 0x81, 0x99, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, - 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, - 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, - 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x82, - 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x0c, 0x0f, 0x08, 0x79, - 0x6f, 0x56, 0x21, 0xdf, 0xdd, 0xf5, 0x97, 0x8d, 0xdc, 0x97, 0x06, 0xfb, 0x2e, 0xe0, 0x21, 0x60, - 0xc3, 0x02, 0xf4, 0x41, 0x79, 0x79, 0xc2, 0x23, 0x9a, 0x8a, 0x54, 0x2e, 0x66, 0xab, 0xc0, 0x21, - 0xf6, 0x9f, 0xc5, 0x2e, 0x41, 0xb8, 0xa3, 0x32, 0x9f, 0x3d, 0x4e, 0xf4, 0x83, 0xee, 0xcc, 0x60, - 0xf6, 0x82, 0x3d, 0xb4, 0xa9, 0x9d, 0xcd, 0xa0, 0x02, 0x89, 0xb0, 0x32, 0x1b, 0xb5, 0x7c, 0xf4, - 0x8f, 0xbc, 0x9b, 0x24, 0xc2, 0xe2, 0x81, 0xd6, 0x6f, 0x0e, 0x22, 0x5e, 0x50, 0xd9, 0x5b, 0x2e, - 0x89, 0xbf, 0xa4, 0xfe, 0xa8, 0xc2, 0x9a, 0xf4, 0xec, 0x70, 0x66, 0x01, 0x4b, 0x50, 0x30, 0x97, - 0x0a, 0xcc, 0x9f, 0xac, 0xe4, 0x89, 0x1c, 0x8d, 0x88, 0x0d, 0xdb, 0x21, 0xbd, 0x2f, 0x24, 0x8e, - 0x83, 0xf9, 0xe6, 0x71, 0xed, 0x71, 0x26, 0x31, 0x99, 0x9d, 0x04, 0xeb, 0x34, 0xea, 0x6d, 0x65, - 0xb8, 0x02, 0x83, 0x57, 0x78, 0x36, 0x3a, 0x0b, 0xc7, 0x41, 0x63, 0xb5, 0xf6, 0x1c, 0xd2, 0x01, - 0x86, 0x04, 0x58, 0x40, 0x3e, 0x91, 0x98, 0x39, 0x72, 0x75, 0x11, 0xca, 0x14, 0x73, 0x90, 0x34, - 0x8b, 0x21, 0xa4, 0xd0, 0xba, 0xe7, 0x33, 0x03, 0x22, 0x0f, 0x1a, 0xf7, 0x10, 0x2b, 0x69, 0x4c, - 0x73, 0xef, 0x04, 0x18, 0xf9, 0xe1, 0x11, 0xa8, 0xb8, 0x1b, 0x57, 0x0b, 0x03, 0x10, 0x1c, 0xce, - 0x13, 0xca, 0xe4, 0xde, 0x8c, 0xf4, 0xcf, 0xf5, 0xb7, 0x80, 0x3e, 0xbc, 0x1f, 0x51, 0x9b, 0x20, - 0x8c, 0xb0, 0x2d, 0x67, 0x1c, 0x84, 0x25, 0x4c, 0x8b, 0xd3, 0xa7, 0x09, 0x8e, 0x60, 0xe2, 0x99, - 0x0d, 0x10, 0x12, 0x14, 0xfc, 0x17, 0x62, 0x69, 0xcd, 0xa4, 0x64, 0xf0, 0x7e, 0xba, 0xe0, 0xc9, - 0x51, 0x78, 0xf8, 0xb4, 0x0d, 0x7d, 0xb8, 0xa0, 0xee, 0x9c, 0x9e, 0x84, 0xd5, 0xa4, 0x02, 0xe5, - 0x7a, 0x1c, 0x65, 0xe1, 0x20, 0xfb, 0x4d, 0x61, 0x7a, 0x47, 0x25, 0x06, 0x95, 0x17, 0x62, 0x60, - 0x4b, 0x0b, 0xc6, 0xca, 0xa7, 0x35, 0x8f, 0xd4, 0x63, 0x3e, 0x5e, 0x92, 0x1a, 0x08, 0x7c, 0x6b, - 0x15, 0x41, 0x95, 0x76, 0x7d, 0x39, 0x28, 0xec, 0x3e, 0x1f, 0x49, 0xd5, 0xd5, 0x89, 0xf9, 0x5f, - 0x14, 0x02, 0x2f, 0x27, 0xb0, 0x39, 0xba, 0xf7, 0x91, 0x53, 0x75, 0x77, 0xab, 0x88, 0x40, 0x1d, - 0x77, 0xaf, 0x79, 0xfd, 0xdc, 0xac, 0x99, 0x82, 0xf2, 0x46, 0x05, 0x97, 0x60, 0xef, 0x7b, 0xf5, - 0x34, 0x38, 0xbf, 0xd7, 0x42, 0x3e, 0x8b, 0x5a, 0x4a, 0x0c, 0x22, 0x7e, 0x4d, 0x4e, 0xf6, 0xf7, - 0xcc, 0x6e, 0x31, 0x33, 0x1a, 0x84, 0xbe, 0x07, 0xf7, 0xe8, 0xe2, 0x43, 0x00, 0x54, 0x4a, 0x38, - 0xda, 0x98, 0xe3, 0x84, 0xb2, 0xd0, 0x76, 0x79, 0x94, 0x11, 0x7e, 0xa8, 0xca, 0x56, 0xa0, 0xfd, - 0x4b, 0xba, 0x7c, 0x0a, 0xa4, 0x34, 0x01, 0xad, 0xf4, 0x37, 0x4f, 0x38, 0x33, 0x9f, 0x71, 0xdc, - 0xc4, 0x4c, 0x96, 0xb0, 0x8a, 0x86, 0xe5, 0x8d, 0xd2, 0x44, 0xe3, 0x18, 0xcb, 0x81, 0xa6, 0x7c, - 0xaf, 0x8e, 0xfb, 0x41, 0x6e, 0xc5, 0x82, 0xf0, 0x51, 0xb7, 0x0f, 0x23, 0x9b, 0x77, 0xed, 0x9a, - 0x06, 0x6b, 0x77, 0x7c, 0x8e, 0xc4, 0xdf, 0x50, 0xa0, 0xd2, 0x81, 0x3e, 0x65, 0xbe, 0xe5, 0x51, - 0x79, 0x93, 0x24, 0x8e, 0xb3, 0xb5, 0x25, 0x48, 0x76, 0x0e, 0x75, 0x94, 0xef, 0x9a, 0x9d, 0xc7, - 0x95, 0x08, 0xca, 0x35, 0x6b, 0x73, 0xbc, 0x4b, 0x93, 0x7a, 0x93, 0x55, 0x2d, 0xe4, 0x5f, 0xcf, - 0x11, 0x31, 0x94, 0xb2, 0x5a, 0x05, 0x80, 0xd7, 0x59, 0x79, 0x14, 0x8a, 0x2a, 0xb9, 0xd7, 0x3d, - 0x33, 0x69, 0xa9, 0xab, 0xaa, 0xb8, 0x4c, 0x73, 0xb6, 0x71, 0x2c, 0x6f, 0x31, 0x82, 0x03, 0x99, - 0x30, 0x82, 0x03, 0x95, 0x02, 0x01, 0x01, 0x30, 0x81, 0xa4, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, - 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, - 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 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, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, - 0x6e, 0x65, 0x72, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0d, - 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x81, 0xc6, - 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x30, 0x32, - 0x36, 0x30, 0x38, 0x34, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x30, 0x9e, 0x11, 0x91, 0x83, 0x14, 0xd8, - 0xb9, 0xd6, 0x24, 0x8e, 0x04, 0x7e, 0x31, 0xa7, 0x66, 0xf7, 0x3c, 0x96, 0xc6, 0x23, 0x60, 0x2e, - 0xec, 0x9e, 0x0c, 0xda, 0xab, 0x25, 0x58, 0x02, 0xf2, 0x30, 0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x63, 0x64, 0x09, 0x02, 0x31, 0x4e, 0x30, 0x2d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x65, 0x03, 0x04, 0x02, 0x01, 0x04, 0x20, 0xfc, 0x9d, 0x6f, 0x8e, 0x8b, 0xe2, 0x3d, 0x1d, 0x41, - 0xbf, 0xe6, 0xd1, 0x7a, 0xc9, 0x3f, 0xc9, 0x4d, 0xdd, 0x38, 0x35, 0xbd, 0xdf, 0x98, 0x95, 0x0a, - 0x00, 0xc6, 0x6d, 0x30, 0xe2, 0x37, 0x3b, 0x30, 0x1d, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, - 0x04, 0x14, 0x28, 0x4f, 0x7f, 0xf5, 0xf8, 0x14, 0x80, 0xa6, 0x6b, 0x37, 0x44, 0xeb, 0xed, 0x1e, - 0xf1, 0x3d, 0x35, 0x4e, 0x02, 0x21, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x7c, 0x31, 0x1c, 0x96, 0xbd, 0x0a, 0xe5, - 0x47, 0xab, 0xa0, 0xb4, 0x29, 0x0f, 0x3e, 0xe7, 0x7a, 0x81, 0x87, 0x7e, 0x04, 0x30, 0xf3, 0x95, - 0xe7, 0x54, 0x68, 0xe9, 0x97, 0xae, 0xdc, 0x5a, 0x5d, 0x52, 0xc8, 0x82, 0x27, 0x3b, 0x0a, 0x7c, - 0xe1, 0x69, 0x2f, 0x46, 0x8d, 0xca, 0x77, 0xf3, 0xbf, 0x68, 0xd3, 0xda, 0xcb, 0xb3, 0x11, 0x93, - 0x81, 0x37, 0x22, 0x42, 0xbd, 0x6a, 0x55, 0x02, 0xe7, 0x85, 0x4c, 0x09, 0x5a, 0x02, 0x73, 0x98, - 0xdd, 0x7c, 0x03, 0x00, 0x53, 0xd2, 0x2e, 0x0a, 0x6f, 0x51, 0x8e, 0x95, 0x24, 0xdd, 0x32, 0x9c, - 0x4a, 0x22, 0x38, 0x7f, 0x65, 0x49, 0x17, 0xeb, 0x43, 0x0b, 0xbe, 0x8d, 0x14, 0xdc, 0xde, 0x48, - 0x74, 0x16, 0xbf, 0xe8, 0xed, 0x34, 0x67, 0x62, 0xca, 0x64, 0x57, 0xc4, 0x61, 0xf7, 0xf7, 0xfb, - 0xf2, 0xd0, 0xd1, 0xfd, 0x2e, 0x05, 0xe7, 0xd7, 0x99, 0x75, 0xa8, 0x76, 0x4e, 0xd4, 0x22, 0x67, - 0x2d, 0x34, 0xf6, 0x71, 0x48, 0x4f, 0x78, 0x8e, 0xe1, 0xb9, 0x55, 0x4d, 0x55, 0x87, 0x08, 0xc9, - 0xab, 0xbd, 0xb8, 0x87, 0x2c, 0x27, 0xef, 0x89, 0x93, 0x9c, 0xc0, 0xc1, 0xec, 0x89, 0x0f, 0xc2, - 0xe3, 0x55, 0x6a, 0x1d, 0xd9, 0x96, 0x1d, 0xa4, 0xdf, 0x50, 0x3d, 0x36, 0x25, 0x3e, 0xd4, 0x3e, - 0x1f, 0x44, 0x97, 0xe0, 0x46, 0xe7, 0xb7, 0x81, 0x7d, 0xc3, 0xd5, 0x36, 0xe7, 0x04, 0x34, 0xab, - 0x60, 0x27, 0xc9, 0x00, 0xdd, 0xfa, 0x7c, 0x32, 0x90, 0xa1, 0x62, 0xe4, 0x51, 0x8f, 0x54, 0x81, - 0xa6, 0x5c, 0xcd, 0xaf, 0x3b, 0xb7, 0x12, 0xa6, 0x87, 0x0a, 0x36, 0x5d, 0xc9, 0x77, 0xc3, 0x50, - 0xc6, 0x97, 0x14, 0x43, 0x36, 0x20, 0x6f, 0x40, 0xb3, 0x1f, 0x50, 0x87, 0x24, 0x47, 0x79, 0x93, - 0x9a, 0xc1, 0x61, 0x83, 0xae, 0xc8, 0x00, 0x56, 0x3c, 0x5b, 0x5f, 0xbb, 0x9b, 0xdf, 0x75, 0xea, - 0xc2, 0x3d, 0xf1, 0xd7, 0x26, 0xe5, 0x6b, 0xa1, 0x75, 0x01, 0x0a, 0x3f, 0xae, 0x43, 0x37, 0xdd, - 0xbf, 0x7a, 0x83, 0xa1, 0xb6, 0xc2, 0xb7, 0x2b, 0xda, 0x99, 0xa6, 0x75, 0xb8, 0xc6, 0xf0, 0xc4, - 0x6b, 0x6a, 0xe4, 0xda, 0xac, 0xab, 0x7c, 0xef, 0x6f, 0x7c, 0x73, 0xca, 0x22, 0x33, 0xdd, 0xee, - 0x05, 0xfc, 0x05, 0x90, 0xc5, 0x3f, 0xdd, 0xa6, 0x6f, 0x5b, 0x2d, 0xaf, 0x99, 0x89, 0x93, 0xf0, - 0xfa, 0xb0, 0x8e, 0xcf, 0x39, 0xf1, 0x03, 0xfe, 0x0c, 0x8a, 0x6d, 0x30, 0x6c, 0x2b, 0x67, 0x84, - 0x60, 0x2d, 0x98, 0x80, 0x6c, 0xa7, 0x3e, 0x44, 0xda, 0x44, 0x42, 0x22, 0x7d, 0xcc, 0x43, 0x1c, - 0x7a, 0x89, 0x8c, 0xa0, 0x07, 0xd0, 0x08, 0x45, 0xe0, 0x18, 0x6b, 0x58, 0xb1, 0x66, 0x49, 0x97, - 0xdd, 0xde, 0xa2, 0x73, 0xaf, 0x55, 0xdc, 0x9f, 0xe6, 0x82, 0x67, 0xdf, 0x14, 0x29, 0x90, 0x1a, - 0x00, 0xa8, 0x0a, 0x59, 0xa0, 0xef, 0x97, 0x3d, 0x09, 0x54, 0x0c, 0xe4, 0xa8, 0x3b, 0xdd, 0x08, - 0xb0, 0x9e, 0x48, 0x93, 0xa7, 0xea, 0xaa, 0xe2, 0x55, 0xca, 0x1b, 0xe8, 0xb0, 0x25, 0xa4, 0xf4, - 0x79, 0xad, 0x03, 0xe1, 0xa3, 0xb9, 0x9a, 0x27, 0x12, 0xe5, 0xe8, 0x08, 0x28, 0x36, 0xb2, 0x93, - 0x3a, 0xf8, 0x45, 0x38, 0xea, 0xd7, 0x2f, 0xa7, 0x37, 0xd1, 0xcf, 0x35, 0xef, 0xaf, 0x51, 0x76, - 0xc3, 0xf9, 0x9a, 0xc8, 0x7c, 0x17, 0x00, 0x48, 0xa0, 0x16, 0x10, 0x1c, 0x3f, 0xeb, 0xca, 0xa0, - 0xb5, 0xb7, 0x0b, 0xc1, 0xb8, 0xcf, 0x3a, 0xbd, 0xeb, 0xab, 0x1a, 0xf7, 0x00, 0x78, 0x34, 0xbd, - 0xe0, 0xfd, 0xc4, 0x8e, 0x51, 0x2e, 0x2e, 0x45, 0x18, 0x5e, 0x87, 0x33, 0xbb, 0x26, 0x71, 0x3f, - 0xad, 0x79, 0xc5, 0x60, 0x9c, 0xda, 0xc3, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -#endif /* cms_hashagility_test_h */ diff --git a/OSX/libsecurity_cms/regressions/cms-hashagility-test.m b/OSX/libsecurity_cms/regressions/cms-hashagility-test.m deleted file mode 100644 index 7657edc7..00000000 --- a/OSX/libsecurity_cms/regressions/cms-hashagility-test.m +++ /dev/null @@ -1,422 +0,0 @@ -/* - * Copyright (c) 2015-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cms-hashagility-test.h" - -#define TMP_KEYCHAIN_PATH "/tmp/cms_signer.keychain" - -/* encode test */ -static void encode_test(void) -{ - CMSEncoderRef encoder = NULL; - CFDataRef attributeData = NULL, message = NULL, p12Data = NULL; - CFArrayRef imported_items = NULL; - SecIdentityRef identity = NULL; - SecKeychainRef keychain = NULL; - SecExternalFormat sef = kSecFormatPKCS12; - SecItemImportExportKeyParameters keyParams = { - .passphrase = CFSTR("password") - }; - - /* Create encoder */ - ok_status(CMSEncoderCreate(&encoder), "Create CMS encoder"); - ok_status(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), - "Set digest algorithm to SHA256"); - - /* Load identity and set as signer */ - unlink(TMP_KEYCHAIN_PATH); - ok_status(SecKeychainCreate(TMP_KEYCHAIN_PATH, 8, "password", false, NULL, &keychain), - "Create keychain for identity"); - ok(p12Data = CFDataCreate(NULL, signing_identity_p12, sizeof(signing_identity_p12)), - "Create p12 data"); - ok_status(SecItemImport(p12Data, NULL, &sef, NULL, 0, &keyParams, keychain, &imported_items), - "Import identity"); - is(CFArrayGetCount(imported_items),1,"Imported 1 items"); - is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items, 0)), SecIdentityGetTypeID(), - "Got back an identity"); - ok(identity = (SecIdentityRef) CFRetainSafe(CFArrayGetValueAtIndex(imported_items, 0)), - "Retrieve identity"); - ok_status(CMSEncoderAddSigners(encoder, identity), "Set Signer identity"); - - /* Add signing time attribute for 3 November 2015 */ - ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), - "Set signing time flag"); - ok_status(CMSEncoderSetSigningTime(encoder, 468295000.0), "Set Signing time"); - - /* Add hash agility attribute */ - ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgility), - "Set hash agility flag"); - ok(attributeData = CFDataCreate(NULL, attribute, sizeof(attribute)), - "Create atttribute object"); - ok_status(CMSEncoderSetAppleCodesigningHashAgility(encoder, attributeData), - "Set hash agility data"); - - /* Load content */ - ok_status(CMSEncoderSetHasDetachedContent(encoder, true), "Set detached content"); - ok_status(CMSEncoderUpdateContent(encoder, content, sizeof(content)), "Set content"); - - /* output cms message */ - ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); - - /* decode message */ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL; - isnt(message, NULL, "Encoded message exists"); - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), CFDataGetLength(message)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Cleanup */ - ok_status(SecKeychainDelete(keychain), "Delete temporary keychain"); - - CFReleaseNull(encoder); - CFReleaseNull(keychain); - CFReleaseNull(p12Data); - CFReleaseNull(imported_items); - CFReleaseNull(identity); - CFReleaseNull(attributeData); - CFReleaseNull(message); - CFReleaseNull(decoder); - CFReleaseNull(contentData); -} - -static void decode_positive_test(void) -{ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL, attrValue = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - CFAbsoluteTime signingTime = 0.0; - - /* Create decoder and decode */ - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerValid, "Valid signature"); - - /* Get Hash Agility Attribute value */ - ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), - "Copy hash agility attribute value"); - is(CFDataGetLength(attrValue), sizeof(attribute), "Decoded attribute size"); - is(memcmp(attribute, CFDataGetBytePtr(attrValue), sizeof(attribute)), 0, - "Decoded value same as input value"); - - /* Get Signing Time Attribute value */ - ok_status(CMSDecoderCopySignerSigningTime(decoder, 0, &signingTime), - "Copy signing time attribute value"); - is(signingTime, 468295000.0, "Decoded date same as input date"); - - CFReleaseNull(decoder); - CFReleaseNull(contentData); - CFReleaseNull(policy); - CFReleaseNull(trust); - CFReleaseNull(attrValue); -} - -static void decode_negative_test(void) -{ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - - /* Create decoder and decode */ - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, sizeof(invalid_message)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerInvalidSignature, "Invalid signature"); - - CFReleaseNull(decoder); - CFReleaseNull(contentData); - CFReleaseNull(policy); - CFReleaseNull(trust); -} - -static void decode_no_attr_test(void) -{ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL, attrValue = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - - /* Create decoder and decode */ - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, sizeof(valid_no_attr)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerValid, "Valid signature"); - - /* Get Hash Agility Attribute value */ - ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), - "Copy empty hash agility attribute value"); - is(attrValue, NULL, "NULL attribute value"); - - CFReleaseNull(decoder); - CFReleaseNull(contentData); - CFReleaseNull(policy); - CFReleaseNull(trust); - CFReleaseNull(attrValue); -} - -static void macOS_shim_tests(void) { - encode_test(); - decode_positive_test(); - decode_negative_test(); - decode_no_attr_test(); -} - -static void encode_V2_test(void) { - CMSEncoderRef encoder = NULL; - CMSDecoderRef decoder = NULL; - NSData *p12Data = nil; - CFArrayRef tmp_imported_items = NULL; - NSArray *imported_items = nil; - SecIdentityRef identity = NULL; - CFDataRef message = NULL; - NSDictionary *attrValues = nil, *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" }; - - /* Create encoder */ - require_noerr_string(CMSEncoderCreate(&encoder), exit, "Failed to create CMS encoder"); - require_noerr_string(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit, - "Failed to set digest algorithm to SHA256"); - - /* Load identity and set as signer */ - p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)]; - require_noerr_string(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options, - &tmp_imported_items), exit, - "Failed to import identity"); - imported_items = CFBridgingRelease(tmp_imported_items); - require_noerr_string([imported_items count] == 0 && - [imported_items[0] isKindOfClass:[NSDictionary class]], exit, - "Wrong imported items output"); - identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]); - require_string(identity, exit, "Failed to get identity"); - require_noerr_string(CMSEncoderAddSigners(encoder, identity), exit, "Failed to add signer identity"); - - /* Add signing time attribute for 26 October 2017 */ - require_noerr_string(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), exit, - "Failed to set signing time flag"); - require_noerr_string(CMSEncoderSetSigningTime(encoder, 530700000.0), exit, "Failed to set signing time"); - - /* Add hash agility attribute */ - attrValues = @{ @(SEC_OID_SHA1) : [NSData dataWithBytes:_attributev2 length:20], - @(SEC_OID_SHA256) : [NSData dataWithBytes:(_attributev2 + 32) length:32], - }; - ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgilityV2), - "Set hash agility flag"); - ok_status(CMSEncoderSetAppleCodesigningHashAgilityV2(encoder, (__bridge CFDictionaryRef)attrValues), - "Set hash agility data"); - - /* Load content */ - require_noerr_string(CMSEncoderSetHasDetachedContent(encoder, true), exit, "Failed to set detached content"); - require_noerr_string(CMSEncoderUpdateContent(encoder, content, sizeof(content)), exit, "Failed to set content"); - - /* output cms message */ - ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); - isnt(message, NULL, "Encoded message exists"); - - /* decode message */ - require_noerr_string(CMSDecoderCreate(&decoder), exit, "Create CMS decoder"); - require_noerr_string(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), - CFDataGetLength(message)), exit, - "Update decoder with CMS message"); - require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:content - length:sizeof(content)]), - exit, "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - -exit: - CFReleaseNull(encoder); - CFReleaseNull(identity); - CFReleaseNull(message); - CFReleaseNull(decoder); -} - -/* macOS shim test - decode positive */ -static void decode_V2_positive_test(void) { - CMSDecoderRef decoder = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - NSData *contentData = nil; - CFDictionaryRef tmpAttrValue = NULL; - NSDictionary *attrValue = nil; - - /* Create decoder and decode */ - require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); - require_noerr_string(CMSDecoderUpdateMessage(decoder, _V2_valid_message, sizeof(_V2_valid_message)), exit, - "Failed to update decoder with CMS message"); - contentData = [NSData dataWithBytes:content length:sizeof(content)]; - require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, - "Failed to set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerValid, "Valid signature"); - - /* Get Hash Agility Attribute value */ - ok_status(CMSDecoderCopySignerAppleCodesigningHashAgilityV2(decoder, 0, &tmpAttrValue), - "Copy hash agility attribute value"); - attrValue = CFBridgingRelease(tmpAttrValue); - ok([attrValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]], - "Got wrong SHA1 agility value"); - ok([attrValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]], - "Got wrong SHA256 agility value"); - -exit: - CFReleaseNull(decoder); - CFReleaseNull(policy); - CFReleaseNull(trust); -} - -/* macOS shim test - decode negative */ -static void decode_V2_negative_test(void) { - CMSDecoderRef decoder = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - NSData *contentData = nil; - NSMutableData *invalid_message = nil; - - /* Create decoder and decode */ - invalid_message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)]; - [invalid_message resetBytesInRange:NSMakeRange(2110, 1)]; /* reset byte in hash agility attribute */ - require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); - require_noerr_string(CMSDecoderUpdateMessage(decoder, [invalid_message bytes], [invalid_message length]), exit, - "Failed to update decoder with CMS message"); - contentData = [NSData dataWithBytes:content length:sizeof(content)]; - require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, - "Failed to set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerInvalidSignature, "Valid signature"); - -exit: - CFReleaseNull(decoder); - CFReleaseNull(policy); - CFReleaseNull(trust); -} - -/* macOS shim test - no attribute */ -static void decodeV2_no_attr_test(void) { - CMSDecoderRef decoder = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - NSData *contentData = nil; - CFDictionaryRef attrValue = NULL; - - /* Create decoder and decode */ - require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); - require_noerr_string(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), exit, - "Failed to update decoder with CMS message"); - contentData = [NSData dataWithBytes:content length:sizeof(content)]; - require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, - "Failed to set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerValid, "Valid signature"); - - /* Get Hash Agility Attribute value */ - ok_status(CMSDecoderCopySignerAppleCodesigningHashAgilityV2(decoder, 0, &attrValue), - "Copy hash agility attribute value"); - is(attrValue, NULL, "NULL attribute value"); - -exit: - CFReleaseNull(decoder); - CFReleaseNull(policy); - CFReleaseNull(trust); - CFReleaseNull(attrValue); -} - -static void macOS_shim_V2_tests(void) { - encode_V2_test(); - decode_V2_positive_test(); - decode_V2_negative_test(); - decodeV2_no_attr_test(); -} - -int cms_hash_agility_test(int argc, char *const *argv) -{ - plan_tests(74); - - macOS_shim_tests(); - macOS_shim_V2_tests(); - - return 0; -} diff --git a/OSX/libsecurity_cms/regressions/cms_regressions.h b/OSX/libsecurity_cms/regressions/cms_regressions.h index 4cc5ad52..11b0febe 100644 --- a/OSX/libsecurity_cms/regressions/cms_regressions.h +++ b/OSX/libsecurity_cms/regressions/cms_regressions.h @@ -25,5 +25,4 @@ #include -ONE_TEST(cms_hash_agility_test) ONE_TEST(cms_trust_settings_test) diff --git a/OSX/libsecurity_codesigning/lib/CSCommon.h b/OSX/libsecurity_codesigning/lib/CSCommon.h index 22129bcb..d3a6bb18 100644 --- a/OSX/libsecurity_codesigning/lib/CSCommon.h +++ b/OSX/libsecurity_codesigning/lib/CSCommon.h @@ -119,12 +119,13 @@ CF_ENUM(OSStatus) { errSecCSBadDiskImageFormat = -67001, /* disk image format unrecognized, invalid, or unsuitable */ errSecCSUnsupportedDigestAlgorithm = -67000, /* a requested signature digest algorithm is not supported */ errSecCSInvalidAssociatedFileData = -66999, /* resource fork, Finder information, or similar detritus not allowed */ - errSecCSInvalidTeamIdentifier = -66998, /* a Team Identifier string is invalid */ - errSecCSBadTeamIdentifier = -66997, /* a Team Identifier is wrong or inappropriate */ - errSecCSSignatureUntrusted = -66996, /* signature is valid but signer is not trusted */ + errSecCSInvalidTeamIdentifier = -66998, /* a Team Identifier string is invalid */ + errSecCSBadTeamIdentifier = -66997, /* a Team Identifier is wrong or inappropriate */ + errSecCSSignatureUntrusted = -66996, /* signature is valid but signer is not trusted */ errSecMultipleExecSegments = -66995, /* the image contains multiple executable segments */ errSecCSInvalidEntitlements = -66994, /* invalid entitlement plist */ - errSecCSInvalidRuntimeVersion = -66993, /* an invalid runtime version was explicitly set */ + errSecCSInvalidRuntimeVersion = -66993, /* an invalid runtime version was explicitly set */ + errSecCSRevokedNotarization = -66992, /* notarization indicates this code has been revoked */ }; /* @@ -302,11 +303,20 @@ typedef CF_OPTIONS(uint32_t, SecCodeSignatureFlags) { This bit can only be set. Code that has the kill flag set will never be dynamically invalid (and live). Note however that a change in static validity does not necessarily trigger instant death. + + @constant kSecCodeStatusDebugged + Indicated that code has been debugged by another process that was allowed to do so. The debugger + causes this to be set when it attachs. + + @constant kSecCodeStatusPlatform + Indicates the code is platform code, shipping with the operating system and signed by Apple. */ typedef CF_OPTIONS(uint32_t, SecCodeStatus) { - kSecCodeStatusValid = 0x0001, - kSecCodeStatusHard = 0x0100, - kSecCodeStatusKill = 0x0200, + kSecCodeStatusValid = 0x00000001, + kSecCodeStatusHard = 0x00000100, + kSecCodeStatusKill = 0x00000200, + kSecCodeStatusDebugged = 0x10000000, + kSecCodeStatusPlatform = 0x04000000, }; @@ -343,6 +353,7 @@ typedef CF_ENUM(uint32_t, SecCSDigestAlgorithm) { kSecCodeSignatureHashSHA256 = 2, /* SHA-256 */ kSecCodeSignatureHashSHA256Truncated = 3, /* SHA-256 truncated to first 20 bytes */ kSecCodeSignatureHashSHA384 = 4, /* SHA-384 */ + kSecCodeSignatureHashSHA512 = 5, /* SHA-512 */ }; CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_codesigning/lib/Code.cpp b/OSX/libsecurity_codesigning/lib/Code.cpp index 8de98a37..919ff0bc 100644 --- a/OSX/libsecurity_codesigning/lib/Code.cpp +++ b/OSX/libsecurity_codesigning/lib/Code.cpp @@ -30,6 +30,7 @@ #include "cskernel.h" #include #include +#include "SecInternalReleasePriv.h" namespace Security { namespace CodeSigning { @@ -210,9 +211,20 @@ void SecCode::checkValidity(SecCSFlags flags) myDisk->diskRep()->strictValidate(myDisk->codeDirectory(), DiskRep::ToleratedErrors(), flags); // check my own dynamic state - if (!(this->host()->getGuestStatus(this) & kSecCodeStatusValid)) - MacOSError::throwMe(errSecCSGuestInvalid); - + SecCodeStatus dynamic_status = this->host()->getGuestStatus(this); + bool isValid = (dynamic_status & kSecCodeStatusValid) != 0; + if (!isValid) { + bool isDebugged = (dynamic_status & kSecCodeStatusDebugged) != 0; + bool isPlatform = (dynamic_status & kSecCodeStatusPlatform) != 0; + bool isInternal = SecIsInternalRelease(); + + if (!isDebugged || (isPlatform && !isInternal)) { + // fatal if the code is invalid and not being debugged, but + // never let platform code be debugged except on internal systems. + MacOSError::throwMe(errSecCSGuestInvalid); + } + } + // check that static and dynamic views are consistent if (this->cdHash() && !CFEqual(this->cdHash(), myDisk->cdHash())) MacOSError::throwMe(errSecCSStaticCodeChanged); diff --git a/OSX/libsecurity_codesigning/lib/CodeSigner.cpp b/OSX/libsecurity_codesigning/lib/CodeSigner.cpp index b6b274e2..84383ca6 100644 --- a/OSX/libsecurity_codesigning/lib/CodeSigner.cpp +++ b/OSX/libsecurity_codesigning/lib/CodeSigner.cpp @@ -336,6 +336,7 @@ SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters) } state.mRuntimeVersionOverride = parseRuntimeVersion(runtime); } + state.mPreserveAFSC = getBool(kSecCodeSignerPreserveAFSC); } diff --git a/OSX/libsecurity_codesigning/lib/CodeSigner.h b/OSX/libsecurity_codesigning/lib/CodeSigner.h index 7cb3b6d3..d8888f09 100644 --- a/OSX/libsecurity_codesigning/lib/CodeSigner.h +++ b/OSX/libsecurity_codesigning/lib/CodeSigner.h @@ -94,6 +94,7 @@ public: bool mNoTimeStampCerts; // don't request certificates with timestamping request LimitedAsync *mLimitedAsync; // limited async workers for verification uint32_t mRuntimeVersionOverride; // runtime Version Override + bool mPreserveAFSC; // preserve AFSC compression }; diff --git a/OSX/libsecurity_codesigning/lib/RequirementKeywords.h b/OSX/libsecurity_codesigning/lib/RequirementKeywords.h index dde80999..09c304b5 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementKeywords.h +++ b/OSX/libsecurity_codesigning/lib/RequirementKeywords.h @@ -12,6 +12,7 @@ "identifier", "cdhash", "platform", + "notarized", "anchor", "apple", "generic", diff --git a/OSX/libsecurity_codesigning/lib/RequirementLexer.cpp b/OSX/libsecurity_codesigning/lib/RequirementLexer.cpp index 5ed5abea..83296a4a 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementLexer.cpp +++ b/OSX/libsecurity_codesigning/lib/RequirementLexer.cpp @@ -39,31 +39,32 @@ RequirementLexer::RequirementLexer(const antlr::LexerSharedInputState& state) void RequirementLexer::initLiterals() { - literals["certificate"] = 25; + literals["certificate"] = 26; literals["always"] = 15; literals["host"] = 6; literals["guest"] = 5; literals["cdhash"] = 20; - literals["entitlement"] = 29; + literals["entitlement"] = 30; literals["library"] = 8; literals["never"] = 17; - literals["cert"] = 26; + literals["cert"] = 27; literals["plugin"] = 9; literals["or"] = 10; - literals["leaf"] = 42; - literals["info"] = 28; + literals["leaf"] = 43; + literals["info"] = 29; literals["designated"] = 7; - literals["apple"] = 23; - literals["trusted"] = 27; + literals["apple"] = 24; + literals["trusted"] = 28; literals["true"] = 16; + literals["notarized"] = 22; literals["and"] = 11; - literals["root"] = 43; + literals["root"] = 44; literals["platform"] = 21; - literals["anchor"] = 22; + literals["anchor"] = 23; literals["false"] = 18; - literals["generic"] = 24; + literals["generic"] = 25; literals["identifier"] = 19; - literals["exists"] = 30; + literals["exists"] = 31; } antlr::RefToken RequirementLexer::nextToken() @@ -1248,22 +1249,22 @@ 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 }; // 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 +// 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 }; // 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 +// ! \" # $ % & \' ( ) * + , - . / 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 }; // 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 +// 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 }; // 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 +// 0x1f ! \" # $ % & \' ( ) + , - . / 0 1 2 3 4 5 6 7 8 9 : const antlr::BitSet RequirementLexer::_tokenSet_5(_tokenSet_5_data_,8); ANTLR_END_NAMESPACE diff --git a/OSX/libsecurity_codesigning/lib/RequirementParser.cpp b/OSX/libsecurity_codesigning/lib/RequirementParser.cpp index dfaa3450..ae070e4d 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementParser.cpp +++ b/OSX/libsecurity_codesigning/lib/RequirementParser.cpp @@ -129,6 +129,7 @@ BlobCore * RequirementParser::autosense() { case LITERAL_identifier: case LITERAL_cdhash: case LITERAL_platform: + case LITERAL_notarized: case LITERAL_anchor: case LITERAL_certificate: case LITERAL_cert: @@ -476,6 +477,12 @@ void RequirementParser::primary( maker.platform(ident); break; } + case LITERAL_notarized: + { + match(LITERAL_notarized); + maker.put(opNotarized); + break; + } default: if ((LA(1) == LPAREN) && (_tokenSet_8.member(LA(2)))) { match(LPAREN); @@ -1224,6 +1231,7 @@ const char* RequirementParser::tokenNames[] = { "\"identifier\"", "\"cdhash\"", "\"platform\"", + "\"notarized\"", "\"anchor\"", "\"apple\"", "\"generic\"", @@ -1266,63 +1274,63 @@ const char* RequirementParser::tokenNames[] = { const unsigned long RequirementParser::_tokenSet_0_data_[] = { 2UL, 0UL, 0UL, 0UL }; // EOF const antlr::BitSet RequirementParser::_tokenSet_0(_tokenSet_0_data_,4); -const unsigned long RequirementParser::_tokenSet_1_data_[] = { 992UL, 131072UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_1_data_[] = { 992UL, 262144UL, 0UL, 0UL }; // "guest" "host" "designated" "library" "plugin" INTEGER const antlr::BitSet RequirementParser::_tokenSet_1(_tokenSet_1_data_,4); const unsigned long RequirementParser::_tokenSet_2_data_[] = { 16UL, 0UL, 0UL, 0UL }; // ARROW const antlr::BitSet RequirementParser::_tokenSet_2(_tokenSet_2_data_,4); -const unsigned long RequirementParser::_tokenSet_3_data_[] = { 994UL, 131072UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_3_data_[] = { 994UL, 262144UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" INTEGER const antlr::BitSet RequirementParser::_tokenSet_3(_tokenSet_3_data_,4); -const unsigned long RequirementParser::_tokenSet_4_data_[] = { 2281713650UL, 512129UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_4_data_[] = { 268447730UL, 1024259UL, 0UL, 0UL }; // EOF ARROW "guest" "host" "designated" "library" "plugin" "or" "and" // RPAREN "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME // INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_4(_tokenSet_4_data_,4); -const unsigned long RequirementParser::_tokenSet_5_data_[] = { 9186UL, 393216UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_5_data_[] = { 9186UL, 786432UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" RPAREN INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_5(_tokenSet_5_data_,4); -const unsigned long RequirementParser::_tokenSet_6_data_[] = { 994UL, 393216UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_6_data_[] = { 994UL, 786432UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_6(_tokenSet_6_data_,4); -const unsigned long RequirementParser::_tokenSet_7_data_[] = { 10210UL, 393216UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_7_data_[] = { 10210UL, 786432UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" RPAREN INTEGER // SEMI const antlr::BitSet RequirementParser::_tokenSet_7(_tokenSet_7_data_,4); -const unsigned long RequirementParser::_tokenSet_8_data_[] = { 914345984UL, 0UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_8_data_[] = { 1828704256UL, 0UL, 0UL, 0UL }; // LPAREN NOT "always" "true" "never" "false" "identifier" "cdhash" "platform" -// "anchor" "certificate" "cert" "info" "entitlement" +// "notarized" "anchor" "certificate" "cert" "info" "entitlement" const antlr::BitSet RequirementParser::_tokenSet_8(_tokenSet_8_data_,4); -const unsigned long RequirementParser::_tokenSet_9_data_[] = { 12258UL, 393216UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_9_data_[] = { 12258UL, 786432UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_9(_tokenSet_9_data_,4); -const unsigned long RequirementParser::_tokenSet_10_data_[] = { 0UL, 134656UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_10_data_[] = { 0UL, 269312UL, 0UL, 0UL }; // NEG "leaf" "root" INTEGER const antlr::BitSet RequirementParser::_tokenSet_10(_tokenSet_10_data_,4); -const unsigned long RequirementParser::_tokenSet_11_data_[] = { 2147483648UL, 118913UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_11_data_[] = { 0UL, 237827UL, 0UL, 0UL }; // EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME const antlr::BitSet RequirementParser::_tokenSet_11(_tokenSet_11_data_,4); -const unsigned long RequirementParser::_tokenSet_12_data_[] = { 0UL, 249856UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_12_data_[] = { 0UL, 499712UL, 0UL, 0UL }; // HASHCONSTANT DOTKEY STRING PATHNAME INTEGER const antlr::BitSet RequirementParser::_tokenSet_12(_tokenSet_12_data_,4); -const unsigned long RequirementParser::_tokenSet_13_data_[] = { 2281701376UL, 118913UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_13_data_[] = { 268435456UL, 237827UL, 0UL, 0UL }; // "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME const antlr::BitSet RequirementParser::_tokenSet_13(_tokenSet_13_data_,4); -const unsigned long RequirementParser::_tokenSet_14_data_[] = { 1073754082UL, 512000UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_14_data_[] = { 2147495906UL, 1024000UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // "exists" HASHCONSTANT DOTKEY STRING PATHNAME INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_14(_tokenSet_14_data_,4); -const unsigned long RequirementParser::_tokenSet_15_data_[] = { 3221237730UL, 393341UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_15_data_[] = { 2147495906UL, 786683UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // "exists" EQL EQQL SUBS LESS GT LE GE INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_15(_tokenSet_15_data_,4); -const unsigned long RequirementParser::_tokenSet_16_data_[] = { 12258UL, 393218UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_16_data_[] = { 12258UL, 786436UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // STAR INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_16(_tokenSet_16_data_,4); -const unsigned long RequirementParser::_tokenSet_17_data_[] = { 12258UL, 393474UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_17_data_[] = { 12258UL, 786948UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // STAR RBRACK INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_17(_tokenSet_17_data_,4); diff --git a/OSX/libsecurity_codesigning/lib/RequirementParser.hpp b/OSX/libsecurity_codesigning/lib/RequirementParser.hpp index 81857c65..80d37170 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementParser.hpp +++ b/OSX/libsecurity_codesigning/lib/RequirementParser.hpp @@ -109,10 +109,10 @@ protected: private: static const char* tokenNames[]; #ifndef NO_STATIC_CONSTS - static const int NUM_TOKENS = 58; + static const int NUM_TOKENS = 59; #else enum { - NUM_TOKENS = 58 + NUM_TOKENS = 59 }; #endif diff --git a/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.hpp b/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.hpp index 3654840c..f4aa120a 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.hpp +++ b/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.hpp @@ -31,42 +31,43 @@ struct CUSTOM_API RequirementParserTokenTypes { LITERAL_identifier = 19, LITERAL_cdhash = 20, LITERAL_platform = 21, - LITERAL_anchor = 22, - LITERAL_apple = 23, - LITERAL_generic = 24, - LITERAL_certificate = 25, - LITERAL_cert = 26, - LITERAL_trusted = 27, - LITERAL_info = 28, - LITERAL_entitlement = 29, - LITERAL_exists = 30, - EQL = 31, - EQQL = 32, - STAR = 33, - SUBS = 34, - LESS = 35, - GT = 36, - LE = 37, - GE = 38, - LBRACK = 39, - RBRACK = 40, - NEG = 41, - LITERAL_leaf = 42, - LITERAL_root = 43, - HASHCONSTANT = 44, - HEXCONSTANT = 45, - DOTKEY = 46, - STRING = 47, - PATHNAME = 48, - INTEGER = 49, - SEMI = 50, - IDENT = 51, - HEX = 52, - COMMA = 53, - WS = 54, - SHELLCOMMENT = 55, - C_COMMENT = 56, - CPP_COMMENT = 57, + LITERAL_notarized = 22, + LITERAL_anchor = 23, + LITERAL_apple = 24, + LITERAL_generic = 25, + LITERAL_certificate = 26, + LITERAL_cert = 27, + LITERAL_trusted = 28, + LITERAL_info = 29, + LITERAL_entitlement = 30, + LITERAL_exists = 31, + EQL = 32, + EQQL = 33, + STAR = 34, + SUBS = 35, + LESS = 36, + GT = 37, + LE = 38, + GE = 39, + LBRACK = 40, + RBRACK = 41, + NEG = 42, + LITERAL_leaf = 43, + LITERAL_root = 44, + HASHCONSTANT = 45, + HEXCONSTANT = 46, + DOTKEY = 47, + STRING = 48, + PATHNAME = 49, + INTEGER = 50, + SEMI = 51, + IDENT = 52, + HEX = 53, + COMMA = 54, + WS = 55, + SHELLCOMMENT = 56, + C_COMMENT = 57, + CPP_COMMENT = 58, NULL_TREE_LOOKAHEAD = 3 }; #ifdef __cplusplus diff --git a/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.txt b/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.txt index 781f4f52..09dee68b 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.txt +++ b/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.txt @@ -18,39 +18,40 @@ LITERAL_false="false"=18 LITERAL_identifier="identifier"=19 LITERAL_cdhash="cdhash"=20 LITERAL_platform="platform"=21 -LITERAL_anchor="anchor"=22 -LITERAL_apple="apple"=23 -LITERAL_generic="generic"=24 -LITERAL_certificate="certificate"=25 -LITERAL_cert="cert"=26 -LITERAL_trusted="trusted"=27 -LITERAL_info="info"=28 -LITERAL_entitlement="entitlement"=29 -LITERAL_exists="exists"=30 -EQL=31 -EQQL=32 -STAR=33 -SUBS=34 -LESS=35 -GT=36 -LE=37 -GE=38 -LBRACK=39 -RBRACK=40 -NEG=41 -LITERAL_leaf="leaf"=42 -LITERAL_root="root"=43 -HASHCONSTANT=44 -HEXCONSTANT=45 -DOTKEY=46 -STRING=47 -PATHNAME=48 -INTEGER=49 -SEMI=50 -IDENT=51 -HEX=52 -COMMA=53 -WS=54 -SHELLCOMMENT=55 -C_COMMENT=56 -CPP_COMMENT=57 +LITERAL_notarized="notarized"=22 +LITERAL_anchor="anchor"=23 +LITERAL_apple="apple"=24 +LITERAL_generic="generic"=25 +LITERAL_certificate="certificate"=26 +LITERAL_cert="cert"=27 +LITERAL_trusted="trusted"=28 +LITERAL_info="info"=29 +LITERAL_entitlement="entitlement"=30 +LITERAL_exists="exists"=31 +EQL=32 +EQQL=33 +STAR=34 +SUBS=35 +LESS=36 +GT=37 +LE=38 +GE=39 +LBRACK=40 +RBRACK=41 +NEG=42 +LITERAL_leaf="leaf"=43 +LITERAL_root="root"=44 +HASHCONSTANT=45 +HEXCONSTANT=46 +DOTKEY=47 +STRING=48 +PATHNAME=49 +INTEGER=50 +SEMI=51 +IDENT=52 +HEX=53 +COMMA=54 +WS=55 +SHELLCOMMENT=56 +C_COMMENT=57 +CPP_COMMENT=58 diff --git a/OSX/libsecurity_codesigning/lib/SecAssessment.cpp b/OSX/libsecurity_codesigning/lib/SecAssessment.cpp index f3395e63..f6aee169 100644 --- a/OSX/libsecurity_codesigning/lib/SecAssessment.cpp +++ b/OSX/libsecurity_codesigning/lib/SecAssessment.cpp @@ -147,6 +147,7 @@ CFStringRef kSecAssessmentAssessmentAuthorityFlags = CFSTR("assessment:authority CFStringRef kSecAssessmentAssessmentFromCache = CFSTR("assessment:authority:cached"); CFStringRef kSecAssessmentAssessmentWeakSignature = CFSTR("assessment:authority:weak"); CFStringRef kSecAssessmentAssessmentCodeSigningError = CFSTR("assessment:cserror"); +CFStringRef kSecAssessmentAssessmentNotarizationDate = CFSTR("assessment:notarization-date"); CFStringRef kDisabledOverride = CFSTR("security disabled"); @@ -466,6 +467,14 @@ CFDictionaryRef SecAssessmentCopyUpdate(CFTypeRef target, END_CSAPI_ERRORS1(NULL) } +static void +updateAuthority(const char *authority, bool enable, CFErrorRef *errors) +{ + CFStringRef updateValue = enable ? kSecAssessmentUpdateOperationEnable : kSecAssessmentUpdateOperationDisable; + CFTemp ctx("{%O=%s, %O=%O}", kSecAssessmentUpdateKeyLabel, authority, kSecAssessmentContextKeyUpdate, updateValue); + SecAssessmentUpdate(NULL, kSecCSDefaultFlags, ctx, errors); +} + // // The fcntl of System Policies. @@ -496,14 +505,13 @@ Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *e result = kCFBooleanTrue; return true; } else if (CFEqual(control, CFSTR("ui-enable-devid"))) { - CFTemp ctx("{%O=%s, %O=%O}", kSecAssessmentUpdateKeyLabel, "Developer ID", kSecAssessmentContextKeyUpdate, kSecAssessmentUpdateOperationEnable); - SecAssessmentUpdate(NULL, kSecCSDefaultFlags, ctx, errors); + updateAuthority("Developer ID", true, errors); + updateAuthority("Notarized Developer ID", true, errors); MessageTrace trace("com.apple.security.assessment.state", "enable-devid"); trace.send("enable Developer ID approval"); return true; } else if (CFEqual(control, CFSTR("ui-disable-devid"))) { - CFTemp ctx("{%O=%s, %O=%O}", kSecAssessmentUpdateKeyLabel, "Developer ID", kSecAssessmentContextKeyUpdate, kSecAssessmentUpdateOperationDisable); - SecAssessmentUpdate(NULL, kSecCSDefaultFlags, ctx, errors); + updateAuthority("Developer ID", false, errors); MessageTrace trace("com.apple.security.assessment.state", "disable-devid"); trace.send("disable Developer ID approval"); return true; @@ -517,6 +525,26 @@ Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *e else result = kCFBooleanTrue; return true; + } else if (CFEqual(control, CFSTR("ui-enable-notarized"))) { + updateAuthority("Notarized Developer ID", true, errors); + MessageTrace trace("com.apple.security.assessment.state", "enable-notarized"); + trace.send("enable Notarized Developer ID approval"); + return true; + } else if (CFEqual(control, CFSTR("ui-disable-notarized"))) { + updateAuthority("Notarized Developer ID", false, errors); + MessageTrace trace("com.apple.security.assessment.state", "disable-notarized"); + trace.send("disable Notarized Developer ID approval"); + return true; + } else if (CFEqual(control, CFSTR("ui-get-notarized"))) { + xpcEngineCheckNotarized((CFBooleanRef*)(arguments)); + return true; + } else if (CFEqual(control, CFSTR("ui-get-notarized-local"))) { + CFBooleanRef &result = *(CFBooleanRef*)(arguments); + if (gEngine().value("SELECT disabled FROM authority WHERE label = 'Notarized Developer ID';", true)) + result = kCFBooleanFalse; + else + result = kCFBooleanTrue; + return true; } else if (CFEqual(control, CFSTR("ui-record-reject"))) { // send this through syspolicyd for update validation xpcEngineRecord(CFDictionaryRef(arguments)); @@ -544,3 +572,24 @@ Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *e END_CSAPI_ERRORS1(false) } + +Boolean SecAssessmentTicketRegister(CFDataRef ticketData, CFErrorRef *errors) +{ + BEGIN_CSAPI + + xpcEngineTicketRegister(ticketData); + return true; + + END_CSAPI_ERRORS1(false) +} + +Boolean SecAssessmentTicketLookup(CFDataRef hash, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date, CFErrorRef *errors) +{ + BEGIN_CSAPI + + xpcEngineTicketLookup(hash, hashType, flags, date); + return true; + + END_CSAPI_ERRORS1(false) +} + diff --git a/OSX/libsecurity_codesigning/lib/SecAssessment.h b/OSX/libsecurity_codesigning/lib/SecAssessment.h index efc6dd4a..620c5857 100644 --- a/OSX/libsecurity_codesigning/lib/SecAssessment.h +++ b/OSX/libsecurity_codesigning/lib/SecAssessment.h @@ -24,6 +24,7 @@ #define _H_SECASSESSMENT #include +#include #ifdef __cplusplus extern "C" { @@ -156,6 +157,7 @@ extern CFStringRef kSecAssessmentAssessmentAuthorityRow; // (internal) extern CFStringRef kSecAssessmentAssessmentAuthorityOverride; // (internal) extern CFStringRef kSecAssessmentAssessmentAuthorityOriginalVerdict; // (internal) extern CFStringRef kSecAssessmentAssessmentAuthorityFlags; // (internal) +extern CFStringRef kSecAssessmentAssessmentNotarizationDate; // (internal) extern CFStringRef kDisabledOverride; // AuthorityOverride value for "Gatekeeper is disabled" @@ -312,6 +314,16 @@ Boolean SecAssessmentUpdate(CFTypeRef target, */ Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *errors); +/* + * SecAssessmentTicket SPI + */ +typedef uint64_t SecAssessmentTicketFlags; +enum { + kSecAssessmentTicketFlagDefault = 0, // default behavior, offline check + kSecAssessmentTicketFlagForceOnlineCheck = 1 << 0, // force an online check +}; +Boolean SecAssessmentTicketRegister(CFDataRef ticketData, CFErrorRef *errors); +Boolean SecAssessmentTicketLookup(CFDataRef hash, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date, CFErrorRef *errors); #ifdef __cplusplus } diff --git a/OSX/libsecurity_codesigning/lib/SecCode.cpp b/OSX/libsecurity_codesigning/lib/SecCode.cpp index 47d1cc16..f3269c91 100644 --- a/OSX/libsecurity_codesigning/lib/SecCode.cpp +++ b/OSX/libsecurity_codesigning/lib/SecCode.cpp @@ -265,6 +265,7 @@ 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"); /* DiskInfoRepInfo types */ const CFStringRef kSecCodeInfoDiskRepVersionPlatform = CFSTR("VersionPlatform"); diff --git a/OSX/libsecurity_codesigning/lib/SecCodePriv.h b/OSX/libsecurity_codesigning/lib/SecCodePriv.h index b610af86..4073c23f 100644 --- a/OSX/libsecurity_codesigning/lib/SecCodePriv.h +++ b/OSX/libsecurity_codesigning/lib/SecCodePriv.h @@ -44,6 +44,7 @@ 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 kSecCodeInfoDiskRepVersionPlatform; /* Number */ extern const CFStringRef kSecCodeInfoDiskRepVersionMin; /* Number */ diff --git a/OSX/libsecurity_codesigning/lib/SecCodeSigner.cpp b/OSX/libsecurity_codesigning/lib/SecCodeSigner.cpp index f043523f..a7e31f65 100644 --- a/OSX/libsecurity_codesigning/lib/SecCodeSigner.cpp +++ b/OSX/libsecurity_codesigning/lib/SecCodeSigner.cpp @@ -60,6 +60,7 @@ const CFStringRef kSecCodeSignerPreserveMetadata = CFSTR("preserve-metadata"); const CFStringRef kSecCodeSignerTeamIdentifier = CFSTR("teamidentifier"); const CFStringRef kSecCodeSignerPlatformIdentifier = CFSTR("platform-identifier"); const CFStringRef kSecCodeSignerRuntimeVersion = CFSTR("runtime-version"); +const CFStringRef kSecCodeSignerPreserveAFSC = CFSTR("preserve-afsc"); diff --git a/OSX/libsecurity_codesigning/lib/SecCodeSigner.h b/OSX/libsecurity_codesigning/lib/SecCodeSigner.h index 88067c14..2da5670f 100644 --- a/OSX/libsecurity_codesigning/lib/SecCodeSigner.h +++ b/OSX/libsecurity_codesigning/lib/SecCodeSigner.h @@ -164,6 +164,7 @@ extern const CFStringRef kSecCodeSignerPreserveMetadata; extern const CFStringRef kSecCodeSignerTeamIdentifier; extern const CFStringRef kSecCodeSignerPlatformIdentifier; extern const CFStringRef kSecCodeSignerRuntimeVersion; +extern const CFStringRef kSecCodeSignerPreserveAFSC; enum { kSecCodeSignerPreserveIdentifier = 1 << 0, // preserve signing identifier diff --git a/OSX/libsecurity_codesigning/lib/SecRequirement.cpp b/OSX/libsecurity_codesigning/lib/SecRequirement.cpp index 932096a8..1ed75082 100644 --- a/OSX/libsecurity_codesigning/lib/SecRequirement.cpp +++ b/OSX/libsecurity_codesigning/lib/SecRequirement.cpp @@ -167,6 +167,8 @@ OSStatus SecRequirementCopyString(SecRequirementRef requirementRef, SecCSFlags f CFStringRef kSecRequirementKeyInfoPlist = CFSTR("requirement:eval:info"); CFStringRef kSecRequirementKeyEntitlements = CFSTR("requirement:eval:entitlements"); CFStringRef kSecRequirementKeyIdentifier = CFSTR("requirement:eval:identifier"); +CFStringRef kSecRequirementKeyPackageChecksum = CFSTR("requirement:eval:package_checksum"); +CFStringRef kSecRequirementKeyChecksumAlgorithm = CFSTR("requirement:eval:package_checksum_algorithm"); OSStatus SecRequirementEvaluate(SecRequirementRef requirementRef, CFArrayRef certificateChain, CFDictionaryRef context, @@ -177,13 +179,24 @@ OSStatus SecRequirementEvaluate(SecRequirementRef requirementRef, const Requirement *req = SecRequirement::required(requirementRef)->requirement(); checkFlags(flags); CodeSigning::Required(certificateChain); - + + SecCSDigestAlgorithm checksumAlgorithm = kSecCodeSignatureNoHash; + if (context) { + CFRef num = (CFNumberRef)CFDictionaryGetValue(context, kSecRequirementKeyChecksumAlgorithm); + if (num) { + checksumAlgorithm = (SecCSDigestAlgorithm)cfNumber(num); + } + } + Requirement::Context ctx(certificateChain, // mandatory context ? CFDictionaryRef(CFDictionaryGetValue(context, kSecRequirementKeyInfoPlist)) : NULL, context ? CFDictionaryRef(CFDictionaryGetValue(context, kSecRequirementKeyEntitlements)) : NULL, (context && CFDictionaryGetValue(context, kSecRequirementKeyIdentifier)) ? cfString(CFStringRef(CFDictionaryGetValue(context, kSecRequirementKeyIdentifier))) : "", - NULL // can't specify a CodeDirectory here + NULL, // can't specify a CodeDirectory here + context ? CFDataRef(CFDictionaryGetValue(context, kSecRequirementKeyPackageChecksum)) : NULL, + checksumAlgorithm, + false // can't get forced platform this way ); req->validate(ctx); diff --git a/OSX/libsecurity_codesigning/lib/SecRequirementPriv.h b/OSX/libsecurity_codesigning/lib/SecRequirementPriv.h index d40b1bec..5e80a93b 100644 --- a/OSX/libsecurity_codesigning/lib/SecRequirementPriv.h +++ b/OSX/libsecurity_codesigning/lib/SecRequirementPriv.h @@ -164,6 +164,8 @@ OSStatus SecRequirementCreateGroup(CFStringRef groupName, SecCertificateRef anch extern CFStringRef kSecRequirementKeyInfoPlist; extern CFStringRef kSecRequirementKeyEntitlements; extern CFStringRef kSecRequirementKeyIdentifier; +extern CFStringRef kSecRequirementKeyPackageChecksum; +extern CFStringRef kSecRequirementKeyChecksumAlgorithm; /*! @function SecRequirementEvaluate Explicitly evaluate a SecRequirementRef against context provided in the call. diff --git a/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp b/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp index 7a93ee24..6e54a079 100644 --- a/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp +++ b/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp @@ -52,8 +52,8 @@ OSStatus SecStaticCodeCreateWithPath(CFURLRef path, SecCSFlags flags, SecStaticC { BEGIN_CSAPI - checkFlags(flags); - CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str())))->handle(); + checkFlags(flags, kSecCSForceOnlineNotarizationCheck); + CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str()), flags))->handle(); END_CSAPI } @@ -68,7 +68,7 @@ OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flag { BEGIN_CSAPI - checkFlags(flags); + checkFlags(flags, kSecCSForceOnlineNotarizationCheck); DiskRep::Context ctx; std::string version; // holds memory placed into ctx if (attributes) { @@ -87,7 +87,7 @@ OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flag ctx.version = version.c_str(); } - CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str(), &ctx)))->handle(); + CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str(), &ctx), flags))->handle(); END_CSAPI } @@ -238,10 +238,38 @@ OSStatus SecCodeMapMemory(SecStaticCodeRef codeRef, SecCSFlags flags) checkFlags(flags); SecPointer code = SecStaticCode::requiredStatic(codeRef); if (const CodeDirectory *cd = code->codeDirectory(false)) { - fsignatures args = { static_cast(code->diskRep()->signingBase()), (void *)cd, cd->length() }; - UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args)); - } else + if (code->isDetached()) { + // Detached signatures need to attach their code directory from memory. + fsignatures args = { static_cast(code->diskRep()->signingBase()), (void *)cd, cd->length() }; + UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args)); + } else { + // All other signatures can simply point to the signature in the main executable. + Universal *execImage = code->diskRep()->mainExecutableImage(); + if (execImage == NULL) { + MacOSError::throwMe(errSecCSNoMainExecutable); + } + + auto_ptr arch(execImage->architecture()); + if (arch.get() == NULL) { + MacOSError::throwMe(errSecCSNoMainExecutable); + } + + size_t signatureOffset = arch->signingOffset(); + size_t signatureLength = arch->signingLength(); + if (signatureOffset == 0) { + MacOSError::throwMe(errSecCSUnsigned); + } + + fsignatures args = { + static_cast(code->diskRep()->signingBase()), + (void *)signatureOffset, + signatureLength, + }; + UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDFILESIGS, &args)); + } + } else { MacOSError::throwMe(errSecCSUnsigned); + } END_CSAPI } diff --git a/OSX/libsecurity_codesigning/lib/SecStaticCodePriv.h b/OSX/libsecurity_codesigning/lib/SecStaticCodePriv.h index a736a9e2..a5376f44 100644 --- a/OSX/libsecurity_codesigning/lib/SecStaticCodePriv.h +++ b/OSX/libsecurity_codesigning/lib/SecStaticCodePriv.h @@ -35,6 +35,13 @@ extern "C" { #endif +/* + Private SecStaticCodeCreate* SecCS flags. + */ +CF_ENUM(uint32_t) { + kSecCSForceOnlineNotarizationCheck = 1 << 0, +}; + /* @function SecCodeSetCallback diff --git a/OSX/libsecurity_codesigning/lib/StaticCode.cpp b/OSX/libsecurity_codesigning/lib/StaticCode.cpp index 059a8c00..7458d53b 100644 --- a/OSX/libsecurity_codesigning/lib/StaticCode.cpp +++ b/OSX/libsecurity_codesigning/lib/StaticCode.cpp @@ -29,6 +29,7 @@ #include "reqmaker.h" #if TARGET_OS_OSX #include "drmaker.h" +#include "notarization.h" #endif #include "reqdumper.h" #include "reqparser.h" @@ -100,13 +101,14 @@ static inline OSStatus errorForSlot(CodeDirectory::SpecialSlot slot) // // Construct a SecStaticCode object given a disk representation object // -SecStaticCode::SecStaticCode(DiskRep *rep) +SecStaticCode::SecStaticCode(DiskRep *rep, uint32_t flags) : mCheckfix30814861builder1(NULL), mRep(rep), mValidated(false), mExecutableValidated(false), mResourcesValidated(false), mResourcesValidContext(NULL), mProgressQueue("com.apple.security.validation-progress", false, QOS_CLASS_UNSPECIFIED), mOuterScope(NULL), mResourceScope(NULL), - mDesignatedReq(NULL), mGotResourceBase(false), mMonitor(NULL), mLimitedAsync(NULL) + mDesignatedReq(NULL), mGotResourceBase(false), mMonitor(NULL), mLimitedAsync(NULL), + mFlags(flags), mNotarizationChecked(false), mStaplingChecked(false), mNotarizationDate(NAN) #if TARGET_OS_OSX , mEvalDetails(NULL) #else @@ -675,6 +677,58 @@ CFAbsoluteTime SecStaticCode::signingTimestamp() return mSigningTimestamp; } +#if TARGET_OS_OSX +#define kSecSHA256HashSize 32 +// subject:/C=US/ST=California/L=San Jose/O=Adobe Systems Incorporated/OU=Information Systems/OU=Digital ID Class 3 - Microsoft Software Validation v2/CN=Adobe Systems Incorporated +// issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Code Signing 2010 CA +// Not Before: Dec 15 00:00:00 2010 GMT +// Not After : Dec 14 23:59:59 2012 GMT +static const unsigned char ASI_CS_12[] = { + 0x77,0x82,0x9C,0x64,0x33,0x45,0x2E,0x4A,0xD3,0xA8,0xE4,0x6F,0x00,0x6C,0x27,0xEA, + 0xFB,0xD3,0xF2,0x6D,0x50,0xF3,0x6F,0xE0,0xE9,0x6D,0x06,0x59,0x19,0xB5,0x46,0xFF +}; + +bool SecStaticCode::checkfix41082220(OSStatus cssmTrustResult) +{ + // only applicable to revoked results + if (cssmTrustResult != CSSMERR_TP_CERT_REVOKED) { + return false; + } + + // only this leaf certificate + if (CFArrayGetCount(mCertChain) == 0) { + return false; + } + CFRef leafHash(SecCertificateCopySHA256Digest((SecCertificateRef)CFArrayGetValueAtIndex(mCertChain, 0))); + if (memcmp(ASI_CS_12, CFDataGetBytePtr(leafHash), kSecSHA256HashSize) != 0) { + return false; + } + + // detached dmg signature + if (!isDetached() || format() != std::string("disk image")) { + return false; + } + + // sha-1 signed + if (hashAlgorithms().size() != 1 || hashAlgorithm() != kSecCodeSignatureHashSHA1) { + return false; + } + + // not a privileged binary - no TeamID and no entitlements + if (component(cdEntitlementSlot) || teamID()) { + return false; + } + + // no flags and old version + if (codeDirectory()->version != 0x20100 || codeDirectory()->flags != 0) { + return false; + } + + Security::Syslog::warning("CodeSigning: Check-fix enabled for dmg '%s' with identifier '%s' signed with revoked certificates", + mainExecutablePath().c_str(), identifier().c_str()); + return true; +} +#endif // TARGET_OS_OSX // // Verify the CMS signature. @@ -899,6 +953,9 @@ bool SecStaticCode::verifySignature() continue; // retry validation while tolerating expiration } } + if (checkfix41082220(result)) { + break; // success + } Security::Syslog::error("SecStaticCode: verification failed (trust result %d, error %d)", trustResult, (int)result); MacOSError::throwMe(result); } @@ -1822,7 +1879,10 @@ const Requirement *SecStaticCode::defaultDesignatedRequirement() this->infoDictionary(), this->entitlements(), this->identifier(), - this->codeDirectory() + this->codeDirectory(), + NULL, + kSecCodeSignatureNoHash, + false ); return DRMaker(context).make(); #else @@ -1855,7 +1915,7 @@ bool SecStaticCode::satisfiesRequirement(const Requirement *req, OSStatus failur bool result = false; assert(req); validateDirectory(); - result = req->validates(Requirement::Context(mCertChain, infoDictionary(), entitlements(), codeDirectory()->identifier(), codeDirectory()), failure); + result = req->validates(Requirement::Context(mCertChain, infoDictionary(), entitlements(), codeDirectory()->identifier(), codeDirectory(), NULL, kSecCodeSignatureNoHash, mRep->appleInternalForcePlatform()), failure); return result; } @@ -2015,6 +2075,14 @@ CFDictionaryRef SecStaticCode::signingInformation(SecCSFlags flags) if (CFRef ddict = diskRepInformation()) CFDictionaryAddValue(dict, kSecCodeInfoDiskRepInfo, ddict); } catch (...) { } + if (mNotarizationChecked && !isnan(mNotarizationDate)) { + CFRef date = CFDateCreate(NULL, mNotarizationDate); + if (date) { + CFDictionaryAddValue(dict, kSecCodeInfoNotarizationDate, date.get()); + } else { + secerror("Error creating date from timestamp: %f", mNotarizationDate); + } + } } @@ -2086,6 +2154,25 @@ void SecStaticCode::staticValidate(SecCSFlags flags, const SecRequirement *req) { setValidationFlags(flags); +#if TARGET_OS_OSX + if (!mStaplingChecked) { + mRep->registerStapledTicket(); + mStaplingChecked = true; + } + + if (mFlags & kSecCSForceOnlineNotarizationCheck) { + if (!mNotarizationChecked) { + if (this->cdHash()) { + bool is_revoked = checkNotarizationServiceForRevocation(this->cdHash(), (SecCSDigestAlgorithm)this->hashAlgorithm(), &mNotarizationDate); + if (is_revoked) { + MacOSError::throwMe(errSecCSRevokedNotarization); + } + } + mNotarizationChecked = true; + } + } +#endif // TARGET_OS_OSX + // initialize progress/cancellation state if (flags & kSecCSReportProgress) prepareProgress(estimateResourceWorkload() + 2); // +1 head, +1 tail @@ -2203,7 +2290,7 @@ bool SecStaticCode::isAppleDeveloperCert(CFArrayRef certs) { static const std::string appleDeveloperRequirement = "(" + std::string(WWDRRequirement) + ") or (" + MACWWDRRequirement + ") or (" + developerID + ") or (" + distributionCertificate + ") or (" + iPhoneDistributionCert + ")"; SecPointer req = new SecRequirement(parseRequirement(appleDeveloperRequirement), true); - Requirement::Context ctx(certs, NULL, NULL, "", NULL); + Requirement::Context ctx(certs, NULL, NULL, "", NULL, NULL, kSecCodeSignatureNoHash, false); return req->requirement()->validates(ctx); } diff --git a/OSX/libsecurity_codesigning/lib/StaticCode.h b/OSX/libsecurity_codesigning/lib/StaticCode.h index 71ead90f..2ca6d7da 100644 --- a/OSX/libsecurity_codesigning/lib/StaticCode.h +++ b/OSX/libsecurity_codesigning/lib/StaticCode.h @@ -106,7 +106,7 @@ public: static SecStaticCode *requiredStatic(SecStaticCodeRef ref); // convert SecCodeRef static SecCode *optionalDynamic(SecStaticCodeRef ref); // extract SecCodeRef or NULL if static - SecStaticCode(DiskRep *rep); + SecStaticCode(DiskRep *rep, uint32_t flags = 0); virtual ~SecStaticCode() throw(); void initializeFromParent(const SecStaticCode& parent); @@ -227,6 +227,7 @@ protected: private: void validateOtherVersions(CFURLRef path, SecCSFlags flags, SecRequirementRef req, SecStaticCode *code); bool checkfix30814861(string path, bool addition); + bool checkfix41082220(OSStatus result); ResourceBuilder *mCheckfix30814861builder1; dispatch_once_t mCheckfix30814861builder1_once; @@ -291,6 +292,11 @@ private: LimitedAsync *mLimitedAsync; // limited async workers for verification + uint32_t mFlags; // flags from creation + bool mNotarizationChecked; // ensure notarization check only performed once + bool mStaplingChecked; // ensure stapling check only performed once + double mNotarizationDate; // the notarization ticket's date, if online check failed + // signature verification outcome (mTrust == NULL => not done yet) CFRef mTrust; // outcome of crypto validation (valid or not) CFRef mCertChain; diff --git a/OSX/libsecurity_codesigning/lib/bundlediskrep.cpp b/OSX/libsecurity_codesigning/lib/bundlediskrep.cpp index 8b6a67b9..b6178581 100644 --- a/OSX/libsecurity_codesigning/lib/bundlediskrep.cpp +++ b/OSX/libsecurity_codesigning/lib/bundlediskrep.cpp @@ -23,6 +23,7 @@ #include "bundlediskrep.h" #include "filediskrep.h" #include "dirscanner.h" +#include "notarization.h" #include #include #include @@ -47,11 +48,12 @@ static std::string findDistFile(const std::string &directory); // We make a CFBundleRef immediately, but everything else is lazy // BundleDiskRep::BundleDiskRep(const char *path, const Context *ctx) - : mBundle(_CFBundleCreateUnique(NULL, CFTempURL(path))) + : mBundle(_CFBundleCreateUnique(NULL, CFTempURL(path))), forcePlatform(false) { if (!mBundle) MacOSError::throwMe(errSecCSBadBundleFormat); setup(ctx); + forcePlatform = mExecRep->appleInternalForcePlatform(); CODESIGN_DISKREP_CREATE_BUNDLE_PATH(this, (char*)path, (void*)ctx, mExecRep); } @@ -59,6 +61,7 @@ BundleDiskRep::BundleDiskRep(CFBundleRef ref, const Context *ctx) { mBundle = ref; // retains setup(ctx); + forcePlatform = mExecRep->appleInternalForcePlatform(); CODESIGN_DISKREP_CREATE_BUNDLE_REF(this, ref, (void*)ctx, mExecRep); } @@ -87,7 +90,7 @@ void BundleDiskRep::setup(const Context *ctx) mInstallerPackage = false; // default mAppLike = false; // pessimism first bool appDisqualified = false; // found reason to disqualify as app - + // capture the path of the main executable before descending into a specific version CFRef mainExecBefore = CFBundleCopyExecutableURL(mBundle); CFRef infoPlistBefore = _CFBundleCopyInfoPlistURL(mBundle); @@ -576,41 +579,73 @@ CFDictionaryRef BundleDiskRep::defaultResourceRules(const SigningContext &ctx) "'^.*' = #T" // everything is a resource "'^Info\\.plist$' = {omit=#T,weight=10}" // explicitly exclude this for backward compatibility "}}"); - - // new (V2) executable bundle rules - return cfmake("{" // *** the new (V2) world *** - "rules={" // old (V1; legacy) version - "'^version.plist$' = #T" // include version.plist - "%s = #T" // include Resources - "%s = {optional=#T, weight=1000}" // make localizations optional - "%s = {weight=1010}" // ... except for Base.lproj which really isn't optional at all - "%s = {omit=#T, weight=1100}" // exclude all locversion.plist files - "},rules2={" - "'^.*' = #T" // include everything as a resource, with the following exceptions - "'^[^/]+$' = {nested=#T, weight=10}" // files directly in Contents - "'^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/' = {nested=#T, weight=10}" // dynamic repositories - "'.*\\.dSYM($|/)' = {weight=11}" // but allow dSYM directories in code locations (parallel to their code) - "'^(.*/)?\\.DS_Store$' = {omit=#T,weight=2000}" // ignore .DS_Store files - "'^Info\\.plist$' = {omit=#T, weight=20}" // excluded automatically now, but old systems need to be told - "'^version\\.plist$' = {weight=20}" // include version.plist as resource - "'^embedded\\.provisionprofile$' = {weight=20}" // include embedded.provisionprofile as resource - "'^PkgInfo$' = {omit=#T, weight=20}" // traditionally not included - "%s = {weight=20}" // Resources override default nested (widgets) - "%s = {optional=#T, weight=1000}" // make localizations optional - "%s = {weight=1010}" // ... except for Base.lproj which really isn't optional at all - "%s = {omit=#T, weight=1100}" // exclude all locversion.plist files - "}}", - - (string("^") + resources).c_str(), - (string("^") + resources + ".*\\.lproj/").c_str(), - (string("^") + resources + "Base\\.lproj/").c_str(), - (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str(), - - (string("^") + resources).c_str(), - (string("^") + resources + ".*\\.lproj/").c_str(), - (string("^") + resources + "Base\\.lproj/").c_str(), - (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str() - ); + + // new (V2) executable bundle rules + if (!resources.empty()) { + return cfmake("{" // *** the new (V2) world *** + "rules={" // old (V1; legacy) version + "'^version.plist$' = #T" // include version.plist + "%s = #T" // include Resources + "%s = {optional=#T, weight=1000}" // make localizations optional + "%s = {weight=1010}" // ... except for Base.lproj which really isn't optional at all + "%s = {omit=#T, weight=1100}" // exclude all locversion.plist files + "},rules2={" + "'^.*' = #T" // include everything as a resource, with the following exceptions + "'^[^/]+$' = {nested=#T, weight=10}" // files directly in Contents + "'^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/' = {nested=#T, weight=10}" // dynamic repositories + "'.*\\.dSYM($|/)' = {weight=11}" // but allow dSYM directories in code locations (parallel to their code) + "'^(.*/)?\\.DS_Store$' = {omit=#T,weight=2000}" // ignore .DS_Store files + "'^Info\\.plist$' = {omit=#T, weight=20}" // excluded automatically now, but old systems need to be told + "'^version\\.plist$' = {weight=20}" // include version.plist as resource + "'^embedded\\.provisionprofile$' = {weight=20}" // include embedded.provisionprofile as resource + "'^PkgInfo$' = {omit=#T, weight=20}" // traditionally not included + "%s = {weight=20}" // Resources override default nested (widgets) + "%s = {optional=#T, weight=1000}" // make localizations optional + "%s = {weight=1010}" // ... except for Base.lproj which really isn't optional at all + "%s = {omit=#T, weight=1100}" // exclude all locversion.plist files + "}}", + + (string("^") + resources).c_str(), + (string("^") + resources + ".*\\.lproj/").c_str(), + (string("^") + resources + "Base\\.lproj/").c_str(), + (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str(), + + (string("^") + resources).c_str(), + (string("^") + resources + ".*\\.lproj/").c_str(), + (string("^") + resources + "Base\\.lproj/").c_str(), + (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str() + ); + } else { + /* This is a bundle format without a Resources directory, which means we need to omit + * Resources-directory specific rules that would create conflicts. */ + + /* We also declare that flat bundles do not use any nested code rules. + * Embedded, where flat bundles are used, currently does not support them, + * and we have no plans for allowing the replacement of nested code there. + * Should anyone actually intend to use nested code rules in a flat + * bundle, they are free to create their own rules. */ + + return cfmake("{" // *** the new (V2) world *** + "rules={" // old (V1; legacy) version + "'^version.plist$' = #T" // include version.plist + "'^.*' = #T" // include Resources + "'^.*\\.lproj/' = {optional=#T, weight=1000}" // make localizations optional + "'^Base\\.lproj/' = {weight=1010}" // ... except for Base.lproj which really isn't optional at all + "'^.*\\.lproj/locversion.plist$' = {omit=#T, weight=1100}" // exclude all locversion.plist files + "},rules2={" + "'^.*' = #T" // include everything as a resource, with the following exceptions + "'.*\\.dSYM($|/)' = {weight=11}" // but allow dSYM directories in code locations (parallel to their code) + "'^(.*/)?\\.DS_Store$' = {omit=#T,weight=2000}" // ignore .DS_Store files + "'^Info\\.plist$' = {omit=#T, weight=20}" // excluded automatically now, but old systems need to be told + "'^version\\.plist$' = {weight=20}" // include version.plist as resource + "'^embedded\\.provisionprofile$' = {weight=20}" // include embedded.provisionprofile as resource + "'^PkgInfo$' = {omit=#T, weight=20}" // traditionally not included + "'^.*\\.lproj/' = {optional=#T, weight=1000}" // make localizations optional + "'^Base\\.lproj/' = {weight=1010}" // ... except for Base.lproj which really isn't optional at all + "'^.*\\.lproj/locversion.plist$' = {omit=#T, weight=1100}" // exclude all locversion.plist files + "}}" + ); + } } @@ -797,8 +832,48 @@ void BundleDiskRep::Writer::component(CodeDirectory::SpecialSlot slot, CFDataRef if (const char *name = CodeDirectory::canonicalSlotName(slot)) { rep->createMeta(); string path = rep->metaPath(name); + +#if TARGET_OS_OSX + // determine AFSC status if we are told to preserve compression + bool conductCompression = false; + cmpInfo cInfo; + if (this->getPreserveAFSC()) { + struct stat statBuffer; + if (stat(path.c_str(), &statBuffer) == 0) { + if (queryCompressionInfo(path.c_str(), &cInfo) == 0) { + if (cInfo.compressionType != 0 && cInfo.compressedSize > 0) { + conductCompression = true; + } + } + } + } +#endif + AutoFileDesc fd(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); fd.writeAll(CFDataGetBytePtr(data), CFDataGetLength(data)); + fd.close(); + +#if TARGET_OS_OSX + // if the original file was compressed, compress the new file after move + if (conductCompression) { + CFMutableDictionaryRef options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFStringRef val = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), cInfo.compressionType); + CFDictionarySetValue(options, kAFSCCompressionTypes, val); + CFRelease(val); + + CompressionQueueContext compressionQueue = CreateCompressionQueue(NULL, NULL, NULL, NULL, options); + + if (!CompressFile(compressionQueue, path.c_str(), NULL)) { + secinfo("bundlediskrep", "%p Failed to queue compression of file %s", this, path.c_str()); + MacOSError::throwMe(errSecCSInternalError); + } + + FinishCompressionAndCleanUp(compressionQueue); + compressionQueue = NULL; + CFRelease(options); + } +#endif + mWrittenFiles.insert(name); } else MacOSError::throwMe(errSecCSBadBundleFormat); @@ -838,8 +913,7 @@ void BundleDiskRep::Writer::flush() execWriter->flush(); purgeMetaDirectory(); } - - + // purge _CodeSignature of all left-over files from any previous signature void BundleDiskRep::Writer::purgeMetaDirectory() { @@ -856,6 +930,11 @@ void BundleDiskRep::Writer::purgeMetaDirectory() } +void BundleDiskRep::registerStapledTicket() +{ + string root = cfStringRelease(copyCanonicalPath()); + registerStapledTicketInBundle(root); +} } // end namespace CodeSigning } // end namespace Security diff --git a/OSX/libsecurity_codesigning/lib/bundlediskrep.h b/OSX/libsecurity_codesigning/lib/bundlediskrep.h index f44a2b1c..a166a7e0 100644 --- a/OSX/libsecurity_codesigning/lib/bundlediskrep.h +++ b/OSX/libsecurity_codesigning/lib/bundlediskrep.h @@ -30,6 +30,14 @@ #include "diskrep.h" #include "machorep.h" +#include + +#if TARGET_OS_OSX +__BEGIN_DECLS +#include +__END_DECLS +#endif + namespace Security { namespace CodeSigning { @@ -80,6 +88,10 @@ public: void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); CFArrayRef allowedResourceOmissions(); + void registerStapledTicket(); + + bool appleInternalForcePlatform() const {return forcePlatform;}; + CFBundleRef bundle() const { return mBundle; } public: @@ -118,6 +130,7 @@ private: bool mComponentsFromExecValid; // mComponentsFromExec is valid (tri-state) std::set mUsedComponents; // remember what components we've retrieved std::set mStrictErrors; // strict validation errors encountered + bool forcePlatform; // treat as anchor apple on apple internal }; diff --git a/OSX/libsecurity_codesigning/lib/codedirectory.cpp b/OSX/libsecurity_codesigning/lib/codedirectory.cpp index 33ae72ca..5218ef4b 100644 --- a/OSX/libsecurity_codesigning/lib/codedirectory.cpp +++ b/OSX/libsecurity_codesigning/lib/codedirectory.cpp @@ -111,6 +111,8 @@ unsigned CodeDirectory::slotAttributes(SpecialSlot slot) return cdComponentIsBlob; // global case cdIdentificationSlot: return cdComponentPerArchitecture; // raw + case cdTicketSlot: + return 0; // global, raw default: return 0; // global, raw } diff --git a/OSX/libsecurity_codesigning/lib/codedirectory.h b/OSX/libsecurity_codesigning/lib/codedirectory.h index 3da3be15..eae6649f 100644 --- a/OSX/libsecurity_codesigning/lib/codedirectory.h +++ b/OSX/libsecurity_codesigning/lib/codedirectory.h @@ -113,6 +113,7 @@ enum { cdAlternateCodeDirectoryLimit = 0x1005, // 5+1 hashes should be enough for everyone... cdSignatureSlot = 0x10000, // CMS signature cdIdentificationSlot, // identification blob (detached signatures only) + cdTicketSlot, // ticket embedded in signature (DMG only) // (add further virtual slot numbers here) }; diff --git a/OSX/libsecurity_codesigning/lib/csprocess.cpp b/OSX/libsecurity_codesigning/lib/csprocess.cpp index 8e208c06..26ee9005 100644 --- a/OSX/libsecurity_codesigning/lib/csprocess.cpp +++ b/OSX/libsecurity_codesigning/lib/csprocess.cpp @@ -84,7 +84,10 @@ CFDictionaryRef ProcessDynamicCode::infoDictionary() { if (mGuest->pidBased()->supportInfoPlist()) return SecStaticCode::infoDictionary(); - return makeCFDictionary(0); + if (!mEmptyInfoDict) { + mEmptyInfoDict.take(makeCFDictionary(0)); + } + return mEmptyInfoDict; } void ProcessDynamicCode::validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail /* = errSecCSSignatureFailed */) diff --git a/OSX/libsecurity_codesigning/lib/csprocess.h b/OSX/libsecurity_codesigning/lib/csprocess.h index d41ef23c..1e38473b 100644 --- a/OSX/libsecurity_codesigning/lib/csprocess.h +++ b/OSX/libsecurity_codesigning/lib/csprocess.h @@ -80,7 +80,7 @@ public: void validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed); private: ProcessCode *mGuest; - + CFRef mEmptyInfoDict; }; } // end namespace CodeSigning diff --git a/OSX/libsecurity_codesigning/lib/diskimagerep.cpp b/OSX/libsecurity_codesigning/lib/diskimagerep.cpp index a24b9e59..be2443d1 100644 --- a/OSX/libsecurity_codesigning/lib/diskimagerep.cpp +++ b/OSX/libsecurity_codesigning/lib/diskimagerep.cpp @@ -25,6 +25,7 @@ // diskimagerep - DiskRep representing a single read-only compressed disk image file // #include "diskimagerep.h" +#include "notarization.h" #include "sigblob.h" #include "CodeSigner.h" #include @@ -235,6 +236,15 @@ void DiskImageRep::Writer::addDiscretionary(CodeDirectory::Builder &builder) { } +void DiskImageRep::registerStapledTicket() +{ + CFRef data = NULL; + if (mSigningData) { + data.take(mSigningData->component(cdTicketSlot)); + registerStapledTicketInDMG(data); + } +} + } // end namespace CodeSigning } // end namespace Security diff --git a/OSX/libsecurity_codesigning/lib/diskimagerep.h b/OSX/libsecurity_codesigning/lib/diskimagerep.h index 96a63a2a..91a09193 100644 --- a/OSX/libsecurity_codesigning/lib/diskimagerep.h +++ b/OSX/libsecurity_codesigning/lib/diskimagerep.h @@ -52,7 +52,8 @@ public: void prepareForSigning(SigningContext& state); static bool candidate(UnixPlusPlus::FileDesc &fd); - + void registerStapledTicket(); + public: static CFDataRef identificationFor(MachO *macho); diff --git a/OSX/libsecurity_codesigning/lib/diskrep.cpp b/OSX/libsecurity_codesigning/lib/diskrep.cpp index cc6e389a..0fd4ede8 100644 --- a/OSX/libsecurity_codesigning/lib/diskrep.cpp +++ b/OSX/libsecurity_codesigning/lib/diskrep.cpp @@ -78,7 +78,6 @@ void DiskRep::Writer::addDiscretionary(CodeDirectory::Builder &) // do nothing } - // // Given a file system path, come up with the most likely correct // disk representation for what's there. @@ -300,6 +299,9 @@ std::string DiskRep::canonicalIdentifier(const std::string &name) return s.substr(0, p); } +void DiskRep::registerStapledTicket() +{ /* do nothing */ } + // // Writers diff --git a/OSX/libsecurity_codesigning/lib/diskrep.h b/OSX/libsecurity_codesigning/lib/diskrep.h index 131f8f68..cf90ae61 100644 --- a/OSX/libsecurity_codesigning/lib/diskrep.h +++ b/OSX/libsecurity_codesigning/lib/diskrep.h @@ -82,6 +82,8 @@ public: virtual void flush(); // flush caches (refetch as needed) virtual CFDictionaryRef diskRepInformation(); // information from diskrep + virtual void registerStapledTicket(); + // default values for signing operations virtual std::string recommendedIdentifier(const SigningContext &ctx) = 0; // default identifier virtual CFDictionaryRef defaultResourceRules(const SigningContext &ctx); // default resource rules [none] @@ -92,6 +94,8 @@ public: virtual void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); // perform strict validation virtual CFArrayRef allowedResourceOmissions(); // allowed (default) resource omission rules + virtual bool appleInternalForcePlatform() const {return false;}; + bool mainExecutableIsMachO() { return mainExecutableImage() != NULL; } // shorthands @@ -186,10 +190,18 @@ public: void signature(CFDataRef data) { component(cdSignatureSlot, data); } void codeDirectory(const CodeDirectory *cd, CodeDirectory::SpecialSlot slot) { component(slot, CFTempData(cd->data(), cd->length())); } - + +#if TARGET_OS_OSX + bool getPreserveAFSC() { return mPreserveAFSC; } + void setPreserveAFSC(bool flag) { mPreserveAFSC = flag; } +#endif + private: Architecture mArch; uint32_t mAttributes; +#if TARGET_OS_OSX + bool mPreserveAFSC = false; // preserve AFSC compression +#endif }; // diff --git a/OSX/libsecurity_codesigning/lib/machorep.h b/OSX/libsecurity_codesigning/lib/machorep.h index d30ba537..69d089a6 100644 --- a/OSX/libsecurity_codesigning/lib/machorep.h +++ b/OSX/libsecurity_codesigning/lib/machorep.h @@ -68,7 +68,7 @@ public: void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); void flush(); // flush cache - + static bool candidate(UnixPlusPlus::FileDesc &fd); public: diff --git a/OSX/libsecurity_codesigning/lib/notarization.cpp b/OSX/libsecurity_codesigning/lib/notarization.cpp new file mode 100644 index 00000000..91a2c15f --- /dev/null +++ b/OSX/libsecurity_codesigning/lib/notarization.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2018 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@ + */ +#include "SecAssessment.h" +#include "notarization.h" +#include "unix++.h" + +typedef struct __attribute__((packed)) _package_trailer { + uint8_t magic[4]; + uint16_t version; + uint16_t type; + uint32_t length; + uint8_t reserved[4]; +} package_trailer_t; + +enum TrailerType { + TrailerTypeInvalid = 0, + TrailerTypeTerminator, + TrailerTypeTicket, +}; + +static const char *TrailerMagic = "t8lr"; + +namespace Security { +namespace CodeSigning { + +static void +registerStapledTicketWithSystem(CFDataRef data) +{ + secinfo("notarization", "Registering stapled ticket with system"); + +#if TARGET_OS_OSX + CFErrorRef error = NULL; + if (!SecAssessmentTicketRegister(data, &error)) { + secerror("Error registering stapled ticket: %@", data); + } +#endif // TARGET_OS_OSX +} + +bool +checkNotarizationServiceForRevocation(CFDataRef hash, SecCSDigestAlgorithm hashType, double *date) +{ + bool is_revoked = false; + + secinfo("notarization", "checking with online notarization service for hash: %@", hash); + +#if TARGET_OS_OSX + CFRef error; + if (!SecAssessmentTicketLookup(hash, hashType, kSecAssessmentTicketFlagForceOnlineCheck, date, &error.aref())) { + CFIndex err = CFErrorGetCode(error); + if (err == EACCES) { + secerror("Notarization daemon found revoked hash: %@", hash); + is_revoked = true; + } else { + secerror("Error checking with notarization daemon: %ld", err); + } + } +#endif + + return is_revoked; +} + +bool +isNotarized(const Requirement::Context *context) +{ + CFRef cd; + CFRef error; + bool is_notarized = false; + SecCSDigestAlgorithm hashType = kSecCodeSignatureNoHash; + + if (context == NULL) { + is_notarized = false; + goto lb_exit; + } + + if (context->directory) { + cd.take(context->directory->cdhash()); + hashType = (SecCSDigestAlgorithm)context->directory->hashType; + } else if (context->packageChecksum) { + cd = context->packageChecksum; + hashType = context->packageAlgorithm; + } + + if (cd.get() == NULL) { + // No cdhash means we can't check notarization. + is_notarized = false; + goto lb_exit; + } + + secinfo("notarization", "checking notarization on %d, %@", hashType, cd.get()); + +#if TARGET_OS_OSX + if (SecAssessmentTicketLookup(cd, hashType, kSecAssessmentTicketFlagDefault, NULL, &error.aref())) { + is_notarized = true; + } else { + is_notarized = false; + if (error.get() != NULL) { + secerror("Error checking with notarization daemon: %ld", CFErrorGetCode(error)); + } + } +#endif + +lb_exit: + secinfo("notarization", "isNotarized = %d", is_notarized); + return is_notarized; +} + +void +registerStapledTicketInPackage(const std::string& path) +{ + int fd = 0; + package_trailer_t trailer; + off_t readOffset = 0; + size_t bytesRead = 0; + off_t backSeek = 0; + uint8_t *ticketData = NULL; + boolean_t ticketTrailerFound = false; + CFRef data; + + secinfo("notarization", "Extracting ticket from package: %s", path.c_str()); + + fd = open(path.c_str(), O_RDONLY); + if (fd <= 0) { + secerror("cannot open package for reading"); + goto lb_exit; + } + + bzero(&trailer, sizeof(trailer)); + readOffset = lseek(fd, -sizeof(trailer), SEEK_END); + if (readOffset <= 0) { + secerror("could not scan for first trailer on package (error - %d)", errno); + goto lb_exit; + } + + while (!ticketTrailerFound) { + bytesRead = read(fd, &trailer, sizeof(trailer)); + if (bytesRead != sizeof(trailer)) { + secerror("could not read next trailer from package (error - %d)", errno); + goto lb_exit; + } + + if (memcmp(trailer.magic, TrailerMagic, strlen(TrailerMagic)) != 0) { + // Most packages will not be stapled, so this isn't really an error. + secdebug("notarization", "package did not end in a trailer"); + goto lb_exit; + } + + switch (trailer.type) { + case TrailerTypeTicket: + ticketTrailerFound = true; + break; + case TrailerTypeTerminator: + // Found a terminator before a trailer, so just exit. + secinfo("notarization", "package had a trailer, but no ticket trailers"); + goto lb_exit; + case TrailerTypeInvalid: + secinfo("notarization", "package had an invalid trailer"); + goto lb_exit; + default: + // it's an unsupported trailer type, so skip it. + break; + } + + // If we're here, it's either a ticket or an unknown trailer. In both cases we can definitely seek back to the + // beginning of the data pointed to by this trailer, which is the length of its data and the size of the trailer itself. + backSeek = -1 * (sizeof(trailer) + trailer.length); + if (!ticketTrailerFound) { + // If we didn't find a ticket, we're about to iterate again and want to read the next trailer so seek back an additional + // trailer blob to prepare for reading it. + backSeek -= sizeof(trailer); + } + readOffset = lseek(fd, backSeek, SEEK_CUR); + if (readOffset <= 0) { + secerror("could not scan backwards (%lld) for next trailer on package (error - %d)", backSeek, errno); + goto lb_exit; + } + } + + // If we got here, we have a valid ticket trailer and already seeked back to the beginning of its data. + ticketData = (uint8_t*)malloc(trailer.length); + if (ticketData == NULL) { + secerror("could not allocate memory for ticket"); + goto lb_exit; + } + + bytesRead = read(fd, ticketData, trailer.length); + if (bytesRead != trailer.length) { + secerror("unable to read entire ticket (error - %d)", errno); + goto lb_exit; + } + + data = CFDataCreateWithBytesNoCopy(NULL, ticketData, trailer.length, NULL); + if (data.get() == NULL) { + secerror("unable to create cfdata for notarization"); + goto lb_exit; + } + + secinfo("notarization", "successfully found stapled ticket for: %s", path.c_str()); + registerStapledTicketWithSystem(data); + +lb_exit: + if (fd) { + close(fd); + } + if (ticketData) { + free(ticketData); + } +} + +void +registerStapledTicketInBundle(const std::string& path) +{ + int fd = 0; + struct stat st; + uint8_t *ticketData = NULL; + size_t ticketLength = 0; + size_t bytesRead = 0; + CFRef data; + std::string ticketLocation = path + "/Contents/CodeResources"; + + secinfo("notarization", "Extracting ticket from bundle: %s", path.c_str()); + + fd = open(ticketLocation.c_str(), O_RDONLY); + if (fd <= 0) { + // Only print an error if the file exists, otherwise its an expected early exit case. + if (errno != ENOENT) { + secerror("cannot open stapled file for reading: %d", errno); + } + goto lb_exit; + } + + if (fstat(fd, &st)) { + secerror("unable to stat stapling file: %d", errno); + goto lb_exit; + } + + if ((st.st_mode & S_IFREG) != S_IFREG) { + secerror("stapling is not a regular file"); + goto lb_exit; + } + + if (st.st_size <= INT_MAX) { + ticketLength = (size_t)st.st_size; + } else { + secerror("ticket size was too large: %lld", st.st_size); + goto lb_exit; + } + + ticketData = (uint8_t*)malloc(ticketLength); + if (ticketData == NULL) { + secerror("unable to allocate data for ticket"); + goto lb_exit; + } + + bytesRead = read(fd, ticketData, ticketLength); + if (bytesRead != ticketLength) { + secerror("unable to read entire ticket from bundle"); + goto lb_exit; + } + + data = CFDataCreateWithBytesNoCopy(NULL, ticketData, ticketLength, NULL); + if (data.get() == NULL) { + secerror("unable to create cfdata for notarization"); + goto lb_exit; + } + + secinfo("notarization", "successfully found stapled ticket for: %s", path.c_str()); + registerStapledTicketWithSystem(data); + +lb_exit: + if (fd) { + close(fd); + } + if (ticketData) { + free(ticketData); + } +} + +void +registerStapledTicketInDMG(CFDataRef ticketData) +{ + if (ticketData == NULL) { + return; + } + secinfo("notarization", "successfully found stapled ticket in DMG"); + registerStapledTicketWithSystem(ticketData); +} + +} +} diff --git a/OSX/libsecurity_codesigning/lib/notarization.h b/OSX/libsecurity_codesigning/lib/notarization.h new file mode 100644 index 00000000..21ae3c16 --- /dev/null +++ b/OSX/libsecurity_codesigning/lib/notarization.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018 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@ + */ +#ifndef _H_NOTARIZATION +#define _H_NOTARIZATION + +#include +#include +#include +#include +#include "requirement.h" + +namespace Security { +namespace CodeSigning { + +// Performs an online check for a ticket, and returns true if a revocation ticket is found. +bool checkNotarizationServiceForRevocation(CFDataRef hash, SecCSDigestAlgorithm hashType, double *date); + +// Performs an offline notarization check for the hash represented in the requirement context +// and returns whether the hash has a valid, unrevoked notarization ticket. +bool isNotarized(const Requirement::Context *context); + +// Representation-specific methods for extracting a stapled ticket and registering +// it with the notarization daemon. +void registerStapledTicketInPackage(const std::string& path); +void registerStapledTicketInBundle(const std::string& path); +void registerStapledTicketInDMG(CFDataRef ticketData); + +} // end namespace CodeSigning +} // end namespace Security + +#endif /* _H_NOTARIZATION */ diff --git a/OSX/libsecurity_codesigning/lib/piddiskrep.cpp b/OSX/libsecurity_codesigning/lib/piddiskrep.cpp index e56d1f46..76d785dc 100644 --- a/OSX/libsecurity_codesigning/lib/piddiskrep.cpp +++ b/OSX/libsecurity_codesigning/lib/piddiskrep.cpp @@ -190,7 +190,18 @@ string PidDiskRep::mainExecutablePath() return path; } - + +bool PidDiskRep::appleInternalForcePlatform() const +{ + uint32_t flags = 0; + int rcent = ::csops(mPid, CS_OPS_STATUS, &flags, sizeof(flags)); + + if (rcent != 0) { + MacOSError::throwMe(errSecCSNoSuchCode); + } + + return (flags & CS_PLATFORM_BINARY) == CS_PLATFORM_BINARY; +} } // end namespace CodeSigning } // end namespace Security diff --git a/OSX/libsecurity_codesigning/lib/piddiskrep.h b/OSX/libsecurity_codesigning/lib/piddiskrep.h index 766a6bda..a530984e 100644 --- a/OSX/libsecurity_codesigning/lib/piddiskrep.h +++ b/OSX/libsecurity_codesigning/lib/piddiskrep.h @@ -58,6 +58,8 @@ public: void setCredentials(const CodeDirectory* cd); + bool appleInternalForcePlatform() const; + private: const BlobCore *blob() { return (const BlobCore *)mBuffer; } void fetchData(void); diff --git a/OSX/libsecurity_codesigning/lib/policydb.cpp b/OSX/libsecurity_codesigning/lib/policydb.cpp index b3398c26..0be1a6cf 100644 --- a/OSX/libsecurity_codesigning/lib/policydb.cpp +++ b/OSX/libsecurity_codesigning/lib/policydb.cpp @@ -286,6 +286,33 @@ void PolicyDatabase::upgradeDatabase() simpleFeature("root_only", ^{ UnixError::check(::chmod(dbPath(), S_IRUSR | S_IWUSR)); }); + + simpleFeature("notarized_apps", ^{ + + // Insert a set of notarization requirements for notarized applications and installers, with a priority that will be higher than developer id priorities + // so they are guaranteed to match first. + SQLite::Statement addNotarizedExecutables(*this, + "INSERT INTO authority (type, allow, flags, priority, label, requirement) VALUES (1, 1, 2, 5.0, 'Notarized Developer ID', 'anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists and notarized')"); + addNotarizedExecutables.execute(); + + SQLite::Statement addNotarizedInstallers(*this, + "INSERT INTO authority (type, allow, flags, priority, label, requirement) VALUES (2, 1, 2, 5.0, 'Notarized Developer ID', 'anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and (certificate leaf[field.1.2.840.113635.100.6.1.14] or certificate leaf[field.1.2.840.113635.100.6.1.13]) and notarized')"); + addNotarizedInstallers.execute(); + + // Bump the priority on apple system, apple installer, and mac app store entries so they are evaluated before Developer ID variants. + // This is important because notarized variants meet the requirement of the Developer ID variant and would could match that too. + SQLite::Statement bumpAppleSystemPriority(*this, + "UPDATE authority SET priority = 20.0 WHERE label = 'Apple System'"); + bumpAppleSystemPriority.execute(); + + SQLite::Statement bumpAppleInstallerPriority(*this, + "UPDATE authority SET priority = 20.0 WHERE label = 'Apple Installer'"); + bumpAppleInstallerPriority.execute(); + + SQLite::Statement bumpMacAppStorePriority(*this, + "UPDATE authority SET priority = 10.0 WHERE label = 'Mac App Store'"); + bumpMacAppStorePriority.execute(); + }); } diff --git a/OSX/libsecurity_codesigning/lib/policyengine.cpp b/OSX/libsecurity_codesigning/lib/policyengine.cpp index fa2a971a..f3436493 100644 --- a/OSX/libsecurity_codesigning/lib/policyengine.cpp +++ b/OSX/libsecurity_codesigning/lib/policyengine.cpp @@ -38,6 +38,7 @@ #include "diskrep.h" #include "codedirectory.h" #include "csutilities.h" +#include "notarization.h" #include "StaticCode.h" #include @@ -182,8 +183,8 @@ void PolicyEngine::evaluateCodeItem(SecStaticCodeRef code, CFURLRef path, Author SQLite3::int64 disabled = query[6]; // const char *filter = query[7]; // const char *remarks = query[8]; - - secdebug("gk", "considering rule %d(%s) requirement %s", int(id), label ? label : "UNLABELED", reqString); + + secdebug("gk", "considering rule %d(%s) requirement %s", int(id), label ? label : "UNLABELED", reqString); CFRef requirement; MacOSError::check(SecRequirementCreateWithString(CFTempString(reqString), kSecCSDefaultFlags, &requirement.aref())); switch (OSStatus rc = SecStaticCodeCheckValidity(code, kSecCSBasicValidateOnly | kSecCSCheckGatekeeperArchitectures, requirement)) { @@ -197,13 +198,17 @@ void PolicyEngine::evaluateCodeItem(SecStaticCodeRef code, CFURLRef path, Author MacOSError::throwMe(rc); // general error; pass to caller } - // if this rule is disabled, skip it but record the first matching one for posterity - if (disabled && latentID == 0) { - latentID = id; - latentLabel = label ? label : ""; + // If this rule is disabled, do not continue any further and just continue iterating + // until we find one that is enabled. + if (disabled) { + // ...but always record the first matching rule for informational purposes. + if (latentID == 0) { + latentID = id; + latentLabel = label ? label : ""; + } continue; } - + // current rule is first rule (in priority order) that matched. Apply it secnotice("gk", "rule %d applies - allow=%d", int(id), allow); if (nested && allow) // success, nothing to record @@ -388,7 +393,7 @@ void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessment } CFCopyRef code; - MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags, &code.aref())); + MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags | kSecCSForceOnlineNotarizationCheck, &code.aref())); SecCSFlags validationFlags = kSecCSEnforceRevocationChecks | kSecCSCheckAllArchitectures; if (!(flags & kSecAssessmentFlagAllowWeak)) @@ -449,7 +454,7 @@ void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessment } return NULL; })); - + // go for it! SecCSFlags topFlags = validationFlags | kSecCSCheckNestedCode | kSecCSRestrictSymlinks | kSecCSReportProgress; if (type == kAuthorityExecute && !appOk) @@ -506,6 +511,18 @@ void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessment default: MacOSError::throwMe(rc); } + + // Copy notarization date, if present, from code signing information + CFRef info; + OSStatus status = SecCodeCopySigningInformation(code, kSecCSInternalInformation, &info.aref()); + if (status == 0 && info) { + CFDateRef date = (CFDateRef)CFDictionaryGetValue(info, kSecCodeInfoNotarizationDate); + if (date) { + cfadd(result, "{%O=%O}", kSecAssessmentAssessmentNotarizationDate, date); + } + } else { + secerror("Unable to copy signing information: %d", (int)status); + } if (nestedFailure && CFEqual(CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict), kCFBooleanTrue)) { // structure intact, top level approved, nested code failed policy @@ -568,6 +585,8 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi if (CFRef certs = xar.copyCertChain()) { CFRef policy = installerPolicy(); CFRef trust; + CFRef checksum; + CFRef requirementContext = makeCFMutableDictionary(); MacOSError::check(SecTrustCreateWithCertificates(certs, policy, &trust.aref())); // MacOSError::check(SecTrustSetAnchorCertificates(trust, cfEmptyArray())); // no anchors MacOSError::check(SecTrustSetOptions(trust, kSecTrustOptionAllowExpired | kSecTrustOptionImplicitAnchors)); @@ -593,6 +612,30 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi } } + xar.registerStapledNotarization(); + checksum.take(xar.createPackageChecksum()); + if (checksum) { + double notarizationDate = NAN; + + // Force a single online check for the checksum, which is always SHA1. + bool is_revoked = checkNotarizationServiceForRevocation(checksum, kSecCodeSignatureHashSHA1, ¬arizationDate); + if (is_revoked) { + MacOSError::throwMe(errSecCSRevokedNotarization); + } + + // Create the appropriate requirement context entry to allow notarized requirement check. + CFRef algorithm = makeCFNumber((uint32_t)xar.checksumDigestAlgorithm()); + cfadd(requirementContext, "{%O=%O}", kSecRequirementKeyPackageChecksum, checksum.get()); + cfadd(requirementContext, "{%O=%O}", kSecRequirementKeyChecksumAlgorithm, algorithm.get()); + + if (!isnan(notarizationDate)) { + CFRef date = CFDateCreate(NULL, notarizationDate); + if (date) { + cfadd(result, "{%O=%O}", kSecAssessmentAssessmentNotarizationDate, date.get()); + } + } + } + SQLite::Statement query(*this, "SELECT allow, requirement, id, label, flags, disabled FROM scan_authority" " WHERE type = :type" @@ -605,10 +648,10 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi const char *label = query[3]; //sqlite_uint64 ruleFlags = query[4]; SQLite3::int64 disabled = query[5]; - + CFRef requirement; MacOSError::check(SecRequirementCreateWithString(CFTempString(reqString), kSecCSDefaultFlags, &requirement.aref())); - switch (OSStatus rc = SecRequirementEvaluate(requirement, chain, NULL, kSecCSDefaultFlags)) { + switch (OSStatus rc = SecRequirementEvaluate(requirement, chain, requirementContext.get(), kSecCSDefaultFlags)) { case errSecSuccess: // success break; case errSecCSReqFailed: // requirement missed, but otherwise okay diff --git a/OSX/libsecurity_codesigning/lib/reqdumper.cpp b/OSX/libsecurity_codesigning/lib/reqdumper.cpp index c971f0ff..75e240d5 100644 --- a/OSX/libsecurity_codesigning/lib/reqdumper.cpp +++ b/OSX/libsecurity_codesigning/lib/reqdumper.cpp @@ -236,6 +236,9 @@ void Dumper::expr(SyntaxLevel level) case opPlatform: print("platform = %d", get()); break; + case opNotarized: + print("notarized"); + break; default: if (op & opGenericFalse) { print(" false /* opcode %d */", op & ~opFlagMask); diff --git a/OSX/libsecurity_codesigning/lib/reqinterp.cpp b/OSX/libsecurity_codesigning/lib/reqinterp.cpp index b685802b..80a6ae13 100644 --- a/OSX/libsecurity_codesigning/lib/reqinterp.cpp +++ b/OSX/libsecurity_codesigning/lib/reqinterp.cpp @@ -34,6 +34,7 @@ #include #include #include "csutilities.h" +#include "notarization.h" namespace Security { namespace CodeSigning { @@ -178,6 +179,10 @@ bool Requirement::Interpreter::eval(int depth) int32_t targetPlatform = get(); return mContext->directory && mContext->directory->platform == targetPlatform; } + case opNotarized: + { + return isNotarized(mContext); + } default: // opcode not recognized - handle generically if possible, fail otherwise if (op & (opGenericFalse | opGenericSkip)) { @@ -371,6 +376,10 @@ bool Requirement::Interpreter::appleLocalAnchored() if (csr_check(CSR_ALLOW_APPLE_INTERNAL)) return false; + if (mContext->forcePlatform) { + return true; + } + static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ additionalTrustedCertificates = getAdditionalTrustedAnchors(); @@ -399,7 +408,7 @@ bool Requirement::Interpreter::appleSigned() return true; } else if (appleLocalAnchored()) { return true; - } + } return false; } diff --git a/OSX/libsecurity_codesigning/lib/reqmaker.h b/OSX/libsecurity_codesigning/lib/reqmaker.h index a3ac0eed..0b26c4f9 100644 --- a/OSX/libsecurity_codesigning/lib/reqmaker.h +++ b/OSX/libsecurity_codesigning/lib/reqmaker.h @@ -70,7 +70,7 @@ public: void cdhash(SHA1::Digest digest); void cdhash(CFDataRef digest); void platform(int platformIdentifier); - + void copy(const void *data, size_t length) { memcpy(this->alloc(length), data, length); } void copy(const Requirement *req); // inline expand diff --git a/OSX/libsecurity_codesigning/lib/requirement.h b/OSX/libsecurity_codesigning/lib/requirement.h index 64cbb93a..eccd2d6a 100644 --- a/OSX/libsecurity_codesigning/lib/requirement.h +++ b/OSX/libsecurity_codesigning/lib/requirement.h @@ -100,18 +100,22 @@ private: class Requirement::Context { protected: Context() - : certs(NULL), info(NULL), entitlements(NULL), identifier(""), directory(NULL) { } + : certs(NULL), info(NULL), entitlements(NULL), identifier(""), directory(NULL), packageChecksum(NULL), packageAlgorithm(kSecCodeSignatureNoHash), forcePlatform(false) { } public: - Context(CFArrayRef certChain, CFDictionaryRef infoDict, CFDictionaryRef entitlementDict, - const std::string &ident, const CodeDirectory *dir) - : certs(certChain), info(infoDict), entitlements(entitlementDict), identifier(ident), directory(dir) { } + Context(CFArrayRef certChain, CFDictionaryRef infoDict, CFDictionaryRef entitlementDict, const std::string &ident, + const CodeDirectory *dir, CFDataRef packageChecksum, SecCSDigestAlgorithm packageAlgorithm, bool force_platform) + : certs(certChain), info(infoDict), entitlements(entitlementDict), identifier(ident), directory(dir), + packageChecksum(packageChecksum), packageAlgorithm(packageAlgorithm), forcePlatform(force_platform) { } CFArrayRef certs; // certificate chain CFDictionaryRef info; // Info.plist CFDictionaryRef entitlements; // entitlement plist std::string identifier; // signing identifier const CodeDirectory *directory; // CodeDirectory + CFDataRef packageChecksum; // package checksum + SecCSDigestAlgorithm packageAlgorithm; // package checksum algorithm + bool forcePlatform; SecCertificateRef cert(int ix) const; // get a cert from the cert chain (NULL if not found) unsigned int certCount() const; // length of cert chain (including root) @@ -161,6 +165,7 @@ enum ExprOp { opNamedAnchor, // named anchor type opNamedCode, // named subroutine opPlatform, // platform constraint [integer] + opNotarized, // has a developer id+ ticket exprOpCount // (total opcode count in use) }; diff --git a/OSX/libsecurity_codesigning/lib/signer.cpp b/OSX/libsecurity_codesigning/lib/signer.cpp index 2a9aea29..9e81b53a 100644 --- a/OSX/libsecurity_codesigning/lib/signer.cpp +++ b/OSX/libsecurity_codesigning/lib/signer.cpp @@ -107,6 +107,10 @@ void SecCodeSigner::Signer::remove(SecCSFlags flags) MacOSError::throwMe(errSecCSNotSupported); rep = code->diskRep(); + + if (state.mPreserveAFSC) + rep->writer()->setPreserveAFSC(state.mPreserveAFSC); + if (Universal *fat = state.mNoMachO ? NULL : rep->mainExecutableImage()) { // architecture-sensitive removal MachOEditor editor(rep->writer(), *fat, digestAlgorithms(), rep->mainExecutablePath()); @@ -403,7 +407,8 @@ void SecCodeSigner::Signer::buildResources(std::string root, std::string relBase if (!(signingFlags() & kSecCSSignV1)) { CFCopyRef rules2 = cfget(rulesDict, "rules2"); if (!rules2) { - // Clone V1 rules and add default nesting rules at weight 0 (overridden by anything in rules). + // Clone V1 rules and add default nesting rules at weight 0 (overridden by anything in rules, + // because the default weight, according to ResourceBuilder::addRule(), is 1). // V1 rules typically do not cover these places so we'll prevail, but if they do, we defer to them. rules2 = cfmake("{+%O" "'^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/' = {nested=#T, weight=0}" // exclude dynamic repositories @@ -524,6 +529,10 @@ void SecCodeSigner::Signer::signMachO(Universal *fat, const Requirement::Context { // Mach-O executable at the core - perform multi-architecture signing RefPointer writer = rep->writer(); + + if (state.mPreserveAFSC) + writer->setPreserveAFSC(state.mPreserveAFSC); + auto_ptr editor(state.mDetached ? static_cast(new BlobEditor(*fat, *this)) : new MachOEditor(writer, *fat, this->digestAlgorithms(), rep->mainExecutablePath())); @@ -628,7 +637,10 @@ void SecCodeSigner::Signer::signArchitectureAgnostic(const Requirement::Context // non-Mach-O executable - single-instance signing RefPointer writer = state.mDetached ? (new DetachedBlobWriter(*this)) : rep->writer(); - + + if(state.mPreserveAFSC) + writer->setPreserveAFSC(state.mPreserveAFSC); + CodeDirectorySet cdSet; for (auto type = digestAlgorithms().begin(); type != digestAlgorithms().end(); ++type) { diff --git a/OSX/libsecurity_codesigning/lib/signerutils.cpp b/OSX/libsecurity_codesigning/lib/signerutils.cpp index d543433a..ec0cf483 100644 --- a/OSX/libsecurity_codesigning/lib/signerutils.cpp +++ b/OSX/libsecurity_codesigning/lib/signerutils.cpp @@ -103,6 +103,7 @@ ArchEditor::~ArchEditor() ArchEditor::Arch::Arch(const Architecture &arch, CodeDirectory::HashAlgorithms hashTypes) : architecture(arch) { + blobSize = 0; for (auto type = hashTypes.begin(); type != hashTypes.end(); ++type) cdBuilders.insert(make_pair(*type, new CodeDirectory::Builder(*type))); } @@ -167,6 +168,7 @@ MachOEditor::~MachOEditor() delete mNewCode; if (mTempMayExist) ::remove(tempPath.c_str()); // ignore error (can't do anything about it) + this->kill(); } @@ -311,7 +313,19 @@ void MachOEditor::commit() // copy metadata from original file... copy(sourcePath.c_str(), NULL, COPYFILE_SECURITY | COPYFILE_METADATA); - + +#if TARGET_OS_OSX + // determine AFSC status if we are told to preserve compression + bool conductCompression = false; + cmpInfo cInfo; + if (writer->getPreserveAFSC()) { + if (queryCompressionInfo(sourcePath.c_str(), &cInfo) == 0) { + if (cInfo.compressionType != 0 && cInfo.compressedSize > 0) + conductCompression = true; + } + } +#endif + // ... but explicitly update the timestamps since we did change the file char buf; mFd.read(&buf, sizeof(buf), 0); @@ -320,6 +334,28 @@ void MachOEditor::commit() // move the new file into place UnixError::check(::rename(tempPath.c_str(), sourcePath.c_str())); mTempMayExist = false; // we renamed it away + +#if TARGET_OS_OSX + // if the original file was compressed, compress the new file after move + if (conductCompression) { + CFMutableDictionaryRef options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFStringRef val = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), cInfo.compressionType); + CFDictionarySetValue(options, kAFSCCompressionTypes, val); + CFRelease(val); + + CompressionQueueContext compressionQueue = CreateCompressionQueue(NULL, NULL, NULL, NULL, options); + + if (!CompressFile(compressionQueue, sourcePath.c_str(), NULL)) { + secinfo("signer", "%p Failed to queue compression of file %s", this, sourcePath.c_str()); + MacOSError::throwMe(errSecCSInternalError); + } + FinishCompressionAndCleanUp(compressionQueue); + + compressionQueue = NULL; + CFRelease(options); + } +#endif + } this->writer->flush(); } diff --git a/OSX/libsecurity_codesigning/lib/signerutils.h b/OSX/libsecurity_codesigning/lib/signerutils.h index c4cb1238..53c6e51f 100644 --- a/OSX/libsecurity_codesigning/lib/signerutils.h +++ b/OSX/libsecurity_codesigning/lib/signerutils.h @@ -38,6 +38,14 @@ #include #include +#include + +#if TARGET_OS_OSX +__BEGIN_DECLS +#include +__END_DECLS +#endif + namespace Security { namespace CodeSigning { diff --git a/OSX/libsecurity_codesigning/lib/singlediskrep.cpp b/OSX/libsecurity_codesigning/lib/singlediskrep.cpp index 2c0cbd27..c475d78c 100644 --- a/OSX/libsecurity_codesigning/lib/singlediskrep.cpp +++ b/OSX/libsecurity_codesigning/lib/singlediskrep.cpp @@ -108,6 +108,12 @@ void SingleDiskRep::flush() mFd.close(); } +//Check the magic darwinup xattr +bool SingleDiskRep::appleInternalForcePlatform() const +{ + return mFd.hasExtendedAttribute("com.apple.root.installed"); +} + // // The recommended identifier of a SingleDiskRep is, absent any better clue, // the basename of its path. diff --git a/OSX/libsecurity_codesigning/lib/singlediskrep.h b/OSX/libsecurity_codesigning/lib/singlediskrep.h index 4b9169d0..87109df5 100644 --- a/OSX/libsecurity_codesigning/lib/singlediskrep.h +++ b/OSX/libsecurity_codesigning/lib/singlediskrep.h @@ -53,7 +53,9 @@ public: size_t execSegLimit(const Architecture *arch); // size of executable segment UnixPlusPlus::FileDesc &fd(); // readable fd for this file void flush(); // close cached fd - + + bool appleInternalForcePlatform() const; + std::string recommendedIdentifier(const SigningContext &ctx); // basename(path) void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); diff --git a/OSX/libsecurity_codesigning/lib/xar++.cpp b/OSX/libsecurity_codesigning/lib/xar++.cpp index 3029c5bb..97ae714f 100644 --- a/OSX/libsecurity_codesigning/lib/xar++.cpp +++ b/OSX/libsecurity_codesigning/lib/xar++.cpp @@ -25,6 +25,7 @@ // xar++ - interface to XAR-format archive files // #include "xar++.h" +#include "notarization.h" #include #include @@ -46,6 +47,8 @@ void Xar::open(const char *path) { if ((mXar = ::xar_open(path, READ)) == NULL) return; + + mPath = std::string(path); xar_signature_t sig = ::xar_signature_first(mXar); // read signatures until we find a CMS signature @@ -91,6 +94,67 @@ CFArrayRef Xar::copyCertChain() return NULL; } +void Xar::registerStapledNotarization() +{ + registerStapledTicketInPackage(mPath); +} + +CFDataRef Xar::createPackageChecksum() +{ + xar_signature_t sig = NULL; + + // Always prefer a CMS signature to a class signature and return early + // if no appropriate signature has been found. + if (mSigCMS) { + sig = mSigCMS; + } else if (mSigClassic) { + sig = mSigClassic; + } else { + return NULL; + } + + // Extract the signed data from the xar, which is actually just the checksum + // we use as an identifying hash. + uint8_t *data = NULL; + uint32_t length; + if (xar_signature_copy_signed_data(sig, &data, &length, NULL, NULL, NULL) != 0) { + secerror("Unable to extract package hash for package: %s", mPath.c_str()); + return NULL; + } + + return makeCFData(data, length); +} + +SecCSDigestAlgorithm Xar::checksumDigestAlgorithm() +{ + int32_t error = 0; + const char* value = NULL; + unsigned long size = 0; + + if (mXar == NULL) { + secerror("Evaluating checksum digest on bad xar: %s", mPath.c_str()); + return kSecCodeSignatureNoHash; + } + + error = xar_prop_get((xar_file_t)mXar, "checksum/size", &value); + if (error == -1) { + secerror("Unable to extract package checksum size: %s", mPath.c_str()); + return kSecCodeSignatureNoHash; + } + + size = strtoul(value, NULL, 10); + switch (size) { + case CC_SHA1_DIGEST_LENGTH: + return kSecCodeSignatureHashSHA1; + case CC_SHA256_DIGEST_LENGTH: + return kSecCodeSignatureHashSHA256; + case CC_SHA512_DIGEST_LENGTH: + return kSecCodeSignatureHashSHA512; + case CC_MD5_DIGEST_LENGTH: + default: + return kSecCodeSignatureNoHash; + } +} } // end namespace CodeSigning } // end namespace Security diff --git a/OSX/libsecurity_codesigning/lib/xar++.h b/OSX/libsecurity_codesigning/lib/xar++.h index 8d9dccff..59786e50 100644 --- a/OSX/libsecurity_codesigning/lib/xar++.h +++ b/OSX/libsecurity_codesigning/lib/xar++.h @@ -29,6 +29,7 @@ #include #include +#include "CSCommon.h" extern "C" { #include @@ -49,13 +50,17 @@ public: operator bool() const { return mXar != 0; } bool isSigned() const { return mSigClassic != 0 || mSigCMS != 0; } - + + void registerStapledNotarization(); + CFDataRef createPackageChecksum(); CFArrayRef copyCertChain(); + SecCSDigestAlgorithm checksumDigestAlgorithm(); private: xar_t mXar; xar_signature_t mSigClassic; xar_signature_t mSigCMS; + std::string mPath; }; diff --git a/OSX/libsecurity_codesigning/lib/xpcengine.cpp b/OSX/libsecurity_codesigning/lib/xpcengine.cpp index eb246dd8..63528615 100644 --- a/OSX/libsecurity_codesigning/lib/xpcengine.cpp +++ b/OSX/libsecurity_codesigning/lib/xpcengine.cpp @@ -147,7 +147,7 @@ void xpcEngineAssess(CFURLRef path, SecAssessmentFlags flags, CFDictionaryRef co precheckAccess(path, context); Message msg("assess"); xpc_dictionary_set_string(msg, "path", cfString(path).c_str()); - xpc_dictionary_set_int64(msg, "flags", flags); + xpc_dictionary_set_uint64(msg, "flags", flags); CFRef ctx = makeCFMutableDictionary(); if (context) CFDictionaryApplyFunction(context, copyCFDictionary, ctx); @@ -205,7 +205,7 @@ CFDictionaryRef xpcEngineUpdate(CFTypeRef target, SecAssessmentFlags flags, CFDi } else MacOSError::throwMe(errSecCSInvalidObjectRef); } - xpc_dictionary_set_int64(msg, "flags", flags); + xpc_dictionary_set_uint64(msg, "flags", flags); CFRef ctx = makeCFMutableDictionary(); if (context) CFDictionaryApplyFunction(context, copyCFDictionary, ctx); @@ -264,6 +264,50 @@ void xpcEngineCheckDevID(CFBooleanRef* result) *result = xpc_dictionary_get_bool(msg,"result") ? kCFBooleanTrue : kCFBooleanFalse; } +void xpcEngineCheckNotarized(CFBooleanRef* result) +{ + Message msg("check-notarized"); + + msg.send(); + + if (int64_t error = xpc_dictionary_get_int64(msg, "error")) { + MacOSError::throwMe((int)error); + } + + *result = xpc_dictionary_get_bool(msg,"result") ? kCFBooleanTrue : kCFBooleanFalse; +} + +void xpcEngineTicketRegister(CFDataRef ticketData) +{ + Message msg("ticket-register"); + xpc_dictionary_set_data(msg, "ticketData", CFDataGetBytePtr(ticketData), CFDataGetLength(ticketData)); + + msg.send(); + + if (int64_t error = xpc_dictionary_get_int64(msg, "error")) { + MacOSError::throwMe((int)error); + } +} + +void xpcEngineTicketLookup(CFDataRef hashData, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date) +{ + Message msg("ticket-lookup"); + xpc_dictionary_set_data(msg, "hashData", CFDataGetBytePtr(hashData), CFDataGetLength(hashData)); + xpc_dictionary_set_uint64(msg, "hashType", hashType); + xpc_dictionary_set_uint64(msg, "flags", flags); + + msg.send(); + + if (int64_t error = xpc_dictionary_get_int64(msg, "error")) { + MacOSError::throwMe((int)error); + } + + double local_date = xpc_dictionary_get_double(msg, "date"); + if (date && !isnan(local_date)) { + *date = local_date; + } +} + } // end namespace CodeSigning } // end namespace Security diff --git a/OSX/libsecurity_codesigning/lib/xpcengine.h b/OSX/libsecurity_codesigning/lib/xpcengine.h index 4e1d485e..34b4a51a 100644 --- a/OSX/libsecurity_codesigning/lib/xpcengine.h +++ b/OSX/libsecurity_codesigning/lib/xpcengine.h @@ -38,7 +38,10 @@ CFDictionaryRef xpcEngineUpdate(CFTypeRef target, SecAssessmentFlags flags, CFDi bool xpcEngineControl(const char *name); void xpcEngineRecord(CFDictionaryRef info); void xpcEngineCheckDevID(CFBooleanRef* result); +void xpcEngineCheckNotarized(CFBooleanRef* result); +void xpcEngineTicketRegister(CFDataRef ticketData); +void xpcEngineTicketLookup(CFDataRef hashData, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date); } // end namespace CodeSigning } // end namespace Security diff --git a/OSX/libsecurity_codesigning/requirements.grammar b/OSX/libsecurity_codesigning/requirements.grammar index 6f2b827f..4fd99c70 100644 --- a/OSX/libsecurity_codesigning/requirements.grammar +++ b/OSX/libsecurity_codesigning/requirements.grammar @@ -243,6 +243,8 @@ primary[Maker &maker] { maker.cdhash(digest); } | "platform" { int32_t ident; } eql ident=integer { maker.platform(ident); } + | "notarized" + { maker.put(opNotarized); } | LPAREN { string name; } name=identifierString RPAREN { maker.put(opNamedCode); maker.put(name); } ; diff --git a/OSX/libsecurity_cssm/lib/cssmaci.h b/OSX/libsecurity_cssm/lib/cssmaci.h index f1535aef..d7306c1e 100644 --- a/OSX/libsecurity_cssm/lib/cssmaci.h +++ b/OSX/libsecurity_cssm/lib/cssmaci.h @@ -35,7 +35,7 @@ extern "C" { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -typedef struct cssm_spi_ac_funcs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_ac_funcs { CSSM_RETURN (CSSMACI *AuthCompute) (CSSM_AC_HANDLE ACHandle, const CSSM_TUPLEGROUP *BaseAuthorizations, diff --git a/OSX/libsecurity_cssm/lib/cssmapplePriv.h b/OSX/libsecurity_cssm/lib/cssmapplePriv.h index 9bf4e472..597434fd 100644 --- a/OSX/libsecurity_cssm/lib/cssmapplePriv.h +++ b/OSX/libsecurity_cssm/lib/cssmapplePriv.h @@ -26,6 +26,10 @@ #ifndef _CSSMAPPLE_PRIV_H_ #define _CSSMAPPLE_PRIV_H_ 1 +#include + +#if TARGET_OS_OSX + #include #include @@ -131,40 +135,40 @@ enum }; /* AppleCSPDL passthrough parameters */ -typedef struct cssm_applecspdl_db_recode_parameters +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_recode_parameters { CSSM_DATA dbBlob; CSSM_DATA extraData; -} CSSM_APPLECSPDL_RECODE_PARAMETERS, *CSSM_APPLECSPDL_RECODE_PARAMETERS_PTR; +} CSSM_APPLECSPDL_RECODE_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_APPLECSPDL_RECODE_PARAMETERS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_applecspdl_db_copy_blob_parameters +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_copy_blob_parameters { CSSM_DATA blob; -} CSSM_APPLECSPDL_DB_COPY_BLOB_PARAMETERS; +} CSSM_APPLECSPDL_DB_COPY_BLOB_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_applecspdl_db_insert_without_encryption_parameters +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_insert_without_encryption_parameters { CSSM_DB_RECORDTYPE recordType; CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes; CSSM_DATA data; -} CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS; +} CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_applecspdl_db_modify_without_encryption_parameters +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_modify_without_encryption_parameters { CSSM_DB_RECORDTYPE recordType; CSSM_DB_UNIQUE_RECORD_PTR uniqueID; CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes; CSSM_DATA *data; CSSM_DB_MODIFY_MODE modifyMode; -} CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS; +} CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_applecspdl_db_get_without_encryption_parameters +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_get_without_encryption_parameters { CSSM_DB_UNIQUE_RECORD_PTR uniqueID; CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes; -} CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS; +} CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_applecspdl_db_create_with_blob_parameters +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_create_with_blob_parameters { const char *dbName; const CSSM_NET_ADDRESS *dbLocation; @@ -173,10 +177,12 @@ typedef struct cssm_applecspdl_db_create_with_blob_parameters const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry; const void *openParameters; const CSSM_DATA *blob; -} CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS; +} CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; #ifdef __cplusplus } #endif +#endif /* TARGET_OS_OSX */ + #endif /* _CSSMAPPLE_PRIV_H_ */ diff --git a/OSX/libsecurity_cssm/lib/cssmcli.h b/OSX/libsecurity_cssm/lib/cssmcli.h index 504c9d7f..50195d18 100644 --- a/OSX/libsecurity_cssm/lib/cssmcli.h +++ b/OSX/libsecurity_cssm/lib/cssmcli.h @@ -35,7 +35,7 @@ extern "C" { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -typedef struct cssm_spi_cl_funcs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_cl_funcs { CSSM_RETURN (CSSMCLI *CertCreateTemplate) (CSSM_CL_HANDLE CLHandle, uint32 NumberOfFields, diff --git a/OSX/libsecurity_cssm/lib/cssmcspi.h b/OSX/libsecurity_cssm/lib/cssmcspi.h index 16535953..d828582b 100644 --- a/OSX/libsecurity_cssm/lib/cssmcspi.h +++ b/OSX/libsecurity_cssm/lib/cssmcspi.h @@ -36,7 +36,7 @@ extern "C" { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -typedef struct cssm_spi_csp_funcs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_csp_funcs { CSSM_RETURN (CSSMCSPI *EventNotify) (CSSM_CSP_HANDLE CSPHandle, CSSM_CONTEXT_EVENT Event, diff --git a/OSX/libsecurity_cssm/lib/cssmdli.h b/OSX/libsecurity_cssm/lib/cssmdli.h index b755d0ad..170c22dc 100644 --- a/OSX/libsecurity_cssm/lib/cssmdli.h +++ b/OSX/libsecurity_cssm/lib/cssmdli.h @@ -35,7 +35,7 @@ extern "C" { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -typedef struct cssm_spi_dl_funcs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_dl_funcs { CSSM_RETURN (CSSMDLI *DbOpen) (CSSM_DL_HANDLE DLHandle, const char *DbName, diff --git a/OSX/libsecurity_cssm/lib/cssmkrapi.h b/OSX/libsecurity_cssm/lib/cssmkrapi.h index 47375c15..b8a8fd26 100644 --- a/OSX/libsecurity_cssm/lib/cssmkrapi.h +++ b/OSX/libsecurity_cssm/lib/cssmkrapi.h @@ -43,7 +43,7 @@ typedef struct cssm_kr_name { char *Name; /* name string */ } CSSM_KR_NAME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_kr_profile { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kr_profile { CSSM_KR_NAME UserName; /* name of the user */ CSSM_CERTGROUP_PTR UserCertificate; /* public key certificate of the user */ CSSM_CERTGROUP_PTR KRSCertChain; /* cert chain for the KRSP coordinator */ @@ -58,7 +58,7 @@ typedef struct cssm_kr_profile { CSSM_DATA_PTR KRSPExtensions; /* reserved for extensions specific to KRSPs */ } CSSM_KR_PROFILE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KR_PROFILE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_kr_wrappedproductinfo { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kr_wrappedproductinfo { CSSM_VERSION StandardVersion; CSSM_STRING StandardDescription; CSSM_VERSION ProductVersion; @@ -67,11 +67,11 @@ typedef struct cssm_kr_wrappedproductinfo { uint32 ProductFlags; } CSSM_KR_WRAPPEDPRODUCT_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KR_WRAPPEDPRODUCT_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_krsubservice { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_krsubservice { uint32 SubServiceId; char *Description; /* Description of this sub service */ CSSM_KR_WRAPPEDPRODUCT_INFO WrappedProduct; -} CSSM_KRSUBSERVICE, *CSSM_KRSUBSERVICE_PTR; +} CSSM_KRSUBSERVICE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KRSUBSERVICE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef uint32 CSSM_KR_POLICY_TYPE; #define CSSM_KR_INDIV_POLICY (0x00000001) @@ -89,7 +89,7 @@ typedef uint32 CSSM_KR_POLICY_FLAGS; #define CSSM_KR_OPTIMIZE (0x00000010) #define CSSM_KR_DROP_WORKFACTOR (0x00000020) -typedef struct cssm_kr_policy_list_item { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kr_policy_list_item { struct kr_policy_list_item *next; CSSM_ALGORITHMS AlgorithmId; CSSM_ENCRYPT_MODE Mode; @@ -100,7 +100,7 @@ typedef struct cssm_kr_policy_list_item { CSSM_CONTEXT_TYPE AlgClass; } CSSM_KR_POLICY_LIST_ITEM DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KR_POLICY_LIST_ITEM_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_kr_policy_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kr_policy_info { CSSM_BOOL krbNotAllowed; uint32 numberOfEntries; CSSM_KR_POLICY_LIST_ITEM *policyEntry; diff --git a/OSX/libsecurity_cssm/lib/cssmkrspi.h b/OSX/libsecurity_cssm/lib/cssmkrspi.h index 741d5578..00eea5e4 100644 --- a/OSX/libsecurity_cssm/lib/cssmkrspi.h +++ b/OSX/libsecurity_cssm/lib/cssmkrspi.h @@ -38,7 +38,7 @@ extern "C" { /* Data types for Key Recovery SPI */ -typedef struct cssm_spi_kr_funcs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_kr_funcs { CSSM_RETURN (CSSMKRI *RegistrationRequest) (CSSM_KRSP_HANDLE KRSPHandle, CSSM_CC_HANDLE KRRegistrationContextHandle, diff --git a/OSX/libsecurity_cssm/lib/cssmspi.h b/OSX/libsecurity_cssm/lib/cssmspi.h index 782f3c58..f1fd4bab 100644 --- a/OSX/libsecurity_cssm/lib/cssmspi.h +++ b/OSX/libsecurity_cssm/lib/cssmspi.h @@ -41,7 +41,7 @@ typedef CSSM_RETURN (CSSMAPI *CSSM_SPI_ModuleEventHandler) void *CssmNotifyCallbackCtx, uint32 SubserviceId, CSSM_SERVICE_TYPE ServiceType, - CSSM_MODULE_EVENT EventType); + CSSM_MODULE_EVENT EventType) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef uint32 CSSM_CONTEXT_EVENT; enum { @@ -50,7 +50,7 @@ enum { CSSM_CONTEXT_EVENT_UPDATE = 3 }; -typedef struct cssm_module_funcs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_module_funcs { CSSM_SERVICE_TYPE ServiceType; uint32 NumberOfServiceFuncs; const CSSM_PROC_ADDR *ServiceFuncs; @@ -74,7 +74,7 @@ typedef void *(CSSMAPI *CSSM_UPCALLS_CALLOC) size_t num, size_t size) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_upcalls { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_upcalls { CSSM_UPCALLS_MALLOC malloc_func; CSSM_UPCALLS_FREE free_func; CSSM_UPCALLS_REALLOC realloc_func; diff --git a/OSX/libsecurity_cssm/lib/cssmtpi.h b/OSX/libsecurity_cssm/lib/cssmtpi.h index ad92b112..352d4391 100644 --- a/OSX/libsecurity_cssm/lib/cssmtpi.h +++ b/OSX/libsecurity_cssm/lib/cssmtpi.h @@ -35,7 +35,7 @@ extern "C" { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -typedef struct cssm_spi_tp_funcs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_tp_funcs { CSSM_RETURN (CSSMTPI *SubmitCredRequest) (CSSM_TP_HANDLE TPHandle, const CSSM_TP_AUTHORITY_ID *PreferredAuthority, diff --git a/OSX/libsecurity_cssm/lib/cssmtype.h b/OSX/libsecurity_cssm/lib/cssmtype.h index 57481d1c..0dd97461 100644 --- a/OSX/libsecurity_cssm/lib/cssmtype.h +++ b/OSX/libsecurity_cssm/lib/cssmtype.h @@ -141,7 +141,7 @@ enum { typedef CSSM_SERVICE_MASK CSSM_SERVICE_TYPE; -typedef struct cssm_subservice_uid { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_subservice_uid { CSSM_GUID Guid; CSSM_VERSION Version; uint32 SubserviceId; @@ -160,7 +160,7 @@ typedef CSSM_RETURN (CSSMAPI *CSSM_API_ModuleEventHandler) void* AppNotifyCallbackCtx, uint32 SubserviceId, CSSM_SERVICE_TYPE ServiceType, - CSSM_MODULE_EVENT EventType); + CSSM_MODULE_EVENT EventType) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef uint32 CSSM_ATTACH_FLAGS; enum { @@ -195,7 +195,7 @@ enum { CSSM_ADDR_NAME = 4 /* char* - qualified by access method */ }; -typedef struct cssm_net_address { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_net_address { CSSM_NET_ADDRESS_TYPE AddressType; CSSM_DATA Address; } CSSM_NET_ADDRESS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_NET_ADDRESS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -217,9 +217,9 @@ enum { }; typedef CSSM_RETURN (CSSMAPI *CSSM_CALLBACK) - (CSSM_DATA_PTR OutData, void *CallerCtx); + (CSSM_DATA_PTR OutData, void *CallerCtx) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_crypto_data { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_crypto_data { CSSM_DATA Param; CSSM_CALLBACK Callback; void *CallerCtx; @@ -386,7 +386,7 @@ typedef struct cssm_list { CSSM_LIST_ELEMENT_PTR Tail; /* tail of the list */ } CSSM_LIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_LIST_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_list_element { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_list_element { struct cssm_list_element *NextElement; /* next list element */ CSSM_WORDID_TYPE WordID; /* integer identifier associated */ /* with a Word value */ @@ -395,9 +395,9 @@ typedef struct cssm_list_element { CSSM_LIST Sublist; /* sublist */ CSSM_DATA Word; /* a byte-string */ } Element; -} CSSM_LIST_ELEMENT; +} CSSM_LIST_ELEMENT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct { /* 5-tuple definition */ +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { /* 5-tuple definition */ CSSM_LIST Issuer; /* issuer, or empty if ACL */ CSSM_LIST Subject; /* subject */ CSSM_BOOL Delegate; /* permission to delegate */ @@ -405,7 +405,7 @@ typedef struct { /* 5-tuple definition */ CSSM_LIST ValidityPeriod; /* validity information (dates) */ } CSSM_TUPLE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TUPLE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_tuplegroup { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tuplegroup { uint32 NumberOfTuples; CSSM_TUPLE_PTR Tuples; } CSSM_TUPLEGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TUPLEGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -424,12 +424,12 @@ enum { CSSM_SAMPLE_TYPE_THRESHOLD = CSSM_WORDID_THRESHOLD }; -typedef struct cssm_sample { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_sample { CSSM_LIST TypedSample; const CSSM_SUBSERVICE_UID *Verifier; } CSSM_SAMPLE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_SAMPLE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_samplegroup { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_samplegroup { uint32 NumberOfSamples; const CSSM_SAMPLE *Samples; } CSSM_SAMPLEGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_SAMPLEGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -460,14 +460,14 @@ typedef struct cssm_memory_funcs { void *AllocRef; } CSSM_MEMORY_FUNCS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_MEMORY_FUNCS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef CSSM_MEMORY_FUNCS CSSM_API_MEMORY_FUNCS; -typedef CSSM_API_MEMORY_FUNCS *CSSM_API_MEMORY_FUNCS_PTR; +typedef CSSM_MEMORY_FUNCS CSSM_API_MEMORY_FUNCS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; +typedef CSSM_API_MEMORY_FUNCS *CSSM_API_MEMORY_FUNCS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef CSSM_RETURN (CSSMAPI * CSSM_CHALLENGE_CALLBACK) (const CSSM_LIST *Challenge, CSSM_SAMPLEGROUP_PTR Response, void *CallerCtx, - const CSSM_MEMORY_FUNCS *MemFuncs); + const CSSM_MEMORY_FUNCS *MemFuncs) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef uint32 CSSM_CERT_TYPE, *CSSM_CERT_TYPE_PTR; enum { @@ -508,7 +508,7 @@ enum { CSSM_CL_CUSTOM_CERT_ENCODING = 0x8000 }; -typedef struct cssm_encoded_cert { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_encoded_cert { CSSM_CERT_TYPE CertType; /* type of certificate */ CSSM_CERT_ENCODING CertEncoding; /* encoding for this packed cert */ CSSM_DATA CertBlob; /* packed cert */ @@ -540,7 +540,7 @@ typedef struct cssm_parsed_cert { void *ParsedCert; /* parsed cert (to be typecast) */ } CSSM_PARSED_CERT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_PARSED_CERT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_cert_pair { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_cert_pair { CSSM_ENCODED_CERT EncodedCert; /* an encoded certificate blob */ CSSM_PARSED_CERT ParsedCert; /* equivalent parsed certificate */ } CSSM_CERT_PAIR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CERT_PAIR_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -553,7 +553,7 @@ enum { CSSM_CERTGROUP_CERT_PAIR = 0x03 }; -typedef struct cssm_certgroup { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_certgroup { CSSM_CERT_TYPE CertType; CSSM_CERT_ENCODING CertEncoding; uint32 NumCerts; /* # of certificates in this list */ @@ -569,15 +569,15 @@ typedef struct cssm_certgroup { CSSM_CERTGROUP_TYPE CertGroupType; /* type of structure in the GroupList */ void *Reserved; /* reserved for implementation dependent use */ -} CSSM_CERTGROUP, *CSSM_CERTGROUP_PTR; +} CSSM_CERTGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CERTGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_base_certs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_base_certs { CSSM_TP_HANDLE TPHandle; CSSM_CL_HANDLE CLHandle; CSSM_CERTGROUP Certs; } CSSM_BASE_CERTS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_BASE_CERTS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_access_credentials { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_access_credentials { CSSM_STRING EntryTag; CSSM_BASE_CERTS BaseCerts; CSSM_SAMPLEGROUP Samples; @@ -637,12 +637,12 @@ typedef struct cssm_authorizationgroup { CSSM_ACL_AUTHORIZATION_TAG *AuthTags; } CSSM_AUTHORIZATIONGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_AUTHORIZATIONGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_acl_validity_period { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_validity_period { CSSM_DATA StartDate; CSSM_DATA EndDate; } CSSM_ACL_VALIDITY_PERIOD DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_VALIDITY_PERIOD_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_acl_entry_prototype { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_entry_prototype { CSSM_LIST TypedSubject; CSSM_BOOL Delegate; CSSM_AUTHORIZATIONGROUP Authorization; @@ -650,7 +650,7 @@ typedef struct cssm_acl_entry_prototype { CSSM_STRING EntryTag; } CSSM_ACL_ENTRY_PROTOTYPE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_ENTRY_PROTOTYPE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_acl_owner_prototype { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_owner_prototype { CSSM_LIST TypedSubject; CSSM_BOOL Delegate; } CSSM_ACL_OWNER_PROTOTYPE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_OWNER_PROTOTYPE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -659,22 +659,22 @@ typedef CSSM_RETURN (CSSMAPI * CSSM_ACL_SUBJECT_CALLBACK) (const CSSM_LIST *SubjectRequest, CSSM_LIST_PTR SubjectResponse, void *CallerContext, - const CSSM_MEMORY_FUNCS *MemFuncs); + const CSSM_MEMORY_FUNCS *MemFuncs) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_acl_entry_input { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_entry_input { CSSM_ACL_ENTRY_PROTOTYPE Prototype; CSSM_ACL_SUBJECT_CALLBACK Callback; void *CallerContext; } CSSM_ACL_ENTRY_INPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_ENTRY_INPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_resource_control_context { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_resource_control_context { CSSM_ACCESS_CREDENTIALS_PTR AccessCred; CSSM_ACL_ENTRY_INPUT InitialAclEntry; } CSSM_RESOURCE_CONTROL_CONTEXT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_RESOURCE_CONTROL_CONTEXT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef CSSM_HANDLE CSSM_ACL_HANDLE; -typedef struct cssm_acl_entry_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_entry_info { CSSM_ACL_ENTRY_PROTOTYPE EntryPublicInfo; CSSM_ACL_HANDLE EntryHandle; } CSSM_ACL_ENTRY_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_ENTRY_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -686,7 +686,7 @@ enum { CSSM_ACL_EDIT_MODE_REPLACE = 3 }; -typedef struct cssm_acl_edit { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_edit { CSSM_ACL_EDIT_MODE EditMode; CSSM_ACL_HANDLE OldEntryHandle; const CSSM_ACL_ENTRY_INPUT *NewEntry; @@ -985,7 +985,7 @@ enum { CSSM_ALGMODE_VENDOR_DEFINED = CSSM_ALGMODE_NONE + 0x80000000 }; -typedef struct cssm_keyheader { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_keyheader { CSSM_HEADERVERSION HeaderVersion; /* Key header version */ CSSM_GUID CspId; /* GUID of CSP generating the key */ CSSM_KEYBLOB_TYPE BlobType; /* See BlobType enum */ @@ -1002,12 +1002,12 @@ typedef struct cssm_keyheader { uint32 Reserved; } CSSM_KEYHEADER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KEYHEADER_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_key { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_key { CSSM_KEYHEADER KeyHeader; /* Fixed length key header */ CSSM_DATA KeyData; /* Variable length key data */ } CSSM_KEY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KEY_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef CSSM_KEY CSSM_WRAP_KEY, *CSSM_WRAP_KEY_PTR; +typedef CSSM_KEY CSSM_WRAP_KEY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_WRAP_KEY_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef uint32 CSSM_CSPTYPE; enum { @@ -1121,10 +1121,10 @@ enum { typedef CSSM_ALGORITHMS CSSM_KEY_TYPE; -typedef struct cssm_context_attribute { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_context_attribute { CSSM_ATTRIBUTE_TYPE AttributeType; uint32 AttributeLength; - union cssm_context_attribute_value { + union DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_context_attribute_value { char *String; uint32 Uint32; CSSM_ACCESS_CREDENTIALS_PTR AccessCredentials; @@ -1138,9 +1138,9 @@ typedef struct cssm_context_attribute { CSSM_DL_DB_HANDLE_PTR DLDBHandle; struct cssm_kr_profile *KRProfile; } Attribute; -} CSSM_CONTEXT_ATTRIBUTE, *CSSM_CONTEXT_ATTRIBUTE_PTR; +} CSSM_CONTEXT_ATTRIBUTE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CONTEXT_ATTRIBUTE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_context { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_context { CSSM_CONTEXT_TYPE ContextType; CSSM_ALGORITHMS AlgorithmType; uint32 NumberOfAttributes; @@ -1198,7 +1198,7 @@ enum { CSSM_PKCS_OAEP_PSOURCE_Pspecified = CSSM_PKCS_OAEP_PSOURCE_NONE + 1 }; -typedef struct cssm_pkcs1_oaep_params { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_pkcs1_oaep_params { uint32 HashAlgorithm; CSSM_DATA HashParams; CSSM_PKCS_OAEP_MGF MGF; @@ -1227,7 +1227,7 @@ enum { CSSM_VALUE_NOT_AVAILABLE = -1 }; -typedef struct cssm_pkcs5_pbkdf1_params { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_pkcs5_pbkdf1_params { CSSM_DATA Passphrase; CSSM_DATA InitVector; } CSSM_PKCS5_PBKDF1_PARAMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_PKCS5_PBKDF1_PARAMS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -1237,12 +1237,12 @@ enum { CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1 = 0 }; -typedef struct cssm_pkcs5_pbkdf2_params { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_pkcs5_pbkdf2_params { CSSM_DATA Passphrase; CSSM_PKCS5_PBKDF2_PRF PseudoRandomFunction; } CSSM_PKCS5_PBKDF2_PARAMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_PKCS5_PBKDF2_PARAMS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_kea_derive_params { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kea_derive_params { CSSM_DATA Rb; CSSM_DATA Yb; } CSSM_KEA_DERIVE_PARAMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KEA_DERIVE_PARAMS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -1250,7 +1250,7 @@ typedef struct cssm_kea_derive_params { /* Data Types for Trust Policy Services */ -typedef struct cssm_tp_authority_id { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_authority_id { CSSM_DATA *AuthorityCert; CSSM_NET_ADDRESS_PTR AuthorityLocation; } CSSM_TP_AUTHORITY_ID DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_AUTHORITY_ID_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -1270,18 +1270,18 @@ enum { typedef CSSM_RETURN (CSSMAPI * CSSM_TP_VERIFICATION_RESULTS_CALLBACK) (CSSM_MODULE_HANDLE ModuleHandle, void *CallerCtx, - CSSM_DATA_PTR VerifiedCert); + CSSM_DATA_PTR VerifiedCert) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* From CL */ -typedef CSSM_DATA CSSM_OID, *CSSM_OID_PTR; +typedef CSSM_DATA CSSM_OID DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_OID_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_field { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_field { CSSM_OID FieldOid; CSSM_DATA FieldValue; } CSSM_FIELD DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_FIELD_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* TP Again. */ -typedef struct cssm_tp_policyinfo { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_policyinfo { uint32 NumberOfPolicyIds; CSSM_FIELD_PTR PolicyIds; void *PolicyControl; @@ -1313,13 +1313,13 @@ enum { typedef char *CSSM_TIMESTRING; /* From DL. */ -typedef struct cssm_dl_db_list { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_dl_db_list { uint32 NumHandles; CSSM_DL_DB_HANDLE_PTR DLDBHandle; } CSSM_DL_DB_LIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DL_DB_LIST_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* TP Again. */ -typedef struct cssm_tp_callerauth_context { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_callerauth_context { CSSM_TP_POLICYINFO Policy; CSSM_TIMESTRING VerifyTime; CSSM_TP_STOP_ON VerificationAbortOn; @@ -1367,7 +1367,7 @@ enum { CSSM_CRL_ENCODING_MULTIPLE = 0x7FFE }; -typedef struct cssm_encoded_crl { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_encoded_crl { CSSM_CRL_TYPE CrlType; /* type of CRL */ CSSM_CRL_ENCODING CrlEncoding; /* encoding for this packed CRL */ CSSM_DATA CrlBlob; /* packed CRL */ @@ -1381,7 +1381,7 @@ typedef struct cssm_parsed_crl { void *ParsedCrl; /* parsed CRL (to be typecast) */ } CSSM_PARSED_CRL DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_PARSED_CRL_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_crl_pair { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_crl_pair { CSSM_ENCODED_CRL EncodedCrl; /* an encoded CRL blob */ CSSM_PARSED_CRL ParsedCrl; /* equivalent parsed CRL */ } CSSM_CRL_PAIR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CRL_PAIR_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -1394,7 +1394,7 @@ enum { CSSM_CRLGROUP_CRL_PAIR = 0x03 }; -typedef struct cssm_crlgroup { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_crlgroup { CSSM_CRL_TYPE CrlType; CSSM_CRL_ENCODING CrlEncoding; uint32 NumberOfCrls; @@ -1405,9 +1405,9 @@ typedef struct cssm_crlgroup { CSSM_CRL_PAIR_PTR PairCrlList; } GroupCrlList; CSSM_CRLGROUP_TYPE CrlGroupType; -} CSSM_CRLGROUP, *CSSM_CRLGROUP_PTR; +} CSSM_CRLGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CRLGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_fieldgroup { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_fieldgroup { int NumberOfFields; /* number of fields in the array */ CSSM_FIELD_PTR Fields; /* array of fields */ } CSSM_FIELDGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_FIELDGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -1426,24 +1426,24 @@ enum { CSSM_EVIDENCE_FORM_TUPLEGROUP = 0x9 }; -typedef struct cssm_evidence { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_evidence { CSSM_EVIDENCE_FORM EvidenceForm; void *Evidence; /* Evidence content */ } CSSM_EVIDENCE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_EVIDENCE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_tp_verify_context { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_verify_context { CSSM_TP_ACTION Action; CSSM_DATA ActionData; CSSM_CRLGROUP Crls; CSSM_TP_CALLERAUTH_CONTEXT_PTR Cred; } CSSM_TP_VERIFY_CONTEXT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_VERIFY_CONTEXT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_tp_verify_context_result { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_verify_context_result { uint32 NumberOfEvidences; CSSM_EVIDENCE_PTR Evidence; } CSSM_TP_VERIFY_CONTEXT_RESULT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_VERIFY_CONTEXT_RESULT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_tp_request_set { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_request_set { uint32 NumberOfRequests; void *Requests; } CSSM_TP_REQUEST_SET DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_REQUEST_SET_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -1465,7 +1465,7 @@ enum { submit-retrieve function pair */ }; -typedef struct cssm_tp_confirm_response { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_confirm_response { uint32 NumberOfResponses; CSSM_TP_CONFIRM_STATUS_PTR Responses; } CSSM_TP_CONFIRM_RESPONSE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CONFIRM_RESPONSE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -1479,7 +1479,7 @@ enum { CSSM_ELAPSED_TIME_COMPLETE = -2 }; -typedef struct cssm_tp_certissue_input { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certissue_input { CSSM_SUBSERVICE_UID CSPSubserviceUid; CSSM_CL_HANDLE CLHandle; uint32 NumberOfTemplateFields; @@ -1514,7 +1514,7 @@ enum { a revocation of the certificate */ }; -typedef struct cssm_tp_certissue_output { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certissue_output { CSSM_TP_CERTISSUE_STATUS IssueStatus; CSSM_CERTGROUP_PTR CertGroup; CSSM_TP_SERVICES PerformedServiceRequests; @@ -1571,7 +1571,7 @@ enum { jurisdiction of this certificate */ }; -typedef struct cssm_tp_certchange_input { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certchange_input { CSSM_TP_CERTCHANGE_ACTION Action; CSSM_TP_CERTCHANGE_REASON Reason; CSSM_CL_HANDLE CLHandle; @@ -1604,12 +1604,12 @@ enum { the cert state */ }; -typedef struct cssm_tp_certchange_output { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certchange_output { CSSM_TP_CERTCHANGE_STATUS ActionStatus; CSSM_FIELD RevokeInfo; } CSSM_TP_CERTCHANGE_OUTPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CERTCHANGE_OUTPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_tp_certverify_input { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certverify_input { CSSM_CL_HANDLE CLHandle; CSSM_DATA_PTR Cert; CSSM_TP_VERIFY_CONTEXT_PTR VerifyContext; @@ -1636,13 +1636,13 @@ enum { CSSM_TP_CERTVERIFY_UNKNOWN_CRITICAL_EXT = 0x10 }; -typedef struct cssm_tp_certverify_output { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certverify_output { CSSM_TP_CERTVERIFY_STATUS VerifyStatus; uint32 NumberOfEvidence; CSSM_EVIDENCE_PTR Evidence; } CSSM_TP_CERTVERIFY_OUTPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CERTVERIFY_OUTPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_tp_certnotarize_input { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certnotarize_input { CSSM_CL_HANDLE CLHandle; uint32 NumberOfFields; CSSM_FIELD_PTR MoreFields; @@ -1678,13 +1678,13 @@ enum { not authorized */ }; -typedef struct cssm_tp_certnotarize_output { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certnotarize_output { CSSM_TP_CERTNOTARIZE_STATUS NotarizeStatus; CSSM_CERTGROUP_PTR NotarizedCertGroup; CSSM_TP_SERVICES PerformedServiceRequests; } CSSM_TP_CERTNOTARIZE_OUTPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CERTNOTARIZE_OUTPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_tp_certreclaim_input { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certreclaim_input { CSSM_CL_HANDLE CLHandle; uint32 NumberOfSelectionFields; CSSM_FIELD_PTR SelectionFields; @@ -1712,13 +1712,13 @@ enum { authorized */ }; -typedef struct cssm_tp_certreclaim_output { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certreclaim_output { CSSM_TP_CERTRECLAIM_STATUS ReclaimStatus; CSSM_CERTGROUP_PTR ReclaimedCertGroup; CSSM_LONG_HANDLE KeyCacheHandle; } CSSM_TP_CERTRECLAIM_OUTPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CERTRECLAIM_OUTPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_tp_crlissue_input { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_crlissue_input { CSSM_CL_HANDLE CLHandle; uint32 CrlIdentifier; CSSM_TIMESTRING CrlThisTime; @@ -1760,7 +1760,7 @@ enum { next CRL has been returned. */ }; -typedef struct cssm_tp_crlissue_output { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_crlissue_output { CSSM_TP_CRLISSUE_STATUS IssueStatus; CSSM_ENCODED_CRL_PTR Crl; CSSM_TIMESTRING CrlNextTime; @@ -1810,12 +1810,12 @@ enum { CSSM_CERT_BUNDLE_ENCODING_PGP = 0x05 }; -typedef struct cssm_cert_bundle_header { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_cert_bundle_header { CSSM_CERT_BUNDLE_TYPE BundleType; CSSM_CERT_BUNDLE_ENCODING BundleEncoding; } CSSM_CERT_BUNDLE_HEADER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CERT_BUNDLE_HEADER_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_cert_bundle { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_cert_bundle { CSSM_CERT_BUNDLE_HEADER BundleHeader; CSSM_DATA Bundle; } CSSM_CERT_BUNDLE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CERT_BUNDLE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -1846,17 +1846,17 @@ enum { CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX = 8 }; -typedef struct cssm_db_attribute_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_attribute_info { CSSM_DB_ATTRIBUTE_NAME_FORMAT AttributeNameFormat; - union cssm_db_attribute_label { + union DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_attribute_label { char *AttributeName; /* e.g., "record label" */ CSSM_OID AttributeOID; /* e.g., CSSMOID_RECORDLABEL */ uint32 AttributeID; /* e.g., FOUR_CHAR_CODE('recl') */ } Label; CSSM_DB_ATTRIBUTE_FORMAT AttributeFormat; -} CSSM_DB_ATTRIBUTE_INFO, *CSSM_DB_ATTRIBUTE_INFO_PTR; +} CSSM_DB_ATTRIBUTE_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_ATTRIBUTE_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_db_attribute_data { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_attribute_data { CSSM_DB_ATTRIBUTE_INFO Info; uint32 NumberOfValues; CSSM_DATA_PTR Value; @@ -1899,20 +1899,20 @@ enum { CSSM_DB_CERT_USE_PRIVACY = 0x00000020 /* use cert for confidentiality only */ }; -typedef struct cssm_db_record_attribute_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_record_attribute_info { CSSM_DB_RECORDTYPE DataRecordType; uint32 NumberOfAttributes; CSSM_DB_ATTRIBUTE_INFO_PTR AttributeInfo; } CSSM_DB_RECORD_ATTRIBUTE_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_RECORD_ATTRIBUTE_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_db_record_attribute_data { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_record_attribute_data { CSSM_DB_RECORDTYPE DataRecordType; uint32 SemanticInformation; uint32 NumberOfAttributes; CSSM_DB_ATTRIBUTE_DATA_PTR AttributeData; } CSSM_DB_RECORD_ATTRIBUTE_DATA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_db_parsing_module_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_parsing_module_info { CSSM_DB_RECORDTYPE RecordType; CSSM_SUBSERVICE_UID ModuleSubserviceUid; } CSSM_DB_PARSING_MODULE_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_PARSING_MODULE_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -1930,18 +1930,18 @@ enum { CSSM_DB_INDEX_ON_RECORD = 2 }; -typedef struct cssm_db_index_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_index_info { CSSM_DB_INDEX_TYPE IndexType; CSSM_DB_INDEXED_DATA_LOCATION IndexedDataLocation; CSSM_DB_ATTRIBUTE_INFO Info; } CSSM_DB_INDEX_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_INDEX_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_db_unique_record { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_unique_record { CSSM_DB_INDEX_INFO RecordLocator; CSSM_DATA RecordIdentifier; } CSSM_DB_UNIQUE_RECORD DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_UNIQUE_RECORD_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_db_record_index_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_record_index_info { CSSM_DB_RECORDTYPE DataRecordType; uint32 NumberOfIndexes; CSSM_DB_INDEX_INFO_PTR IndexInfo; @@ -1962,7 +1962,7 @@ enum { CSSM_DB_MODIFY_ATTRIBUTE_REPLACE = CSSM_DB_MODIFY_ATTRIBUTE_NONE + 3 }; -typedef struct cssm_dbinfo { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_dbinfo { /* meta information about each record type stored in this data store including meta information about record attributes and indexes */ @@ -1994,7 +1994,7 @@ enum { CSSM_DB_OR = 2 }; -typedef struct cssm_selection_predicate { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_selection_predicate { CSSM_DB_OPERATOR DbOperator; CSSM_DB_ATTRIBUTE_DATA Attribute; } CSSM_SELECTION_PREDICATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_SELECTION_PREDICATE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -2007,7 +2007,7 @@ enum { CSSM_QUERY_SIZELIMIT_NONE = 0 }; -typedef struct cssm_query_limits { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_query_limits { uint32 TimeLimit; /* in seconds */ uint32 SizeLimit; /* max. number of records to return */ } CSSM_QUERY_LIMITS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_QUERY_LIMITS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -2017,7 +2017,7 @@ enum { CSSM_QUERY_RETURN_DATA = 0x01 }; -typedef struct cssm_query { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_query { CSSM_DB_RECORDTYPE RecordType; CSSM_DB_CONJUNCTIVE Conjunctive; uint32 NumSelectionPredicates; @@ -2062,7 +2062,7 @@ enum { CSSM_DB_FILESYSTEMSCAN_MODE = 1 }; -typedef struct cssm_db_schema_attribute_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_schema_attribute_info { uint32 AttributeId; char *AttributeName; CSSM_OID AttributeNameID; diff --git a/OSX/libsecurity_cssm/lib/emmspi.h b/OSX/libsecurity_cssm/lib/emmspi.h index 762972f2..29e5ba2f 100644 --- a/OSX/libsecurity_cssm/lib/emmspi.h +++ b/OSX/libsecurity_cssm/lib/emmspi.h @@ -37,7 +37,7 @@ extern "C" { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -typedef struct cssm_state_funcs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_state_funcs { CSSM_RETURN (CSSMAPI *cssm_GetAttachFunctions) (CSSM_MODULE_HANDLE hAddIn, CSSM_SERVICE_MASK AddinType, @@ -63,7 +63,7 @@ typedef struct cssm_state_funcs { (const CSSM_MANAGER_EVENT_NOTIFICATION *EventDescription); } CSSM_STATE_FUNCS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_STATE_FUNCS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_manager_registration_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_manager_registration_info { /* loading, unloading, dispatch table, and event notification */ CSSM_RETURN (CSSMAPI *Initialize) (uint32 VerMajor, diff --git a/OSX/libsecurity_cssm/lib/emmtype.h b/OSX/libsecurity_cssm/lib/emmtype.h index 1f3c18f1..d61b7caf 100644 --- a/OSX/libsecurity_cssm/lib/emmtype.h +++ b/OSX/libsecurity_cssm/lib/emmtype.h @@ -41,7 +41,7 @@ typedef uint32 CSSM_MANAGER_EVENT_TYPES; #define CSSM_MANAGER_SERVICE_REQUEST 1 #define CSSM_MANAGER_REPLY 2 -typedef struct cssm_manager_event_notification { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_manager_event_notification { CSSM_SERVICE_MASK DestinationModuleManagerType; CSSM_SERVICE_MASK SourceModuleManagerType; CSSM_MANAGER_EVENT_TYPES Event; diff --git a/OSX/libsecurity_cssm/lib/generator.pl b/OSX/libsecurity_cssm/lib/generator.pl index e4792ac9..c3d6802f 100644 --- a/OSX/libsecurity_cssm/lib/generator.pl +++ b/OSX/libsecurity_cssm/lib/generator.pl @@ -192,7 +192,7 @@ print "// "; while (($name, $_) = each %spi) { print "extern const char *const ${name}NameTable[] = {"; - s/^.*struct cssm_spi.*{(.*)} CSSM_SPI.*$/$1/s + s/^.*struct(?: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER)? cssm_spi.*{(.*)} CSSM_SPI.*$/$1/s or die "bad format in $SPI_H{$name}"; s/CSSM_RETURN \(CSSM[A-Z]*I \*([A-Za-z_]+)\)\s+\([^)]+\)[^;]*;/\t"$1",/g; print; diff --git a/OSX/libsecurity_cssm/lib/x509defs.h b/OSX/libsecurity_cssm/lib/x509defs.h index 1affad44..0f011608 100644 --- a/OSX/libsecurity_cssm/lib/x509defs.h +++ b/OSX/libsecurity_cssm/lib/x509defs.h @@ -70,42 +70,42 @@ typedef uint8 CSSM_BER_TAG; /* Data Structures for X.509 Certificates */ -typedef struct cssm_x509_algorithm_identifier { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_algorithm_identifier { CSSM_OID algorithm; CSSM_DATA parameters; } CSSM_X509_ALGORITHM_IDENTIFIER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_ALGORITHM_IDENTIFIER_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* X509 Distinguished name structure */ -typedef struct cssm_x509_type_value_pair { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_type_value_pair { CSSM_OID type; CSSM_BER_TAG valueType; /* The Tag to be used when */ /*this value is BER encoded */ CSSM_DATA value; } CSSM_X509_TYPE_VALUE_PAIR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_TYPE_VALUE_PAIR_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509_rdn { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_rdn { uint32 numberOfPairs; CSSM_X509_TYPE_VALUE_PAIR_PTR AttributeTypeAndValue; } CSSM_X509_RDN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_RDN_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509_name { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_name { uint32 numberOfRDNs; CSSM_X509_RDN_PTR RelativeDistinguishedName; } CSSM_X509_NAME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_NAME_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* Public key info struct */ -typedef struct cssm_x509_subject_public_key_info { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_subject_public_key_info { CSSM_X509_ALGORITHM_IDENTIFIER algorithm; CSSM_DATA subjectPublicKey; } CSSM_X509_SUBJECT_PUBLIC_KEY_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_SUBJECT_PUBLIC_KEY_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509_time { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_time { CSSM_BER_TAG timeType; CSSM_DATA time; } CSSM_X509_TIME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_TIME_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* Validity struct */ -typedef struct x509_validity { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER x509_validity { CSSM_X509_TIME notBefore; CSSM_X509_TIME notAfter; } CSSM_X509_VALIDITY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_VALIDITY_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -114,7 +114,7 @@ typedef struct x509_validity { #define CSSM_X509_OPTION_NOT_PRESENT CSSM_FALSE typedef CSSM_BOOL CSSM_X509_OPTION; -typedef struct cssm_x509ext_basicConstraints { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_basicConstraints { CSSM_BOOL cA; CSSM_X509_OPTION pathLenConstraintPresent; uint32 pathLenConstraint; @@ -126,22 +126,22 @@ typedef enum extension_data_format { CSSM_X509_DATAFORMAT_PAIR } CSSM_X509EXT_DATA_FORMAT; -typedef struct cssm_x509_extensionTagAndValue { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_extensionTagAndValue { CSSM_BER_TAG type; CSSM_DATA value; } CSSM_X509EXT_TAGandVALUE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_TAGandVALUE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509ext_pair { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_pair { CSSM_X509EXT_TAGandVALUE tagAndValue; void *parsedValue; } CSSM_X509EXT_PAIR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_PAIR_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* Extension structure */ -typedef struct cssm_x509_extension { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_extension { CSSM_OID extnId; CSSM_BOOL critical; CSSM_X509EXT_DATA_FORMAT format; - union cssm_x509ext_value { + union DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_value { CSSM_X509EXT_TAGandVALUE *tagAndValue; void *parsedValue; CSSM_X509EXT_PAIR *valuePair; @@ -149,13 +149,13 @@ typedef struct cssm_x509_extension { CSSM_DATA BERvalue; } CSSM_X509_EXTENSION DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_EXTENSION_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509_extensions { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_extensions { uint32 numberOfExtensions; CSSM_X509_EXTENSION_PTR extensions; } CSSM_X509_EXTENSIONS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_EXTENSIONS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* X509V3 certificate structure */ -typedef struct cssm_x509_tbs_certificate { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_tbs_certificate { CSSM_DATA version; CSSM_DATA serialNumber; CSSM_X509_ALGORITHM_IDENTIFIER signature; @@ -169,28 +169,28 @@ typedef struct cssm_x509_tbs_certificate { } CSSM_X509_TBS_CERTIFICATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_TBS_CERTIFICATE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* Signature structure */ -typedef struct cssm_x509_signature { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_signature { CSSM_X509_ALGORITHM_IDENTIFIER algorithmIdentifier; CSSM_DATA encrypted; } CSSM_X509_SIGNATURE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_SIGNATURE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* Signed certificate structure */ -typedef struct cssm_x509_signed_certificate { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_signed_certificate { CSSM_X509_TBS_CERTIFICATE certificate; CSSM_X509_SIGNATURE signature; } CSSM_X509_SIGNED_CERTIFICATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_SIGNED_CERTIFICATE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509ext_policyQualifierInfo { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_policyQualifierInfo { CSSM_OID policyQualifierId; CSSM_DATA value; } CSSM_X509EXT_POLICYQUALIFIERINFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_POLICYQUALIFIERINFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509ext_policyQualifiers { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_policyQualifiers { uint32 numberOfPolicyQualifiers; CSSM_X509EXT_POLICYQUALIFIERINFO *policyQualifier; } CSSM_X509EXT_POLICYQUALIFIERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_POLICYQUALIFIERS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509ext_policyInfo { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_policyInfo { CSSM_OID policyIdentifier; CSSM_X509EXT_POLICYQUALIFIERS policyQualifiers; } CSSM_X509EXT_POLICYINFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_POLICYINFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -199,19 +199,19 @@ typedef struct cssm_x509ext_policyInfo { /* Data Structures for X.509 Certificate Revocations Lists */ /* x509V2 entry in the CRL revokedCertificates sequence */ -typedef struct cssm_x509_revoked_cert_entry { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_revoked_cert_entry { CSSM_DATA certificateSerialNumber; CSSM_X509_TIME revocationDate; CSSM_X509_EXTENSIONS extensions; } CSSM_X509_REVOKED_CERT_ENTRY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_REVOKED_CERT_ENTRY_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509_revoked_cert_list { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_revoked_cert_list { uint32 numberOfRevokedCertEntries; CSSM_X509_REVOKED_CERT_ENTRY_PTR revokedCertEntry; } CSSM_X509_REVOKED_CERT_LIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_REVOKED_CERT_LIST_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* x509v2 Certificate Revocation List (CRL) (unsigned) structure */ -typedef struct cssm_x509_tbs_certlist { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_tbs_certlist { CSSM_DATA version; CSSM_X509_ALGORITHM_IDENTIFIER signature; CSSM_X509_NAME issuer; @@ -221,7 +221,7 @@ typedef struct cssm_x509_tbs_certlist { CSSM_X509_EXTENSIONS extensions; } CSSM_X509_TBS_CERTLIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_TBS_CERTLIST_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct cssm_x509_signed_crl { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_signed_crl { CSSM_X509_TBS_CERTLIST tbsCertList; CSSM_X509_SIGNATURE signature; } CSSM_X509_SIGNED_CRL DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_SIGNED_CRL_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; diff --git a/OSX/libsecurity_keychain/lib/CCallbackMgr.cp b/OSX/libsecurity_keychain/lib/CCallbackMgr.cp index 6fac59b6..96da5d8e 100644 --- a/OSX/libsecurity_keychain/lib/CCallbackMgr.cp +++ b/OSX/libsecurity_keychain/lib/CCallbackMgr.cp @@ -310,7 +310,23 @@ void CCallbackMgr::consume (SecurityServer::NotificationDomain domain, SecurityS Keychain thisKeychain; Item thisItem; - list eventCallbacks; + list eventCallbacks = CCallbackMgr::Instance().mEventCallbacks; + + // First, does this process care about this notification? If not, just exit early. + bool careAboutEventType = thisEvent == kSecDeleteEvent || thisEvent == kSecKeychainListChangedEvent; + bool registeredCallbacksForEventType = false; + for (ConstCallbackInfoListIterator ix = eventCallbacks.begin(); ix != eventCallbacks.end(); ++ix) + { + if ((ix->mEventMask & (1U << thisEvent))) { + registeredCallbacksForEventType = true; + break; + } + } + if(!careAboutEventType && !registeredCallbacksForEventType) { + secinfo("kcnotify", "not processing uninteresting event (%d)", (unsigned int)thisEvent); + return; + } + { // Lock the global API lock before doing stuff with StorageManager. // make sure we have a database identifier @@ -342,7 +358,6 @@ void CCallbackMgr::consume (SecurityServer::NotificationDomain domain, SecurityS else if (thisEvent == kSecKeychainListChangedEvent) globals().storageManager.forceUserSearchListReread(); - eventCallbacks = CCallbackMgr::Instance().mEventCallbacks; // We can safely release the global API lock now since thisKeychain and thisItem // are CFRetained and will be until they go out of scope. } diff --git a/OSX/libsecurity_keychain/lib/KeyItem.cpp b/OSX/libsecurity_keychain/lib/KeyItem.cpp index 12f7113f..04095492 100644 --- a/OSX/libsecurity_keychain/lib/KeyItem.cpp +++ b/OSX/libsecurity_keychain/lib/KeyItem.cpp @@ -81,6 +81,7 @@ KeyItem::operator CFTypeRef() const throw() if (mWeakSecKeyRef != NULL) { if (_CFTryRetain(mWeakSecKeyRef) == NULL) { + StMaybeLock secKeyCDSAMutex(mWeakSecKeyRef->cdsaKeyMutex); // mWeakSecKeyRef is not really valid, pointing to SecKeyRef which going to die - it is somewhere between last CFRelease and entering into mutex-protected section of SecCDSAKeyDestroy. Avoid using it, pretend that no enveloping SecKeyRef exists. But make sure that this KeyImpl is disconnected from this about-to-die SecKeyRef, because we do not want KeyImpl connected to it to be really destroyed, it will be connected to newly created SecKeyRef (see below). mWeakSecKeyRef->key = NULL; mWeakSecKeyRef = NULL; diff --git a/OSX/libsecurity_keychain/lib/KeyItem.h b/OSX/libsecurity_keychain/lib/KeyItem.h index 54691919..a1a6716c 100644 --- a/OSX/libsecurity_keychain/lib/KeyItem.h +++ b/OSX/libsecurity_keychain/lib/KeyItem.h @@ -170,6 +170,7 @@ struct OpaqueSecKeyRef { SecKeyRef cdsaKey; Security::KeychainCore::KeyItem *key; SecCredentialType credentialType; + Mutex *cdsaKeyMutex; }; #endif // !_SECURITY_KEYITEM_H_ diff --git a/OSX/libsecurity_keychain/lib/PolicyCursor.cpp b/OSX/libsecurity_keychain/lib/PolicyCursor.cpp index aa12338f..d8db218b 100644 --- a/OSX/libsecurity_keychain/lib/PolicyCursor.cpp +++ b/OSX/libsecurity_keychain/lib/PolicyCursor.cpp @@ -42,26 +42,29 @@ struct TheOneTP : public TP { }; static ModuleNexus theOneTP; -static const CssmOid *theOidList[] = { - static_cast(&CSSMOID_APPLE_ISIGN), - static_cast(&CSSMOID_APPLE_X509_BASIC), - static_cast(&CSSMOID_APPLE_TP_SSL), - static_cast(&CSSMOID_APPLE_TP_SMIME), - static_cast(&CSSMOID_APPLE_TP_EAP), - static_cast(&CSSMOID_APPLE_TP_SW_UPDATE_SIGNING), - static_cast(&CSSMOID_APPLE_TP_IP_SEC), - static_cast(&CSSMOID_APPLE_TP_ICHAT), - static_cast(&CSSMOID_APPLE_TP_RESOURCE_SIGN), - static_cast(&CSSMOID_APPLE_TP_PKINIT_CLIENT), - static_cast(&CSSMOID_APPLE_TP_PKINIT_SERVER), - static_cast(&CSSMOID_APPLE_TP_CODE_SIGNING), - static_cast(&CSSMOID_APPLE_TP_PACKAGE_SIGNING), - static_cast(&CSSMOID_APPLE_TP_REVOCATION_CRL), - static_cast(&CSSMOID_APPLE_TP_REVOCATION_OCSP), - static_cast(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT), - static_cast(&CSSMOID_APPLE_TP_APPLEID_SHARING), - static_cast(&CSSMOID_APPLE_TP_TIMESTAMPING), - NULL // sentinel +static const CssmOid** theOidList() { + static const CssmOid* list[] = { + static_cast(&CSSMOID_APPLE_ISIGN), + static_cast(&CSSMOID_APPLE_X509_BASIC), + static_cast(&CSSMOID_APPLE_TP_SSL), + static_cast(&CSSMOID_APPLE_TP_SMIME), + static_cast(&CSSMOID_APPLE_TP_EAP), + static_cast(&CSSMOID_APPLE_TP_SW_UPDATE_SIGNING), + static_cast(&CSSMOID_APPLE_TP_IP_SEC), + static_cast(&CSSMOID_APPLE_TP_ICHAT), + static_cast(&CSSMOID_APPLE_TP_RESOURCE_SIGN), + static_cast(&CSSMOID_APPLE_TP_PKINIT_CLIENT), + static_cast(&CSSMOID_APPLE_TP_PKINIT_SERVER), + static_cast(&CSSMOID_APPLE_TP_CODE_SIGNING), + static_cast(&CSSMOID_APPLE_TP_PACKAGE_SIGNING), + static_cast(&CSSMOID_APPLE_TP_REVOCATION_CRL), + static_cast(&CSSMOID_APPLE_TP_REVOCATION_OCSP), + static_cast(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT), + static_cast(&CSSMOID_APPLE_TP_APPLEID_SHARING), + static_cast(&CSSMOID_APPLE_TP_TIMESTAMPING), + NULL // sentinel + }; + return list; }; @@ -94,13 +97,13 @@ bool PolicyCursor::next(SecPointer &policy) { StLock_(mMutex); - while (theOidList[mSearchPos]) { - if (mOidGiven && mOid != *theOidList[mSearchPos]) { + while (theOidList()[mSearchPos]) { + if (mOidGiven && mOid != *(theOidList()[mSearchPos])) { mSearchPos++; continue; // no oid match } // ignoring mValue - not used by current TP - policy = new Policy(theOneTP(), *theOidList[mSearchPos]); + policy = new Policy(theOneTP(), *(theOidList()[mSearchPos])); mSearchPos++; // advance cursor return true; // return next match } diff --git a/OSX/libsecurity_keychain/lib/SecAccess.h b/OSX/libsecurity_keychain/lib/SecAccess.h index 2ba66080..4a8340d4 100644 --- a/OSX/libsecurity_keychain/lib/SecAccess.h +++ b/OSX/libsecurity_keychain/lib/SecAccess.h @@ -127,7 +127,7 @@ CFTypeID SecAccessGetTypeID(void); @param accessRef On return, a pointer to the new access reference. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecAccessCreate(CFStringRef descriptor, CFArrayRef __nullable trustedlist, SecAccessRef * __nonnull CF_RETURNS_RETAINED accessRef); +OSStatus SecAccessCreate(CFStringRef descriptor, CFArrayRef __nullable trustedlist, SecAccessRef * __nonnull CF_RETURNS_RETAINED accessRef) API_UNAVAILABLE(ios); /*! @function SecAccessCreateFromOwnerAndACL @@ -189,7 +189,7 @@ OSStatus SecAccessCopyOwnerAndACL(SecAccessRef accessRef, uid_t * __nullable use @param aclList On return, a pointer to a new created CFArray of SecACL instances. The caller is responsible for calling CFRelease on this array. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecAccessCopyACLList(SecAccessRef accessRef, CFArrayRef * __nonnull CF_RETURNS_RETAINED aclList); +OSStatus SecAccessCopyACLList(SecAccessRef accessRef, CFArrayRef * __nonnull CF_RETURNS_RETAINED aclList) API_UNAVAILABLE(ios); /*! @function SecAccessCopySelectedACLList diff --git a/OSX/libsecurity_keychain/lib/SecAccessPriv.h b/OSX/libsecurity_keychain/lib/SecAccessPriv.h index 4e61067e..cf665b3a 100644 --- a/OSX/libsecurity_keychain/lib/SecAccessPriv.h +++ b/OSX/libsecurity_keychain/lib/SecAccessPriv.h @@ -40,7 +40,7 @@ extern "C" { #endif OSStatus SecKeychainAddIToolsPassword(SecKeychainRef keychain, UInt32 accountNameLength, const char *accountName, - UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) __deprecated_msg("iTools is no longer supported"); + UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) __deprecated_msg("iTools is no longer supported") API_UNAVAILABLE(ios); /*! @function SecAccessCreateWithTrustedApplications @@ -53,7 +53,7 @@ OSStatus SecKeychainAddIToolsPassword(SecKeychainRef keychain, UInt32 accountNam @discussion The SecAccessCreateWithPList creates a SecAccess with the provided list of trusted applications. */ -OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath, CFStringRef accessLabel, Boolean allowAny, SecAccessRef* returnedAccess); +OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath, CFStringRef accessLabel, Boolean allowAny, SecAccessRef* returnedAccess) API_UNAVAILABLE(ios); #if defined(__cplusplus) diff --git a/OSX/libsecurity_keychain/lib/SecBase.cpp b/OSX/libsecurity_keychain/lib/SecBase.cpp index b9633314..2f5c1571 100644 --- a/OSX/libsecurity_keychain/lib/SecBase.cpp +++ b/OSX/libsecurity_keychain/lib/SecBase.cpp @@ -27,6 +27,7 @@ #include #include #include "SecBridge.h" +#include "SecFramework.h" static CFStringRef copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName); diff --git a/OSX/libsecurity_keychain/lib/SecCertificate.cpp b/OSX/libsecurity_keychain/lib/SecCertificate.cpp index ea044d6c..dcd447b4 100644 --- a/OSX/libsecurity_keychain/lib/SecCertificate.cpp +++ b/OSX/libsecurity_keychain/lib/SecCertificate.cpp @@ -52,11 +52,7 @@ OSStatus SecCertificateGetCLHandle_legacy(SecCertificateRef certificate, CSSM_CL_HANDLE *clHandle); extern CSSM_KEYUSE ConvertArrayToKeyUsage(CFArrayRef usage); -#define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v); -SEC_CONST_DECL (kSecCertificateProductionEscrowKey, "ProductionEscrowKey"); -SEC_CONST_DECL (kSecCertificateProductionPCSEscrowKey, "ProductionPCSEscrowKey"); -SEC_CONST_DECL (kSecCertificateEscrowFileName, "AppleESCertificates"); using namespace CssmClient; @@ -791,20 +787,28 @@ OSStatus SecCertificateSetPreference( const char *templateStr = "%s [key usage 0x%X]"; const int keyUsageMaxStrLen = 8; accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen; - char accountUTF8[accountUTF8Len]; + char *accountUTF8 = (char *)malloc(accountUTF8Len); + if (!accountUTF8) { + MacOSError::throwMe(errSecMemoryError); + } if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8)) accountUTF8[0] = (char)'\0'; if (keyUsage) snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage); - CssmData account(const_cast(accountUTF8), strlen(accountUTF8)); + CssmDataContainer account(const_cast(accountUTF8), strlen(accountUTF8)); + free(accountUTF8); CFRelease(labelStr); // service attribute (name provided by the caller) CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), kCFStringEncodingUTF8) + 1;; - char serviceUTF8[serviceUTF8Len]; + char *serviceUTF8 = (char *)malloc(serviceUTF8Len); + if (!serviceUTF8) { + MacOSError::throwMe(errSecMemoryError); + } if (!CFStringGetCString(name, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8)) serviceUTF8[0] = (char)'\0'; - CssmData service(const_cast(serviceUTF8), strlen(serviceUTF8)); + CssmDataContainer service(const_cast(serviceUTF8), strlen(serviceUTF8)); + free(serviceUTF8); // look for existing preference item, in case this is an update StorageManager::KeychainList keychains; diff --git a/OSX/libsecurity_keychain/lib/SecCertificateBundle.h b/OSX/libsecurity_keychain/lib/SecCertificateBundle.h index f63160e0..d2bc3e10 100644 --- a/OSX/libsecurity_keychain/lib/SecCertificateBundle.h +++ b/OSX/libsecurity_keychain/lib/SecCertificateBundle.h @@ -53,7 +53,7 @@ OSStatus SecCertificateBundleImport( const CSSM_CERT_BUNDLE* bundle, CSSM_CERT_BUNDLE_TYPE type, CSSM_CERT_BUNDLE_ENCODING encodingType, - CFArrayRef keychainListToSkipDuplicates); + CFArrayRef keychainListToSkipDuplicates) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function SecCertificateBundleExport @@ -68,7 +68,7 @@ OSStatus SecCertificateBundleExport( CFArrayRef certificates, CSSM_CERT_BUNDLE_TYPE type, CSSM_CERT_BUNDLE_ENCODING encodingType, - CSSM_DATA* data); + CSSM_DATA* data) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; #if defined(__cplusplus) } diff --git a/OSX/libsecurity_keychain/lib/SecIdentity.cpp b/OSX/libsecurity_keychain/lib/SecIdentity.cpp index 79818db9..5d21959b 100644 --- a/OSX/libsecurity_keychain/lib/SecIdentity.cpp +++ b/OSX/libsecurity_keychain/lib/SecIdentity.cpp @@ -596,21 +596,29 @@ OSStatus SecIdentitySetPreference( const char *templateStr = "%s [key usage 0x%X]"; const int keyUsageMaxStrLen = 8; accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen; - char accountUTF8[accountUTF8Len]; + char *accountUTF8 = (char *)malloc(accountUTF8Len); + if (!accountUTF8) { + MacOSError::throwMe(errSecMemoryError); + } if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8)) accountUTF8[0] = (char)'\0'; if (keyUsage) snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage); snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8); - CssmData account(const_cast(accountUTF8), strlen(accountUTF8)); + CssmDataContainer account(const_cast(accountUTF8), strlen(accountUTF8)); + free(accountUTF8); CFRelease(labelStr); // service attribute (name provided by the caller) CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), kCFStringEncodingUTF8) + 1;; - char serviceUTF8[serviceUTF8Len]; + char *serviceUTF8 = (char *)malloc(serviceUTF8Len); + if (!serviceUTF8) { + MacOSError::throwMe(errSecMemoryError); + } if (!CFStringGetCString(name, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8)) serviceUTF8[0] = (char)'\0'; - CssmData service(const_cast(serviceUTF8), strlen(serviceUTF8)); + CssmDataContainer service(const_cast(serviceUTF8), strlen(serviceUTF8)); + free(serviceUTF8); // look for existing identity preference item, in case this is an update StorageManager::KeychainList keychains; @@ -820,21 +828,29 @@ OSStatus _SecIdentityAddPreferenceItemWithName( const char *templateStr = "%s [key usage 0x%X]"; const int keyUsageMaxStrLen = 8; accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen; - char accountUTF8[accountUTF8Len]; + char *accountUTF8 = (char *)malloc(accountUTF8Len); + if (!accountUTF8) { + MacOSError::throwMe(errSecMemoryError); + } if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8)) accountUTF8[0] = (char)'\0'; if (keyUsage) snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage); snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8); - CssmData account(const_cast(accountUTF8), strlen(accountUTF8)); + CssmDataContainer account(const_cast(accountUTF8), strlen(accountUTF8)); + free(accountUTF8); CFRelease(labelStr); // service attribute (name provided by the caller) CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(idString), kCFStringEncodingUTF8) + 1;; - char serviceUTF8[serviceUTF8Len]; + char *serviceUTF8 = (char *)malloc(serviceUTF8Len); + if (!serviceUTF8) { + MacOSError::throwMe(errSecMemoryError); + } if (!CFStringGetCString(idString, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8)) serviceUTF8[0] = (char)'\0'; - CssmData service(const_cast(serviceUTF8), strlen(serviceUTF8)); + CssmDataContainer service(const_cast(serviceUTF8), strlen(serviceUTF8)); + free(serviceUTF8); // set item attribute values item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), service); @@ -992,15 +1008,19 @@ OSStatus SecIdentityUpdatePreferenceItem( const char *templateStr = "%s [key usage 0x%X]"; const int keyUsageMaxStrLen = 8; accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen; - char accountUTF8[accountUTF8Len]; - if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8)) + char *accountUTF8 = (char *)malloc(accountUTF8Len); + if (!accountUTF8) { + MacOSError::throwMe(errSecMemoryError); + } + if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8)) accountUTF8[0] = (char)'\0'; if (keyUsage) snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage); snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8); - CssmData account(const_cast(accountUTF8), strlen(accountUTF8)); + CssmDataContainer account(const_cast(accountUTF8), strlen(accountUTF8)); prefItem->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account); - CFRelease(labelStr); + free(accountUTF8); + CFRelease(labelStr); // generic attribute (store persistent certificate reference) CFDataRef pItemRef = nil; diff --git a/OSX/libsecurity_keychain/lib/SecImportExport.c b/OSX/libsecurity_keychain/lib/SecImportExport.c index 4ef8cd77..38701153 100644 --- a/OSX/libsecurity_keychain/lib/SecImportExport.c +++ b/OSX/libsecurity_keychain/lib/SecImportExport.c @@ -24,8 +24,8 @@ #include #include #include -//#include #include +#include #include #include #include @@ -227,21 +227,10 @@ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArray // key ID if (!status) { - SecKeyRef itemKey = NULL; - status = SecCertificateCopyPublicKey(itemCert, &itemKey); - if (!status) { - const CSSM_KEY *cssmKey; - status = SecKeyGetCSSMKey(itemKey, &cssmKey); - if (!status) { - unsigned char hash[CC_SHA1_DIGEST_LENGTH]; - CC_SHA1(cssmKey->KeyData.Data, (CC_LONG)cssmKey->KeyData.Length, &hash[0]); - CFDataRef digest = CFDataCreate(NULL, (const UInt8 *)hash, CC_SHA1_DIGEST_LENGTH); - if (digest) { - CFDictionaryAddValue(itemDict, kSecImportItemKeyID, digest); - CFRelease(digest); - } - } - CFRelease(itemKey); + CFDataRef digest = SecCertificateCopyPublicKeySHA1Digest(itemCert); + if (digest) { + CFDictionaryAddValue(itemDict, kSecImportItemKeyID, digest); + CFRelease(digest); } } diff --git a/OSX/libsecurity_keychain/lib/SecImportExportUtils.cpp b/OSX/libsecurity_keychain/lib/SecImportExportUtils.cpp index a748ee6e..ab2017ec 100644 --- a/OSX/libsecurity_keychain/lib/SecImportExportUtils.cpp +++ b/OSX/libsecurity_keychain/lib/SecImportExportUtils.cpp @@ -760,6 +760,7 @@ static CSSM_RETURN impExpCreatePassKey( &ccHand); if(crtn) { SecImpExpDbg("impExpCreatePassKey: CSSM_CSP_CreateKeyGenContext error"); + free(ourKey); return crtn; } /* subsequent errors to errOut: */ diff --git a/OSX/libsecurity_keychain/lib/SecItem.cpp b/OSX/libsecurity_keychain/lib/SecItem.cpp index ac9a9e6f..ab0419a2 100644 --- a/OSX/libsecurity_keychain/lib/SecItem.cpp +++ b/OSX/libsecurity_keychain/lib/SecItem.cpp @@ -54,6 +54,7 @@ #include #include #include +#include const uint8_t kUUIDStringLength = 36; @@ -80,6 +81,7 @@ bool _SecItemParsePersistentRef(CFDataRef persistent_ref, CFStringRef *return_cl } static Boolean SecItemSynchronizable(CFDictionaryRef query); +static CFArrayRef _CopyMatchingIssuers(CFArrayRef issuers); static void secitemlog(int priority, const char *format, ...) { @@ -3074,11 +3076,12 @@ _CreateSecItemParamsFromDictionary(CFDictionaryRef dict, OSStatus *error) require_action(!(itemParams->itemClass == 0 && !itemParams->useItems), error_exit, status = errSecItemClassMissing); } - // kSecMatchIssuers is only permitted with identities. + // kSecMatchIssuers is only permitted with identities or certificates. // Convert the input issuers to normalized form. require_noerr(status = _ValidateDictionaryEntry(dict, kSecMatchIssuers, (const void **)&itemParams->matchIssuers, CFArrayGetTypeID(), NULL), error_exit); if (itemParams->matchIssuers) { - require_action(itemParams->returnIdentity, error_exit, status = errSecParam); + CFTypeRef allowCerts = CFDictionaryGetValue(itemParams->query, kSecUseCertificatesWithMatchIssuers); + require_action(itemParams->returnIdentity || (allowCerts && CFEqual(allowCerts, kCFBooleanTrue)), error_exit, status = errSecParam); CFMutableArrayRef canonical_issuers = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFArrayRef issuers = (CFArrayRef)itemParams->matchIssuers; if (canonical_issuers) { @@ -4030,15 +4033,23 @@ static OSStatus SecItemCategorizeQuery(CFDictionaryRef query, bool &can_target_i can_target_osx = can_target_ios = true; // Check no-legacy flag. - CFTypeRef value = CFDictionaryGetValue(query, kSecAttrNoLegacy); - if (value != NULL) { - can_target_ios = readNumber(value) != 0; + // it's iOS or bust if we're on MZ! + CFTypeRef noLegacy = NULL; + if (_CFMZEnabled()) { + noLegacy = kCFBooleanTrue; + } + else { + noLegacy = CFDictionaryGetValue(query, kSecAttrNoLegacy); + } + + if (noLegacy != NULL) { + can_target_ios = readNumber(noLegacy) != 0; can_target_osx = !can_target_ios; return errSecSuccess; } // Check whether the query contains kSecValueRef and modify can_ flags according to the kind and type of the value. - value = CFDictionaryGetValue(query, kSecValueRef); + CFTypeRef value = CFDictionaryGetValue(query, kSecValueRef); if (value != NULL) { CFTypeID typeID = CFGetTypeID(value); if (typeID == SecKeyGetTypeID()) { @@ -4102,6 +4113,13 @@ static OSStatus SecItemCategorizeQuery(CFDictionaryRef query, bool &can_target_i can_target_ios = can_target_ios && !CFDictionaryContainsKey(query, *osx_only_items[i]); } + // Absence of all of kSecItemClass, kSecValuePersistentRef, and kSecValueRef means that the query can't target iOS + if(CFDictionaryGetValue(query, kSecClass) == NULL && + CFDictionaryGetValue(query, kSecValuePersistentRef) == NULL && + CFDictionaryGetValue(query, kSecValueRef) == NULL) { + can_target_ios = false; + } + return (can_target_ios || can_target_osx) ? errSecSuccess : errSecParam; } @@ -4317,13 +4335,16 @@ SecItemValidateAppleApplicationGroupAccess(CFStringRef group) return status; } -static Mutex gParentCertCacheLock; +static Mutex& gParentCertCacheLock() { + static Mutex fParentCertCacheLock; + return fParentCertCacheLock; +} static CFMutableDictionaryRef gParentCertCache; static CFMutableArrayRef gParentCertCacheList; #define PARENT_CACHE_SIZE 100 void SecItemParentCachePurge() { - StLock _(gParentCertCacheLock); + StLock _(gParentCertCacheLock()); CFReleaseNull(gParentCertCache); CFReleaseNull(gParentCertCacheList); } @@ -4334,7 +4355,7 @@ static CFArrayRef CF_RETURNS_RETAINED parentCacheRead(SecCertificateRef certific CFDataRef digest = SecCertificateGetSHA1Digest(certificate); if (!digest) return NULL; - StLock _(gParentCertCacheLock); + StLock _(gParentCertCacheLock()); if (gParentCertCache && gParentCertCacheList) { if (0 <= (ix = CFArrayGetFirstIndexOfValue(gParentCertCacheList, CFRangeMake(0, CFArrayGetCount(gParentCertCacheList)), @@ -4353,7 +4374,7 @@ static void parentCacheWrite(SecCertificateRef certificate, CFArrayRef parents) CFDataRef digest = SecCertificateGetSHA1Digest(certificate); if (!digest) return; - StLock _(gParentCertCacheLock); + StLock _(gParentCertCacheLock()); if (!gParentCertCache || !gParentCertCacheList) { CFReleaseNull(gParentCertCache); gParentCertCache = makeCFMutableDictionary(); @@ -4369,6 +4390,7 @@ static void parentCacheWrite(SecCertificateRef certificate, CFArrayRef parents) CFDictionaryAddValue(gParentCertCache, digest, parents); if (PARENT_CACHE_SIZE <= CFArrayGetCount(gParentCertCacheList)) { // Remove least recently used cache entry. + CFDictionaryRemoveValue(gParentCertCache, CFArrayGetValueAtIndex(gParentCertCacheList, 0)); CFArrayRemoveValueAtIndex(gParentCertCacheList, 0); } CFArrayAppendValue(gParentCertCacheList, digest); @@ -4483,11 +4505,10 @@ SecCertificateRef SecItemCopyStoredCertificate(SecCertificateRef certificate, vo #pragma unused (context) /* for now; in future this can reference a container object */ /* Certificates are unique by issuer and serial number. */ + CFDataRef serialNumber = SecCertificateCopySerialNumberData(certificate, NULL); #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - CFDataRef serialNumber = SecCertificateCopySerialNumber(certificate, NULL); CFDataRef normalizedIssuer = SecCertificateCopyNormalizedIssuerContent(certificate, NULL); #else - CFDataRef serialNumber = SecCertificateCopySerialNumber(certificate); CFDataRef normalizedIssuer = SecCertificateGetNormalizedIssuerContent(certificate); CFRetainSafe(normalizedIssuer); #endif @@ -4659,6 +4680,18 @@ SecItemCopyTranslatedAttributes(CFDictionaryRef inOSXDict, CFTypeRef itemClass, * which won't work once the item is updated. */ CFDictionaryRemoveValue(result, kSecAttrModificationDate); + + /* Find all intermediate certificates in OSX keychain and append them in to the kSecMatchIssuers. + * This is required because secd cannot do query in to the OSX keychain + */ + CFTypeRef matchIssuers = CFDictionaryGetValue(result, kSecMatchIssuers); + if (matchIssuers && CFGetTypeID(matchIssuers) == CFArrayGetTypeID()) { + CFArrayRef newMatchIssuers = _CopyMatchingIssuers((CFArrayRef)matchIssuers); + if (newMatchIssuers) { + CFDictionarySetValue(result, kSecMatchIssuers, newMatchIssuers); + CFRelease(newMatchIssuers); + } + } } else { /* iOS doesn't add the class attribute, so we must do it here. */ @@ -4681,6 +4714,46 @@ SecItemCopyTranslatedAttributes(CFDictionaryRef inOSXDict, CFTypeRef itemClass, } /* extern "C" */ +static CFArrayRef +_CopyMatchingIssuers(CFArrayRef matchIssuers) { + CFMutableArrayRef result = NULL; + CFMutableDictionaryRef query = NULL; + CFMutableDictionaryRef policyProperties = NULL; + SecPolicyRef policy = NULL; + CFTypeRef matchedCertificates = NULL; + + require_quiet(policyProperties = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), out); + CFDictionarySetValue(policyProperties, kSecPolicyKU_KeyCertSign, kCFBooleanTrue); + require_quiet(policy = SecPolicyCreateWithProperties(kSecPolicyAppleX509Basic, policyProperties), out); + + require_quiet(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), out); + CFDictionarySetValue(query, kSecClass, kSecClassCertificate); + CFDictionarySetValue(query, kSecMatchIssuers, matchIssuers); + CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll); + CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue); + CFDictionarySetValue(query, kSecUseCertificatesWithMatchIssuers, kCFBooleanTrue); + CFDictionarySetValue(query, kSecMatchPolicy, policy); + + if (SecItemCopyMatching_osx(query, &matchedCertificates) == errSecSuccess && CFGetTypeID(matchedCertificates) == CFArrayGetTypeID()) { + require_quiet(result = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, (CFArrayRef)matchedCertificates), out); + for(CFIndex i = 0; i < CFArrayGetCount((CFArrayRef)matchedCertificates); ++i) { + CFDictionaryRef attributes = (CFDictionaryRef)CFArrayGetValueAtIndex((CFArrayRef)matchedCertificates, i); + CFTypeRef subject = CFDictionaryGetValue(attributes, kSecAttrSubject); + if (!CFArrayContainsValue(result, CFRangeMake(0, CFArrayGetCount(result)), subject)) { + CFArrayAppendValue(result, subject); + } + } + } + +out: + CFReleaseSafe(query); + CFReleaseSafe(policyProperties); + CFReleaseSafe(policy); + CFReleaseSafe(matchedCertificates); + + return result; +} + static OSStatus SecItemMergeResults(bool can_target_ios, OSStatus status_ios, CFTypeRef result_ios, bool can_target_osx, OSStatus status_osx, CFTypeRef result_osx, diff --git a/OSX/libsecurity_keychain/lib/SecItemConstants.c b/OSX/libsecurity_keychain/lib/SecItemConstants.c index 50657944..4f56a5c7 100644 --- a/OSX/libsecurity_keychain/lib/SecItemConstants.c +++ b/OSX/libsecurity_keychain/lib/SecItemConstants.c @@ -28,220 +28,223 @@ #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v); +// See the other SecItemContants.c for actual definitions + /* Class Key Constant */ -SEC_CONST_DECL (kSecClass, "class"); +//SEC_CONST_DECL (kSecClass, "class"); /* Class Value Constants */ -SEC_CONST_DECL (kSecClassGenericPassword, "genp"); -SEC_CONST_DECL (kSecClassInternetPassword, "inet"); -SEC_CONST_DECL (kSecClassAppleSharePassword, "apls"); -SEC_CONST_DECL (kSecClassCertificate, "cert"); -SEC_CONST_DECL (kSecClassKey, "keys"); -SEC_CONST_DECL (kSecClassIdentity, "idnt"); +//SEC_CONST_DECL (kSecClassGenericPassword, "genp"); +//SEC_CONST_DECL (kSecClassInternetPassword, "inet"); +//SEC_CONST_DECL (kSecClassAppleSharePassword, "apls"); +//SEC_CONST_DECL (kSecClassCertificate, "cert"); +//SEC_CONST_DECL (kSecClassKey, "keys"); +//SEC_CONST_DECL (kSecClassIdentity, "idnt"); /* Attribute Key Constants */ -SEC_CONST_DECL (kSecAttrAccessible, "pdmn"); -SEC_CONST_DECL (kSecAttrAccessGroup, "agrp"); +//SEC_CONST_DECL (kSecAttrAccessible, "pdmn"); +//SEC_CONST_DECL (kSecAttrAccessGroup, "agrp"); SEC_CONST_DECL (kSecAttrAccess, "acls"); -SEC_CONST_DECL (kSecAttrCreationDate, "cdat"); -SEC_CONST_DECL (kSecAttrModificationDate, "mdat"); -SEC_CONST_DECL (kSecAttrDescription, "desc"); -SEC_CONST_DECL (kSecAttrComment, "icmt"); -SEC_CONST_DECL (kSecAttrCreator, "crtr"); -SEC_CONST_DECL (kSecAttrType, "type"); -SEC_CONST_DECL (kSecAttrLabel, "labl"); -SEC_CONST_DECL (kSecAttrIsInvisible, "invi"); -SEC_CONST_DECL (kSecAttrIsNegative, "nega"); -SEC_CONST_DECL (kSecAttrAccount, "acct"); -SEC_CONST_DECL (kSecAttrService, "svce"); -SEC_CONST_DECL (kSecAttrGeneric, "gena"); -SEC_CONST_DECL (kSecAttrSecurityDomain, "sdmn"); -SEC_CONST_DECL (kSecAttrServer, "srvr"); -SEC_CONST_DECL (kSecAttrProtocol, "ptcl"); -SEC_CONST_DECL (kSecAttrAuthenticationType, "atyp"); -SEC_CONST_DECL (kSecAttrPort, "port"); -SEC_CONST_DECL (kSecAttrPath, "path"); -SEC_CONST_DECL (kSecAttrVolume, "volm"); -SEC_CONST_DECL (kSecAttrAddress, "addr"); -SEC_CONST_DECL (kSecAttrAFPServerSignature, "afps"); -SEC_CONST_DECL (kSecAttrAlias, "alis"); -SEC_CONST_DECL (kSecAttrSubject, "subj"); -SEC_CONST_DECL (kSecAttrIssuer, "issr"); -SEC_CONST_DECL (kSecAttrSerialNumber, "slnr"); -SEC_CONST_DECL (kSecAttrSubjectKeyID, "skid"); -SEC_CONST_DECL (kSecAttrPublicKeyHash, "pkhh"); -SEC_CONST_DECL (kSecAttrCertificateType, "ctyp"); -SEC_CONST_DECL (kSecAttrCertificateEncoding, "cenc"); -SEC_CONST_DECL (kSecAttrKeyClass, "kcls"); -SEC_CONST_DECL (kSecAttrApplicationLabel, "klbl"); -SEC_CONST_DECL (kSecAttrIsPermanent, "perm"); -SEC_CONST_DECL (kSecAttrIsModifiable, "modi"); -SEC_CONST_DECL (kSecAttrIsPrivate, "priv"); -SEC_CONST_DECL (kSecAttrApplicationTag, "atag"); -SEC_CONST_DECL (kSecAttrKeyCreator, "crtr"); -SEC_CONST_DECL (kSecAttrKeyType, "type"); +//SEC_CONST_DECL (kSecAttrCreationDate, "cdat"); +//SEC_CONST_DECL (kSecAttrModificationDate, "mdat"); +//SEC_CONST_DECL (kSecAttrDescription, "desc"); +//SEC_CONST_DECL (kSecAttrComment, "icmt"); +//SEC_CONST_DECL (kSecAttrCreator, "crtr"); +//SEC_CONST_DECL (kSecAttrType, "type"); +//SEC_CONST_DECL (kSecAttrLabel, "labl"); +//SEC_CONST_DECL (kSecAttrIsInvisible, "invi"); +//SEC_CONST_DECL (kSecAttrIsNegative, "nega"); +//SEC_CONST_DECL (kSecAttrAccount, "acct"); +//SEC_CONST_DECL (kSecAttrService, "svce"); +//SEC_CONST_DECL (kSecAttrGeneric, "gena"); +//SEC_CONST_DECL (kSecAttrSecurityDomain, "sdmn"); +//SEC_CONST_DECL (kSecAttrServer, "srvr"); +//SEC_CONST_DECL (kSecAttrProtocol, "ptcl"); +//SEC_CONST_DECL (kSecAttrAuthenticationType, "atyp"); +//SEC_CONST_DECL (kSecAttrPort, "port"); +//SEC_CONST_DECL (kSecAttrPath, "path"); +//SEC_CONST_DECL (kSecAttrVolume, "volm"); +//SEC_CONST_DECL (kSecAttrAddress, "addr"); +//SEC_CONST_DECL (kSecAttrAFPServerSignature, "afps"); +//SEC_CONST_DECL (kSecAttrAlias, "alis"); +//SEC_CONST_DECL (kSecAttrSubject, "subj"); +//SEC_CONST_DECL (kSecAttrIssuer, "issr"); +//SEC_CONST_DECL (kSecAttrSerialNumber, "slnr"); +//SEC_CONST_DECL (kSecAttrSubjectKeyID, "skid"); +//SEC_CONST_DECL (kSecAttrPublicKeyHash, "pkhh"); +//SEC_CONST_DECL (kSecAttrCertificateType, "ctyp"); +//SEC_CONST_DECL (kSecAttrCertificateEncoding, "cenc"); +//SEC_CONST_DECL (kSecAttrKeyClass, "kcls"); +//SEC_CONST_DECL (kSecAttrApplicationLabel, "klbl"); +//SEC_CONST_DECL (kSecAttrIsPermanent, "perm"); +//SEC_CONST_DECL (kSecAttrIsModifiable, "modi"); +//SEC_CONST_DECL (kSecAttrIsPrivate, "priv"); +//SEC_CONST_DECL (kSecAttrApplicationTag, "atag"); +//SEC_CONST_DECL (kSecAttrKeyCreator, "crtr"); +//SEC_CONST_DECL (kSecAttrKeyType, "type"); SEC_CONST_DECL (kSecAttrPRF, "prf"); SEC_CONST_DECL (kSecAttrSalt, "salt"); SEC_CONST_DECL (kSecAttrRounds, "rounds"); -SEC_CONST_DECL (kSecAttrKeySizeInBits, "bsiz"); -SEC_CONST_DECL (kSecAttrEffectiveKeySize, "esiz"); -SEC_CONST_DECL (kSecAttrStartDate, "sdat"); -SEC_CONST_DECL (kSecAttrEndDate, "edat"); -SEC_CONST_DECL (kSecAttrIsSensitive, "sens"); -SEC_CONST_DECL (kSecAttrWasAlwaysSensitive, "asen"); -SEC_CONST_DECL (kSecAttrIsExtractable, "extr"); -SEC_CONST_DECL (kSecAttrWasNeverExtractable, "next"); -SEC_CONST_DECL (kSecAttrCanEncrypt, "encr"); -SEC_CONST_DECL (kSecAttrCanDecrypt, "decr"); -SEC_CONST_DECL (kSecAttrCanDerive, "drve"); -SEC_CONST_DECL (kSecAttrCanSign, "sign"); -SEC_CONST_DECL (kSecAttrCanVerify, "vrfy"); -SEC_CONST_DECL (kSecAttrCanSignRecover, "snrc"); -SEC_CONST_DECL (kSecAttrCanVerifyRecover, "vyrc"); -SEC_CONST_DECL (kSecAttrCanWrap, "wrap"); -SEC_CONST_DECL (kSecAttrCanUnwrap, "unwp"); -SEC_CONST_DECL (kSecAttrSyncViewHint, "vwht"); -SEC_CONST_DECL (kSecAttrTokenID, "tkid"); +//SEC_CONST_DECL (kSecAttrKeySizeInBits, "bsiz"); +//SEC_CONST_DECL (kSecAttrEffectiveKeySize, "esiz"); +//SEC_CONST_DECL (kSecAttrStartDate, "sdat"); +//SEC_CONST_DECL (kSecAttrEndDate, "edat"); +//SEC_CONST_DECL (kSecAttrIsSensitive, "sens"); +//SEC_CONST_DECL (kSecAttrWasAlwaysSensitive, "asen"); +//SEC_CONST_DECL (kSecAttrIsExtractable, "extr"); +//SEC_CONST_DECL (kSecAttrWasNeverExtractable, "next"); +//SEC_CONST_DECL (kSecAttrCanEncrypt, "encr"); +//SEC_CONST_DECL (kSecAttrCanDecrypt, "decr"); +//SEC_CONST_DECL (kSecAttrCanDerive, "drve"); +//SEC_CONST_DECL (kSecAttrCanSign, "sign"); +//SEC_CONST_DECL (kSecAttrCanVerify, "vrfy"); +//SEC_CONST_DECL (kSecAttrCanSignRecover, "snrc"); +//SEC_CONST_DECL (kSecAttrCanVerifyRecover, "vyrc"); +//SEC_CONST_DECL (kSecAttrCanWrap, "wrap"); +//SEC_CONST_DECL (kSecAttrCanUnwrap, "unwp"); +//SEC_CONST_DECL (kSecAttrSyncViewHint, "vwht"); +//SEC_CONST_DECL (kSecAttrTokenID, "tkid"); /* Attribute Constants (Private) */ -SEC_CONST_DECL (kSecAttrScriptCode, "scrp"); -SEC_CONST_DECL (kSecAttrHasCustomIcon, "cusi"); -SEC_CONST_DECL (kSecAttrCRLType, "crlt"); -SEC_CONST_DECL (kSecAttrCRLEncoding, "crle"); -SEC_CONST_DECL (kSecAttrSynchronizable, "sync"); -SEC_CONST_DECL (kSecAttrSynchronizableAny, "syna"); -SEC_CONST_DECL (kSecAttrTombstone, "tomb"); -SEC_CONST_DECL (kSecAttrNoLegacy, "nleg"); -SEC_CONST_DECL (kSecAttrMultiUser, "musr"); -SEC_CONST_DECL (kSecAttrTokenOID, "toid"); -SEC_CONST_DECL (kSecAttrUUID, "UUID"); -SEC_CONST_DECL (kSecAttrPersistantReference, "persistref"); -SEC_CONST_DECL (kSecAttrPersistentReference, "persistref"); -SEC_CONST_DECL (kSecAttrSysBound, "sysb"); -SEC_CONST_DECL (kSecAttrSHA1, "sha1"); - -SEC_CONST_DECL (kSecAttrDeriveSyncIDFromItemAttributes, "dspk"); -SEC_CONST_DECL (kSecAttrPCSPlaintextServiceIdentifier, "pcss"); -SEC_CONST_DECL (kSecAttrPCSPlaintextPublicKey, "pcsk"); -SEC_CONST_DECL (kSecAttrPCSPlaintextPublicIdentity, "pcsi"); +//SEC_CONST_DECL (kSecAttrScriptCode, "scrp"); +//SEC_CONST_DECL (kSecAttrHasCustomIcon, "cusi"); +//SEC_CONST_DECL (kSecAttrCRLType, "crlt"); +//SEC_CONST_DECL (kSecAttrCRLEncoding, "crle"); +//SEC_CONST_DECL (kSecAttrSynchronizable, "sync"); +//SEC_CONST_DECL (kSecAttrSynchronizableAny, "syna"); +//SEC_CONST_DECL (kSecAttrTombstone, "tomb"); +//SEC_CONST_DECL (kSecAttrNoLegacy, "nleg"); +//SEC_CONST_DECL (kSecAttrMultiUser, "musr"); +//SEC_CONST_DECL (kSecAttrTokenOID, "toid"); +//SEC_CONST_DECL (kSecAttrUUID, "UUID"); +//SEC_CONST_DECL (kSecAttrPersistantReference, "persistref"); +//SEC_CONST_DECL (kSecAttrPersistentReference, "persistref"); +//SEC_CONST_DECL (kSecAttrSysBound, "sysb"); +//SEC_CONST_DECL (kSecAttrSHA1, "sha1"); +// +//SEC_CONST_DECL (kSecAttrDeriveSyncIDFromItemAttributes, "dspk"); +//SEC_CONST_DECL (kSecAttrPCSPlaintextServiceIdentifier, "pcss"); +//SEC_CONST_DECL (kSecAttrPCSPlaintextPublicKey, "pcsk"); +//SEC_CONST_DECL (kSecAttrPCSPlaintextPublicIdentity, "pcsi"); /* Predefined access groups constants */ -SEC_CONST_DECL (kSecAttrAccessGroupToken, "com.apple.token"); +//SEC_CONST_DECL (kSecAttrAccessGroupToken, "com.apple.token"); /* Search Constants */ -SEC_CONST_DECL (kSecMatchPolicy, "m_Policy"); -SEC_CONST_DECL (kSecMatchItemList, "m_ItemList"); -SEC_CONST_DECL (kSecMatchSearchList, "m_SearchList"); -SEC_CONST_DECL (kSecMatchIssuers, "m_Issuers"); -SEC_CONST_DECL (kSecMatchEmailAddressIfPresent, "m_EmailAddressIfPresent"); -SEC_CONST_DECL (kSecMatchSubjectContains, "m_SubjectContains"); +//SEC_CONST_DECL (kSecMatchPolicy, "m_Policy"); +//SEC_CONST_DECL (kSecMatchItemList, "m_ItemList"); +//SEC_CONST_DECL (kSecMatchSearchList, "m_SearchList"); +//SEC_CONST_DECL (kSecMatchIssuers, "m_Issuers"); +//SEC_CONST_DECL (kSecMatchEmailAddressIfPresent, "m_EmailAddressIfPresent"); +//SEC_CONST_DECL (kSecMatchSubjectContains, "m_SubjectContains"); SEC_CONST_DECL (kSecMatchSubjectStartsWith, "m_SubjectStartsWith"); SEC_CONST_DECL (kSecMatchSubjectEndsWith, "m_SubjectEndsWith"); SEC_CONST_DECL (kSecMatchSubjectWholeString, "m_SubjectWholeString"); -SEC_CONST_DECL (kSecMatchCaseInsensitive, "m_CaseInsensitive"); +//SEC_CONST_DECL (kSecMatchCaseInsensitive, "m_CaseInsensitive"); SEC_CONST_DECL (kSecMatchDiacriticInsensitive, "m_DiacriticInsensitive"); SEC_CONST_DECL (kSecMatchWidthInsensitive, "m_WidthInsensitive"); -SEC_CONST_DECL (kSecMatchTrustedOnly, "m_TrustedOnly"); -SEC_CONST_DECL (kSecMatchValidOnDate, "m_ValidOnDate"); -SEC_CONST_DECL (kSecMatchLimit, "m_Limit"); +//SEC_CONST_DECL (kSecMatchTrustedOnly, "m_TrustedOnly"); +//SEC_CONST_DECL (kSecMatchValidOnDate, "m_ValidOnDate"); +//SEC_CONST_DECL (kSecMatchLimit, "m_Limit"); /* Could just use kCFBooleanTrue and kCFBooleanFalse for these 2. */ -SEC_CONST_DECL (kSecMatchLimitOne, "m_LimitOne"); -SEC_CONST_DECL (kSecMatchLimitAll, "m_LimitAll"); +//SEC_CONST_DECL (kSecMatchLimitOne, "m_LimitOne"); +//SEC_CONST_DECL (kSecMatchLimitAll, "m_LimitAll"); /* Return Type Key Constants */ -SEC_CONST_DECL (kSecReturnData, "r_Data"); -SEC_CONST_DECL (kSecReturnAttributes, "r_Attributes"); -SEC_CONST_DECL (kSecReturnRef, "r_Ref"); -SEC_CONST_DECL (kSecReturnPersistentRef, "r_PersistentRef"); +//SEC_CONST_DECL (kSecReturnData, "r_Data"); +//SEC_CONST_DECL (kSecReturnAttributes, "r_Attributes"); +//SEC_CONST_DECL (kSecReturnRef, "r_Ref"); +//SEC_CONST_DECL (kSecReturnPersistentRef, "r_PersistentRef"); /* Value Type Key Constants */ -SEC_CONST_DECL (kSecValueData, "v_Data"); -SEC_CONST_DECL (kSecValueRef, "v_Ref"); -SEC_CONST_DECL (kSecValuePersistentRef, "v_PersistentRef"); +//SEC_CONST_DECL (kSecValueData, "v_Data"); +//SEC_CONST_DECL (kSecValueRef, "v_Ref"); +//SEC_CONST_DECL (kSecValuePersistentRef, "v_PersistentRef"); /* Other Constants */ -SEC_CONST_DECL (kSecUseItemList, "u_ItemList"); +//SEC_CONST_DECL (kSecUseItemList, "u_ItemList"); SEC_CONST_DECL (kSecUseKeychain, "u_Keychain"); -SEC_CONST_DECL (kSecUseSystemKeychain, "u_SystemKeychain"); -SEC_CONST_DECL (kSecUseSyncBubbleKeychain, "u_SyncBubbleKeychain"); +//SEC_CONST_DECL (kSecUseSystemKeychain, "u_SystemKeychain"); +//SEC_CONST_DECL (kSecUseSyncBubbleKeychain, "u_SyncBubbleKeychain"); /* kSecAttrAccessible Value Constants. */ -SEC_CONST_DECL (kSecAttrAccessibleWhenUnlocked, "ak"); -SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlock, "ck"); -SEC_CONST_DECL (kSecAttrAccessibleAlways, "dk"); -SEC_CONST_DECL (kSecAttrAccessibleWhenUnlockedThisDeviceOnly, "aku"); -SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, "cku"); -SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnly, "dku"); -SEC_CONST_DECL (kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, "akpu"); +//SEC_CONST_DECL (kSecAttrAccessibleWhenUnlocked, "ak"); +//SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlock, "ck"); +//SEC_CONST_DECL (kSecAttrAccessibleAlways, "dk"); +//SEC_CONST_DECL (kSecAttrAccessibleWhenUnlockedThisDeviceOnly, "aku"); +//SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, "cku"); +//SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnly, "dku"); +//SEC_CONST_DECL (kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, "akpu"); /* kSecAttrAccessible Value Constants (Private). */ -SEC_CONST_DECL (kSecAttrAccessibleAlwaysPrivate, "dk"); -SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate, "dku"); +//SEC_CONST_DECL (kSecAttrAccessibleAlwaysPrivate, "dk"); +//SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate, "dku"); /* kSecAttrProtocol Value Constants. */ -SEC_CONST_DECL (kSecAttrProtocolFTP, "ftp "); -SEC_CONST_DECL (kSecAttrProtocolFTPAccount, "ftpa"); -SEC_CONST_DECL (kSecAttrProtocolHTTP, "http"); -SEC_CONST_DECL (kSecAttrProtocolIRC, "irc "); -SEC_CONST_DECL (kSecAttrProtocolNNTP, "nntp"); -SEC_CONST_DECL (kSecAttrProtocolPOP3, "pop3"); -SEC_CONST_DECL (kSecAttrProtocolSMTP, "smtp"); -SEC_CONST_DECL (kSecAttrProtocolSOCKS, "sox "); -SEC_CONST_DECL (kSecAttrProtocolIMAP, "imap"); -SEC_CONST_DECL (kSecAttrProtocolLDAP, "ldap"); -SEC_CONST_DECL (kSecAttrProtocolAppleTalk, "atlk"); -SEC_CONST_DECL (kSecAttrProtocolAFP, "afp "); -SEC_CONST_DECL (kSecAttrProtocolTelnet, "teln"); -SEC_CONST_DECL (kSecAttrProtocolSSH, "ssh "); -SEC_CONST_DECL (kSecAttrProtocolFTPS, "ftps"); -SEC_CONST_DECL (kSecAttrProtocolHTTPS, "htps"); -SEC_CONST_DECL (kSecAttrProtocolHTTPProxy, "htpx"); -SEC_CONST_DECL (kSecAttrProtocolHTTPSProxy, "htsx"); -SEC_CONST_DECL (kSecAttrProtocolFTPProxy, "ftpx"); -SEC_CONST_DECL (kSecAttrProtocolSMB, "smb "); -SEC_CONST_DECL (kSecAttrProtocolRTSP, "rtsp"); -SEC_CONST_DECL (kSecAttrProtocolRTSPProxy, "rtsx"); -SEC_CONST_DECL (kSecAttrProtocolDAAP, "daap"); -SEC_CONST_DECL (kSecAttrProtocolEPPC, "eppc"); -SEC_CONST_DECL (kSecAttrProtocolIPP, "ipp "); -SEC_CONST_DECL (kSecAttrProtocolNNTPS, "ntps"); -SEC_CONST_DECL (kSecAttrProtocolLDAPS, "ldps"); -SEC_CONST_DECL (kSecAttrProtocolTelnetS, "tels"); -SEC_CONST_DECL (kSecAttrProtocolIMAPS, "imps"); -SEC_CONST_DECL (kSecAttrProtocolIRCS, "ircs"); -SEC_CONST_DECL (kSecAttrProtocolPOP3S, "pops"); +//SEC_CONST_DECL (kSecAttrProtocolFTP, "ftp "); +//SEC_CONST_DECL (kSecAttrProtocolFTPAccount, "ftpa"); +//SEC_CONST_DECL (kSecAttrProtocolHTTP, "http"); +//SEC_CONST_DECL (kSecAttrProtocolIRC, "irc "); +//SEC_CONST_DECL (kSecAttrProtocolNNTP, "nntp"); +//SEC_CONST_DECL (kSecAttrProtocolPOP3, "pop3"); +//SEC_CONST_DECL (kSecAttrProtocolSMTP, "smtp"); +//SEC_CONST_DECL (kSecAttrProtocolSOCKS, "sox "); +//SEC_CONST_DECL (kSecAttrProtocolIMAP, "imap"); +//SEC_CONST_DECL (kSecAttrProtocolLDAP, "ldap"); +//SEC_CONST_DECL (kSecAttrProtocolAppleTalk, "atlk"); +//SEC_CONST_DECL (kSecAttrProtocolAFP, "afp "); +//SEC_CONST_DECL (kSecAttrProtocolTelnet, "teln"); +//SEC_CONST_DECL (kSecAttrProtocolSSH, "ssh "); +//SEC_CONST_DECL (kSecAttrProtocolFTPS, "ftps"); +//SEC_CONST_DECL (kSecAttrProtocolHTTPS, "htps"); +//SEC_CONST_DECL (kSecAttrProtocolHTTPProxy, "htpx"); +//SEC_CONST_DECL (kSecAttrProtocolHTTPSProxy, "htsx"); +//SEC_CONST_DECL (kSecAttrProtocolFTPProxy, "ftpx"); +//SEC_CONST_DECL (kSecAttrProtocolSMB, "smb "); +//SEC_CONST_DECL (kSecAttrProtocolRTSP, "rtsp"); +//SEC_CONST_DECL (kSecAttrProtocolRTSPProxy, "rtsx"); +//SEC_CONST_DECL (kSecAttrProtocolDAAP, "daap"); +//SEC_CONST_DECL (kSecAttrProtocolEPPC, "eppc"); +//SEC_CONST_DECL (kSecAttrProtocolIPP, "ipp "); +//SEC_CONST_DECL (kSecAttrProtocolNNTPS, "ntps"); +//SEC_CONST_DECL (kSecAttrProtocolLDAPS, "ldps"); +//SEC_CONST_DECL (kSecAttrProtocolTelnetS, "tels"); +//SEC_CONST_DECL (kSecAttrProtocolIMAPS, "imps"); +//SEC_CONST_DECL (kSecAttrProtocolIRCS, "ircs"); +//SEC_CONST_DECL (kSecAttrProtocolPOP3S, "pops"); /* kSecAttrAuthenticationType Value Constants. */ -SEC_CONST_DECL (kSecAttrAuthenticationTypeNTLM, "ntlm"); -SEC_CONST_DECL (kSecAttrAuthenticationTypeMSN, "msna"); -SEC_CONST_DECL (kSecAttrAuthenticationTypeDPA, "dpaa"); -SEC_CONST_DECL (kSecAttrAuthenticationTypeRPA, "rpaa"); -SEC_CONST_DECL (kSecAttrAuthenticationTypeHTTPBasic, "http"); -SEC_CONST_DECL (kSecAttrAuthenticationTypeHTTPDigest, "httd"); -SEC_CONST_DECL (kSecAttrAuthenticationTypeHTMLForm, "form"); -SEC_CONST_DECL (kSecAttrAuthenticationTypeDefault, "dflt"); +//SEC_CONST_DECL (kSecAttrAuthenticationTypeNTLM, "ntlm"); +//SEC_CONST_DECL (kSecAttrAuthenticationTypeMSN, "msna"); +//SEC_CONST_DECL (kSecAttrAuthenticationTypeDPA, "dpaa"); +//SEC_CONST_DECL (kSecAttrAuthenticationTypeRPA, "rpaa"); +//SEC_CONST_DECL (kSecAttrAuthenticationTypeHTTPBasic, "http"); +//SEC_CONST_DECL (kSecAttrAuthenticationTypeHTTPDigest, "httd"); +//SEC_CONST_DECL (kSecAttrAuthenticationTypeHTMLForm, "form"); +//SEC_CONST_DECL (kSecAttrAuthenticationTypeDefault, "dflt"); /* kSecAttrKeyClass Value Constants. Based on CSSM_KEYCLASS_PUBLIC_KEY = 0, CSSM_KEYCLASS_PRIVATE_KEY = 1, CSSM_KEYCLASS_SESSION_KEY = 2, */ -SEC_CONST_DECL (kSecAttrKeyClassPublic, "0"); -SEC_CONST_DECL (kSecAttrKeyClassPrivate, "1"); -SEC_CONST_DECL (kSecAttrKeyClassSymmetric, "2"); +//SEC_CONST_DECL (kSecAttrKeyClassPublic, "0"); +//SEC_CONST_DECL (kSecAttrKeyClassPrivate, "1"); +//SEC_CONST_DECL (kSecAttrKeyClassSymmetric, "2"); /* kSecAttrKeyType Value Constants. Based on CSSM_ALGORITHMS. */ SEC_CONST_DECL (kSecAttrKeyTypeDES, "14"); SEC_CONST_DECL (kSecAttrKeyType3DES, "17"); SEC_CONST_DECL (kSecAttrKeyTypeRC2, "23"); SEC_CONST_DECL (kSecAttrKeyTypeRC4, "25"); -SEC_CONST_DECL (kSecAttrKeyTypeRSA, "42"); + +//SEC_CONST_DECL (kSecAttrKeyTypeRSA, "42"); SEC_CONST_DECL (kSecAttrKeyTypeDSA, "43"); SEC_CONST_DECL (kSecAttrKeyTypeCAST, "56"); -SEC_CONST_DECL (kSecAttrKeyTypeECDSA, "73"); -SEC_CONST_DECL (kSecAttrKeyTypeEC, "73"); /* rdar://13326326 */ -SEC_CONST_DECL (kSecAttrKeyTypeECSECPrimeRandom, "73"); +SEC_CONST_DECL (kSecAttrKeyTypeECDSA, "73"); /**/ +//SEC_CONST_DECL (kSecAttrKeyTypeEC, "73"); /* rdar://13326326 */ +//SEC_CONST_DECL (kSecAttrKeyTypeECSECPrimeRandom, "73"); SEC_CONST_DECL (kSecAttrKeyTypeAES, "2147483649"); /* */ -SEC_CONST_DECL (kSecAttrKeyTypeECSECPrimeRandomPKA, "2147483678"); /* CSSM_ALGID__FIRST_UNUSED */ -SEC_CONST_DECL (kSecAttrKeyTypeSecureEnclaveAttestation, "2147483679"); /* CSSM_ALGID__FIRST_UNUSED + 1 */ +//SEC_CONST_DECL (kSecAttrKeyTypeECSECPrimeRandomPKA, "2147483678"); /* CSSM_ALGID__FIRST_UNUSED */ +//SEC_CONST_DECL (kSecAttrKeyTypeSecureEnclaveAttestation, "2147483679"); /* CSSM_ALGID__FIRST_UNUSED + 1 */ SEC_CONST_DECL (kSecAttrPRFHmacAlgSHA1, "hsha1"); SEC_CONST_DECL (kSecAttrPRFHmacAlgSHA224, "hsha224"); @@ -252,7 +255,7 @@ SEC_CONST_DECL (kSecAttrPRFHmacAlgSHA512, "hsha512"); /* Constants used by SecKeyGeneratePair() - in SecKey.h. Never used in any SecItem apis directly. */ -SEC_CONST_DECL (kSecPrivateKeyAttrs, "private"); -SEC_CONST_DECL (kSecPublicKeyAttrs, "public"); +//SEC_CONST_DECL (kSecPrivateKeyAttrs, "private"); +//SEC_CONST_DECL (kSecPublicKeyAttrs, "public"); /* Used for SecKeyGenerateSymmetric */ SEC_CONST_DECL (kSecSymmetricKeyAttrs, "symmetric"); diff --git a/OSX/libsecurity_keychain/lib/SecKey.cpp b/OSX/libsecurity_keychain/lib/SecKey.cpp index 229ee8bb..bcefe83e 100644 --- a/OSX/libsecurity_keychain/lib/SecKey.cpp +++ b/OSX/libsecurity_keychain/lib/SecKey.cpp @@ -35,6 +35,10 @@ #include #include +#include +// 'verify' macro is somehow dragged in from CFPriv.h and breaks compilation of signclient.h, so undef it, we don't need it. +#undef verify + #include "SecBridge.h" #include @@ -56,6 +60,7 @@ SecCDSAKeyInit(SecKeyRef key, const uint8_t *keyData, CFIndex keyDataLength, Sec key->key = const_cast(reinterpret_cast(keyData)); key->key->initializeWithSecKeyRef(key); key->credentialType = kSecCredentialTypeDefault; + key->cdsaKeyMutex = new Mutex(); return errSecSuccess; } @@ -65,14 +70,22 @@ SecCDSAKeyDestroy(SecKeyRef keyRef) { // If we hold the keychain's mutex (the key's 'mutexForObject') during this destruction, pthread gets upset. // Hold a reference to the keychain (if it exists) until after we release the keychain's mutex. + StMaybeLock cdsaMutex(keyRef->cdsaKeyMutex); + KeyItem *keyItem = keyRef->key; + if (keyItem == NULL) { // KeyImpl::attachSecKeyRef disconnected us from KeyItem instance, there is nothing to do for us. + cdsaMutex.unlock(); + delete keyRef->cdsaKeyMutex; return; } Keychain kc = keyItem->keychain(); + // We have a +1 reference to the KeyItem now; no need to protect our storage any more + cdsaMutex.unlock(); + { StMaybeLock _(keyItem->getMutexForObject()); keyItem = keyRef->key; @@ -85,6 +98,8 @@ SecCDSAKeyDestroy(SecKeyRef keyRef) { delete keyItem; } + delete keyRef->cdsaKeyMutex; + (void) kc; // Tell the compiler we're actually using this variable. At destruction time, it'll release the keychain. } @@ -501,7 +516,7 @@ static CSSM_DB_NAME_ATTR(kInfoKeyLabel, kSecKeyLabel, (char*) "Label", 0, NULL, #pragma clang diagnostic pop static SecKeyRef SecCDSAKeyCopyPublicKey(SecKeyRef privateKey) { - CFErrorRef *error; + CFErrorRef *error = NULL; BEGIN_SECKEYAPI(SecKeyRef, NULL) result = NULL; @@ -761,7 +776,7 @@ static CFTypeRef SecCDSAKeyCopyOperationResult(SecKeyRef key, SecKeyOperationTyp } static Boolean SecCDSAKeyIsEqual(SecKeyRef key1, SecKeyRef key2) { - CFErrorRef *error; + CFErrorRef *error = NULL; BEGIN_SECKEYAPI(Boolean, false) result = key1->key->equal(*key2->key); @@ -797,6 +812,8 @@ const SecKeyDescriptor kSecCDSAKeyDescriptor = { .copyOperationResult = SecCDSAKeyCopyOperationResult, .isEqual = SecCDSAKeyIsEqual, .setParameter = SecCDSAKeySetParameter, + + .extraBytes = (sizeof(struct OpaqueSecKeyRef) > sizeof(struct __SecKey) ? (sizeof(struct OpaqueSecKeyRef) - sizeof(struct __SecKey)) : 0), }; namespace Security { @@ -910,7 +927,7 @@ SecKeyGetCSSMKey(SecKeyRef key, const CSSM_KEY **cssmKey) // static ModuleNexus gSecReturnedKeyCSPsMutex; -static std::set gSecReturnedKeyCSPs; +static ModuleNexus> gSecReturnedKeyCSPs; OSStatus SecKeyGetCSPHandle(SecKeyRef keyRef, CSSM_CSP_HANDLE *cspHandle) @@ -924,7 +941,7 @@ SecKeyGetCSPHandle(SecKeyRef keyRef, CSSM_CSP_HANDLE *cspHandle) CssmClient::CSP returnedKeyCSP = keyItem->csp(); { StLock _(gSecReturnedKeyCSPsMutex()); - gSecReturnedKeyCSPs.insert(returnedKeyCSP); + gSecReturnedKeyCSPs().insert(returnedKeyCSP); } Required(cspHandle) = returnedKeyCSP->handle(); @@ -1544,19 +1561,26 @@ SecKeyGeneratePairInternal( Required(publicKey); Required(privateKey); - CFTypeRef tokenID = GetAttributeFromParams(parameters, kSecAttrTokenID, NULL); - CFTypeRef noLegacy = GetAttributeFromParams(parameters, kSecAttrNoLegacy, NULL); - CFTypeRef sync = GetAttributeFromParams(parameters, kSecAttrSynchronizable, kSecPrivateKeyAttrs); - CFTypeRef accessControl = GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPrivateKeyAttrs) ?: - GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPublicKeyAttrs); - CFTypeRef accessGroup = GetAttributeFromParams(parameters, kSecAttrAccessGroup, kSecPrivateKeyAttrs) ?: - GetAttributeFromParams(parameters, kSecAttrAccessGroup, kSecPublicKeyAttrs); - - // If any of these attributes are present, forward the call to iOS implementation (and create keys in iOS keychain). - if (tokenID != NULL || - (noLegacy != NULL && CFBooleanGetValue((CFBooleanRef)noLegacy)) || - (sync != NULL && CFBooleanGetValue((CFBooleanRef)sync)) || - accessControl != NULL || (accessGroup != NULL && CFEqual(accessGroup, kSecAttrAccessGroupToken))) { + bool forceIOSKey = false; + if (_CFMZEnabled()) { + // On Marzipan, always go iOS SecItem/SecKey route, do not drag CSSM keys in. + forceIOSKey = true; + } else { + CFTypeRef tokenID = GetAttributeFromParams(parameters, kSecAttrTokenID, NULL); + CFTypeRef noLegacy = GetAttributeFromParams(parameters, kSecAttrNoLegacy, NULL); + CFTypeRef sync = GetAttributeFromParams(parameters, kSecAttrSynchronizable, kSecPrivateKeyAttrs); + CFTypeRef accessControl = GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPrivateKeyAttrs) ?: + GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPublicKeyAttrs); + CFTypeRef accessGroup = GetAttributeFromParams(parameters, kSecAttrAccessGroup, kSecPrivateKeyAttrs) ?: + GetAttributeFromParams(parameters, kSecAttrAccessGroup, kSecPublicKeyAttrs); + // If any of these attributes are present, forward the call to iOS implementation (and create keys in iOS keychain). + forceIOSKey = (tokenID != NULL || + (noLegacy != NULL && CFBooleanGetValue((CFBooleanRef)noLegacy)) || + (sync != NULL && CFBooleanGetValue((CFBooleanRef)sync)) || + accessControl != NULL || (accessGroup != NULL && CFEqual(accessGroup, kSecAttrAccessGroupToken))); + } + + if (forceIOSKey) { // Generate keys in iOS keychain. return SecKeyGeneratePair_ios(parameters, publicKey, privateKey); } diff --git a/OSX/libsecurity_keychain/lib/SecKeychain.cpp b/OSX/libsecurity_keychain/lib/SecKeychain.cpp index 71485cdf..b13c0357 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychain.cpp +++ b/OSX/libsecurity_keychain/lib/SecKeychain.cpp @@ -890,8 +890,8 @@ SecKeychainGetDLDBHandle(SecKeychainRef keychainRef, CSSM_DL_DB_HANDLE *dldbHand END_SECAPI } -static ModuleNexus gSecReturnedKeyCSPsMutex; -static std::set gSecReturnedKeychainCSPs; +static ModuleNexus gSecReturnedKeychainCSPsMutex; +static ModuleNexus> gSecReturnedKeychainCSPs; OSStatus SecKeychainGetCSPHandle(SecKeychainRef keychainRef, CSSM_CSP_HANDLE *cspHandle) @@ -906,8 +906,8 @@ SecKeychainGetCSPHandle(SecKeychainRef keychainRef, CSSM_CSP_HANDLE *cspHandle) // Keep a global pointer to it to force the CSP to stay live forever. CssmClient::CSP returnedKeychainCSP = keychain->csp(); { - StLock _(gSecReturnedKeyCSPsMutex()); - gSecReturnedKeychainCSPs.insert(returnedKeychainCSP); + StLock _(gSecReturnedKeychainCSPsMutex()); + gSecReturnedKeychainCSPs().insert(returnedKeychainCSP); } *cspHandle = returnedKeychainCSP->handle(); diff --git a/OSX/libsecurity_keychain/lib/SecKeychain.h b/OSX/libsecurity_keychain/lib/SecKeychain.h index 1a2d3fd1..7aa9b801 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychain.h +++ b/OSX/libsecurity_keychain/lib/SecKeychain.h @@ -249,14 +249,14 @@ typedef CF_OPTIONS(UInt32, SecKeychainEventMask) @field pid The id of the process that generated this event. @discussion The SecKeychainCallbackInfo type represents a structure that contains information about the keychain event for which your application is being notified. For information on how to write a keychain event callback function, see SecKeychainCallback. */ -struct SecKeychainCallbackInfo +struct API_UNAVAILABLE(ios) SecKeychainCallbackInfo { UInt32 version; SecKeychainItemRef __nonnull item; SecKeychainRef __nonnull keychain; pid_t pid; }; -typedef struct SecKeychainCallbackInfo SecKeychainCallbackInfo; +typedef struct SecKeychainCallbackInfo SecKeychainCallbackInfo API_UNAVAILABLE(ios); /*! @function SecKeychainGetTypeID @@ -296,7 +296,7 @@ OSStatus SecKeychainOpen(const char *pathName, SecKeychainRef * __nonnull CF_RET @param keychain On return, a pointer to a keychain reference. The memory that keychain occupies must be released by calling CFRelease when finished with it. @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain parameter is invalid (NULL). */ -OSStatus SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void * __nullable password, Boolean promptUser, SecAccessRef __nullable initialAccess, SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychain); +OSStatus SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void * __nullable password, Boolean promptUser, SecAccessRef __nullable initialAccess, SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychain) API_UNAVAILABLE(ios); /*! @function SecKeychainDelete @@ -304,7 +304,7 @@ OSStatus SecKeychainCreate(const char *pathName, UInt32 passwordLength, const vo @param keychainOrArray A single keychain reference or a reference to an array of keychains to delete. IMPORTANT: SecKeychainDelete does not dispose the memory occupied by keychain references; use the CFRelease function when you are completely finished with a keychain. @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecInvalidKeychain (-25295) may be returned if the keychain parameter is invalid (NULL). */ -OSStatus SecKeychainDelete(SecKeychainRef __nullable keychainOrArray); +OSStatus SecKeychainDelete(SecKeychainRef __nullable keychainOrArray) API_UNAVAILABLE(ios); /*! @function SecKeychainSetSettings @@ -313,7 +313,7 @@ OSStatus SecKeychainDelete(SecKeychainRef __nullable keychainOrArray); @param newSettings A pointer to the new keychain settings. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainSetSettings(SecKeychainRef __nullable keychain, const SecKeychainSettings *newSettings); +OSStatus SecKeychainSetSettings(SecKeychainRef __nullable keychain, const SecKeychainSettings *newSettings) API_UNAVAILABLE(ios); /*! @function SecKeychainCopySettings @@ -322,7 +322,7 @@ OSStatus SecKeychainSetSettings(SecKeychainRef __nullable keychain, const SecKey @param outSettings A pointer to a keychain settings structure. Since this structure is versioned, you must preallocate it and fill in the version of the structure. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainCopySettings(SecKeychainRef __nullable keychain, SecKeychainSettings *outSettings); +OSStatus SecKeychainCopySettings(SecKeychainRef __nullable keychain, SecKeychainSettings *outSettings) API_UNAVAILABLE(ios); /*! @function SecKeychainUnlock @@ -334,7 +334,7 @@ OSStatus SecKeychainCopySettings(SecKeychainRef __nullable keychain, SecKeychain @result A result code. See "Security Error Codes" (SecBase.h). @discussion In most cases, your application does not need to call the SecKeychainUnlock function directly, since most Keychain Manager functions that require an unlocked keychain call SecKeychainUnlock automatically. If your application needs to verify that a keychain is unlocked, call the function SecKeychainGetStatus. */ -OSStatus SecKeychainUnlock(SecKeychainRef __nullable keychain, UInt32 passwordLength, const void * __nullable password, Boolean usePassword); +OSStatus SecKeychainUnlock(SecKeychainRef __nullable keychain, UInt32 passwordLength, const void * __nullable password, Boolean usePassword) API_UNAVAILABLE(ios); /*! @function SecKeychainLock @@ -342,14 +342,14 @@ OSStatus SecKeychainUnlock(SecKeychainRef __nullable keychain, UInt32 passwordLe @param keychain A reference to the keychain to lock. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainLock(SecKeychainRef __nullable keychain); +OSStatus SecKeychainLock(SecKeychainRef __nullable keychain) API_UNAVAILABLE(ios); /*! @function SecKeychainLockAll @abstract Locks all keychains belonging to the current user. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainLockAll(void); +OSStatus SecKeychainLockAll(void) API_UNAVAILABLE(ios); /*! @function SecKeychainCopyDefault @@ -357,7 +357,7 @@ OSStatus SecKeychainLockAll(void); @param keychain On return, a pointer to the default keychain reference. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainCopyDefault(SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychain); +OSStatus SecKeychainCopyDefault(SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychain) API_UNAVAILABLE(ios); /*! @function SecKeychainSetDefault @@ -365,7 +365,7 @@ OSStatus SecKeychainCopyDefault(SecKeychainRef * __nonnull CF_RETURNS_RETAINED k @param keychain A reference to the keychain to set as default. @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain parameter is invalid (NULL). */ -OSStatus SecKeychainSetDefault(SecKeychainRef __nullable keychain); +OSStatus SecKeychainSetDefault(SecKeychainRef __nullable keychain) API_UNAVAILABLE(ios); /*! @function SecKeychainCopySearchList @@ -373,7 +373,7 @@ OSStatus SecKeychainSetDefault(SecKeychainRef __nullable keychain); @param searchList The returned list of keychains to search. When finished with the array, you must call CFRelease() to release the memory. @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain list is not specified (NULL). */ -OSStatus SecKeychainCopySearchList(CFArrayRef * __nonnull CF_RETURNS_RETAINED searchList); +OSStatus SecKeychainCopySearchList(CFArrayRef * __nonnull CF_RETURNS_RETAINED searchList) API_UNAVAILABLE(ios); /*! @function SecKeychainSetSearchList @@ -381,7 +381,7 @@ OSStatus SecKeychainCopySearchList(CFArrayRef * __nonnull CF_RETURNS_RETAINED se @param searchList The list of keychains to use in a search list when the SecKeychainCopySearchList function is called. An empty array clears the search list. @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain list is not specified (NULL). */ -OSStatus SecKeychainSetSearchList(CFArrayRef searchList); +OSStatus SecKeychainSetSearchList(CFArrayRef searchList) API_UNAVAILABLE(ios); /* @@ -410,7 +410,7 @@ OSStatus SecKeychainGetPreferenceDomain(SecPreferencesDomain *domain); @param keychainStatus On return, a pointer to the status of the specified keychain. See KeychainStatus for valid status constants. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainGetStatus(SecKeychainRef __nullable keychain, SecKeychainStatus *keychainStatus); +OSStatus SecKeychainGetStatus(SecKeychainRef __nullable keychain, SecKeychainStatus *keychainStatus) API_UNAVAILABLE(ios); /*! @function SecKeychainGetPath @@ -420,7 +420,7 @@ OSStatus SecKeychainGetStatus(SecKeychainRef __nullable keychain, SecKeychainSta @param pathName On return, the POSIX path to the keychain. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainGetPath(SecKeychainRef __nullable keychain, UInt32 *ioPathLength, char *pathName); +OSStatus SecKeychainGetPath(SecKeychainRef __nullable keychain, UInt32 *ioPathLength, char *pathName) API_UNAVAILABLE(ios); #pragma mark ---- Keychain Item Attribute Information ---- /*! @@ -432,7 +432,7 @@ OSStatus SecKeychainGetPath(SecKeychainRef __nullable keychain, UInt32 *ioPathLe @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters were supplied (NULL). @discussion Warning, this call returns more attributes than are support by the old style Keychain API and passing them into older calls will yield an invalid attribute error. The recommended call to retrieve the attribute values is the SecKeychainItemCopyAttributesAndData function. */ -OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef __nullable keychain, UInt32 itemID, SecKeychainAttributeInfo * __nullable * __nonnull info); +OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef __nullable keychain, UInt32 itemID, SecKeychainAttributeInfo * __nullable * __nonnull info) API_UNAVAILABLE(ios); /*! @function SecKeychainFreeAttributeInfo @@ -440,7 +440,7 @@ OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef __nullable keychain, @param info A pointer to the keychain attribute information to release. @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters were supplied (NULL). */ -OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info); +OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info) API_UNAVAILABLE(ios); #pragma mark ---- Keychain Manager Callbacks ---- @@ -459,7 +459,7 @@ OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info); To add your callback function, use the SecKeychainAddCallback function. To remove your callback function, use the SecKeychainRemoveCallback function. */ -typedef OSStatus (*SecKeychainCallback)(SecKeychainEvent keychainEvent, SecKeychainCallbackInfo *info, void * __nullable context); +typedef OSStatus (*SecKeychainCallback)(SecKeychainEvent keychainEvent, SecKeychainCallbackInfo *info, void * __nullable context) API_UNAVAILABLE(ios); /*! @function SecKeychainAddCallback @@ -469,7 +469,7 @@ typedef OSStatus (*SecKeychainCallback)(SecKeychainEvent keychainEvent, SecKeych @param userContext A pointer to application-defined storage that will be passed to your callback function. Your application can use this to associate any particular call of SecKeychainAddCallback with any particular call of your keychain event callback function. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainAddCallback(SecKeychainCallback callbackFunction, SecKeychainEventMask eventMask, void * __nullable userContext); +OSStatus SecKeychainAddCallback(SecKeychainCallback callbackFunction, SecKeychainEventMask eventMask, void * __nullable userContext) API_UNAVAILABLE(ios); /*! @function SecKeychainRemoveCallback @@ -477,7 +477,7 @@ OSStatus SecKeychainAddCallback(SecKeychainCallback callbackFunction, SecKeychai @param callbackFunction The callback function pointer to remove @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainRemoveCallback(SecKeychainCallback callbackFunction); +OSStatus SecKeychainRemoveCallback(SecKeychainCallback callbackFunction) API_UNAVAILABLE(ios); #pragma mark ---- High Level Keychain Manager Calls ---- /*! @@ -501,7 +501,7 @@ OSStatus SecKeychainRemoveCallback(SecKeychainCallback callbackFunction); @result A result code. See "Security Error Codes" (SecBase.h). @discussion The SecKeychainAddInternetPassword function adds a new Internet server password to the specified keychain. Required parameters to identify the password are serverName and accountName (you cannot pass NULL for both parameters). In addition, some protocols may require an optional securityDomain when authentication is requested. SecKeychainAddInternetPassword optionally returns a reference to the newly added item. */ -OSStatus SecKeychainAddInternetPassword(SecKeychainRef __nullable keychain, UInt32 serverNameLength, const char * __nullable serverName, UInt32 securityDomainLength, const char * __nullable securityDomain, UInt32 accountNameLength, const char * __nullable accountName, UInt32 pathLength, const char * __nullable path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef); +OSStatus SecKeychainAddInternetPassword(SecKeychainRef __nullable keychain, UInt32 serverNameLength, const char * __nullable serverName, UInt32 securityDomainLength, const char * __nullable securityDomain, UInt32 accountNameLength, const char * __nullable accountName, UInt32 pathLength, const char * __nullable path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios); /*! @function SecKeychainFindInternetPassword @@ -524,7 +524,7 @@ OSStatus SecKeychainAddInternetPassword(SecKeychainRef __nullable keychain, UInt @result A result code. See "Security Error Codes" (SecBase.h). @discussion The SecKeychainFindInternetPassword function finds the first Internet password item which matches the attributes you provide. Most attributes are optional; you should pass only as many as you need to narrow the search sufficiently for your application's intended use. SecKeychainFindInternetPassword optionally returns a reference to the found item. */ -OSStatus SecKeychainFindInternetPassword(CFTypeRef __nullable keychainOrArray, UInt32 serverNameLength, const char * __nullable serverName, UInt32 securityDomainLength, const char * __nullable securityDomain, UInt32 accountNameLength, const char * __nullable accountName, UInt32 pathLength, const char * __nullable path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 * __nullable passwordLength, void * __nullable * __nullable passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef); +OSStatus SecKeychainFindInternetPassword(CFTypeRef __nullable keychainOrArray, UInt32 serverNameLength, const char * __nullable serverName, UInt32 securityDomainLength, const char * __nullable securityDomain, UInt32 accountNameLength, const char * __nullable accountName, UInt32 pathLength, const char * __nullable path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 * __nullable passwordLength, void * __nullable * __nullable passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios); /*! @function SecKeychainAddGenericPassword @@ -540,7 +540,7 @@ OSStatus SecKeychainFindInternetPassword(CFTypeRef __nullable keychainOrArray, U @result A result code. See "Security Error Codes" (SecBase.h). @discussion The SecKeychainAddGenericPassword function adds a new generic password to the default keychain. Required parameters to identify the password are serviceName and accountName, which are application-defined strings. SecKeychainAddGenericPassword optionally returns a reference to the newly added item. */ -OSStatus SecKeychainAddGenericPassword(SecKeychainRef __nullable keychain, UInt32 serviceNameLength, const char * __nullable serviceName, UInt32 accountNameLength, const char * __nullable accountName, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef); +OSStatus SecKeychainAddGenericPassword(SecKeychainRef __nullable keychain, UInt32 serviceNameLength, const char * __nullable serviceName, UInt32 accountNameLength, const char * __nullable accountName, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios); /*! @function SecKeychainFindGenericPassword @@ -556,7 +556,7 @@ OSStatus SecKeychainAddGenericPassword(SecKeychainRef __nullable keychain, UInt3 @result A result code. See "Security Error Codes" (SecBase.h). @discussion The SecKeychainFindGenericPassword function finds the first generic password item which matches the attributes you provide. Most attributes are optional; you should pass only as many as you need to narrow the search sufficiently for your application's intended use. SecKeychainFindGenericPassword optionally returns a reference to the found item. */ -OSStatus SecKeychainFindGenericPassword(CFTypeRef __nullable keychainOrArray, UInt32 serviceNameLength, const char * __nullable serviceName, UInt32 accountNameLength, const char * __nullable accountName, UInt32 * __nullable passwordLength, void * __nullable * __nullable passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef); +OSStatus SecKeychainFindGenericPassword(CFTypeRef __nullable keychainOrArray, UInt32 serviceNameLength, const char * __nullable serviceName, UInt32 accountNameLength, const char * __nullable accountName, UInt32 * __nullable passwordLength, void * __nullable * __nullable passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios); #pragma mark ---- Managing User Interaction ---- /*! @@ -565,7 +565,7 @@ OSStatus SecKeychainFindGenericPassword(CFTypeRef __nullable keychainOrArray, U @param state A boolean representing the state of user interaction. You should pass TRUE to allow user interaction, and FALSE to disallow user interaction @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainSetUserInteractionAllowed(Boolean state); +OSStatus SecKeychainSetUserInteractionAllowed(Boolean state) API_UNAVAILABLE(ios); /*! @function SecKeychainGetUserInteractionAllowed @@ -573,7 +573,7 @@ OSStatus SecKeychainSetUserInteractionAllowed(Boolean state); @param state On return, a pointer to the current state of user interaction. If this is TRUE then user interaction is allowed, if it is FALSE, then user interaction is not allowed. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainGetUserInteractionAllowed(Boolean *state); +OSStatus SecKeychainGetUserInteractionAllowed(Boolean *state) API_UNAVAILABLE(ios); #pragma mark ---- CSSM Bridge Functions ---- /*! diff --git a/OSX/libsecurity_keychain/lib/SecKeychainItem.cpp b/OSX/libsecurity_keychain/lib/SecKeychainItem.cpp index dea894f9..06261009 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainItem.cpp +++ b/OSX/libsecurity_keychain/lib/SecKeychainItem.cpp @@ -604,7 +604,7 @@ static OSStatus SecKeychainItemCreatePersistentReferenceFromCertificate(SecCerti } CFErrorRef errorRef = NULL; - CFDataRef serialData = SecCertificateCopySerialNumber(certItem, &errorRef); + CFDataRef serialData = SecCertificateCopySerialNumberData(certItem, &errorRef); if (errorRef) { CFIndex err = CFErrorGetCode(errorRef); CFRelease(errorRef); diff --git a/OSX/libsecurity_keychain/lib/SecKeychainItem.h b/OSX/libsecurity_keychain/lib/SecKeychainItem.h index 4b579812..cbb51837 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainItem.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainItem.h @@ -160,7 +160,7 @@ CFTypeID SecKeychainItemGetTypeID(void); @result A result code. See "Security Error Codes" (SecBase.h). @discussion The keychain item is written to the keychain's permanent data store. If the keychain item has not previously been added to a keychain, a call to the SecKeychainItemModifyContent function does nothing and returns errSecSuccess. */ -OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data); +OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCreateFromContent @@ -176,7 +176,7 @@ OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, cons */ OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void * __nullable data, SecKeychainRef __nullable keychainRef, - SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef); + SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios); /*! @function SecKeychainItemModifyContent @@ -187,7 +187,7 @@ OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAtt @param data A pointer to a buffer containing the data to store. Pass NULL if you don't need to modify the data. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data); +OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCopyContent @@ -199,7 +199,7 @@ OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeych @param outData On return, a pointer to a buffer containing the data in this item. Pass NULL if you don't need to retrieve the data. You must call SecKeychainItemFreeContent when you no longer need the data. @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters are supplied. */ -OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData); +OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData) API_UNAVAILABLE(ios); /*! @function SecKeychainItemFreeContent @@ -207,7 +207,7 @@ OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass * _ @param attrList A pointer to the attribute list to release. Pass NULL to ignore this parameter. @param data A pointer to the data buffer to release. Pass NULL to ignore this parameter. */ -OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList * __nullable attrList, void * __nullable data); +OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList * __nullable attrList, void * __nullable data) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCopyAttributesAndData @@ -220,7 +220,7 @@ OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList * __nullable attrLi @param outData On return, a pointer to a buffer containing the data in this item. Pass NULL if you don't need to retrieve the data. You must call SecKeychainItemFreeAttributesAndData when you no longer need the data. @result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters are supplied. */ -OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo * __nullable info, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData); +OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo * __nullable info, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData) API_UNAVAILABLE(ios); /*! @function SecKeychainItemFreeAttributesAndData @@ -229,7 +229,7 @@ OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKey @param data A pointer to the data buffer to release. Pass NULL to ignore this parameter. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList * __nullable attrList, void * __nullable data); +OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList * __nullable attrList, void * __nullable data) API_UNAVAILABLE(ios); /*! @function SecKeychainItemDelete @@ -238,7 +238,7 @@ OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList * __nulla @result A result code. See "Security Error Codes" (SecBase.h). @discussion If itemRef has not previously been added to the keychain, SecKeychainItemDelete does nothing and returns errSecSuccess. IMPORTANT: SecKeychainItemDelete does not dispose the memory occupied by the item reference itself; use the CFRelease function when you are completely finished with an item. */ -OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef); +OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCopyKeychain @@ -247,7 +247,7 @@ OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef); @param keychainRef On return, the keychain reference for the specified item. Release this reference by calling the CFRelease function. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychainRef); +OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychainRef) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCreateCopy @@ -259,7 +259,7 @@ OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef @result A result code. See "Security Error Codes" (SecBase.h). */ OSStatus SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainRef __nullable destKeychainRef, - SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemCopy); + SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemCopy) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCreatePersistentReference @@ -268,7 +268,7 @@ OSStatus SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainRef __ @param persistentItemRef On return, a CFDataRef containing a persistent reference. You must release this data reference by calling the CFRelease function. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainItemCreatePersistentReference(SecKeychainItemRef itemRef, CFDataRef * __nonnull CF_RETURNS_RETAINED persistentItemRef); +OSStatus SecKeychainItemCreatePersistentReference(SecKeychainItemRef itemRef, CFDataRef * __nonnull CF_RETURNS_RETAINED persistentItemRef) API_UNAVAILABLE(ios); /*! @@ -278,7 +278,7 @@ OSStatus SecKeychainItemCreatePersistentReference(SecKeychainItemRef itemRef, CF @param itemRef On return, a SecKeychainItemRef for the keychain item described by the persistent reference. You must release this item reference by calling the CFRelease function. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainItemCopyFromPersistentReference(CFDataRef persistentItemRef, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemRef); +OSStatus SecKeychainItemCopyFromPersistentReference(CFDataRef persistentItemRef, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios); #pragma mark ---- CSSM Bridge Functions ---- @@ -312,7 +312,7 @@ OSStatus SecKeychainItemGetUniqueRecordID(SecKeychainItemRef itemRef, const CSSM @param access On return, a reference to the keychain item's access. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef * __nonnull CF_RETURNS_RETAINED access); +OSStatus SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef * __nonnull CF_RETURNS_RETAINED access) API_UNAVAILABLE(ios); /*! @function SecKeychainItemSetAccess @@ -321,7 +321,7 @@ OSStatus SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef * __ @param access A reference to an access to replace the keychain item's current access. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainItemSetAccess(SecKeychainItemRef itemRef, SecAccessRef access); +OSStatus SecKeychainItemSetAccess(SecKeychainItemRef itemRef, SecAccessRef access) API_UNAVAILABLE(ios); CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h b/OSX/libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h index 8a8f4080..98f8a436 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h @@ -75,8 +75,9 @@ extern "C" { OSStatus SecKeychainItemSetExtendedAttribute( SecKeychainItemRef itemRef, CFStringRef attrName, /* identifies the attribute */ - CFDataRef attrValue); /* value to set; NULL means delete the + CFDataRef attrValue) /* value to set; NULL means delete the * attribute */ + API_UNAVAILABLE(ios); /* * SecKeychainItemCopyExtendedAttribute() - Obtain the value of an an extended attribute. @@ -90,7 +91,7 @@ OSStatus SecKeychainItemSetExtendedAttribute( OSStatus SecKeychainItemCopyExtendedAttribute( SecKeychainItemRef itemRef, CFStringRef attrName, - CFDataRef *attrValue); /* RETURNED */ + CFDataRef *attrValue) API_UNAVAILABLE(ios); /* RETURNED */ /* * SecKeychainItemCopyAllExtendedAttributes() - obtain all of an item's extended attributes. @@ -116,8 +117,9 @@ OSStatus SecKeychainItemCopyExtendedAttribute( OSStatus SecKeychainItemCopyAllExtendedAttributes( SecKeychainItemRef itemRef, CFArrayRef *attrNames, /* RETURNED, each element is a CFStringRef */ - CFArrayRef *attrValues); /* optional, RETURNED, each element is a + CFArrayRef *attrValues) /* optional, RETURNED, each element is a * CFDataRef */ + API_UNAVAILABLE(ios); #if defined(__cplusplus) } #endif diff --git a/OSX/libsecurity_keychain/lib/SecKeychainItemPriv.h b/OSX/libsecurity_keychain/lib/SecKeychainItemPriv.h index 595be6ff..4893cff7 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainItemPriv.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainItemPriv.h @@ -72,23 +72,23 @@ enum { /* also kSecModDateItemAttr from SecKeychainItem.h */ }; -OSStatus SecKeychainItemCreateNew(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, SecKeychainItemRef* itemRef); +OSStatus SecKeychainItemCreateNew(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, SecKeychainItemRef* itemRef) API_UNAVAILABLE(ios); -OSStatus SecKeychainItemGetData(SecKeychainItemRef itemRef, UInt32 maxLength, void* data, UInt32* actualLength); +OSStatus SecKeychainItemGetData(SecKeychainItemRef itemRef, UInt32 maxLength, void* data, UInt32* actualLength) API_UNAVAILABLE(ios); -OSStatus SecKeychainItemGetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute, UInt32* actualLength); +OSStatus SecKeychainItemGetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute, UInt32* actualLength) API_UNAVAILABLE(ios); -OSStatus SecKeychainItemSetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute); +OSStatus SecKeychainItemSetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute) API_UNAVAILABLE(ios); -OSStatus SecKeychainItemAdd(SecKeychainItemRef itemRef); +OSStatus SecKeychainItemAdd(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios); -OSStatus SecKeychainItemAddNoUI(SecKeychainRef keychainRef, SecKeychainItemRef itemRef); +OSStatus SecKeychainItemAddNoUI(SecKeychainRef keychainRef, SecKeychainItemRef itemRef) API_UNAVAILABLE(ios); -OSStatus SecKeychainItemUpdate(SecKeychainItemRef itemRef); +OSStatus SecKeychainItemUpdate(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios); -OSStatus SecKeychainItemSetData(SecKeychainItemRef itemRef, UInt32 length, const void* data); +OSStatus SecKeychainItemSetData(SecKeychainItemRef itemRef, UInt32 length, const void* data) API_UNAVAILABLE(ios); -OSStatus SecKeychainItemFindFirst(SecKeychainRef keychainRef, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef, SecKeychainItemRef *itemRef); +OSStatus SecKeychainItemFindFirst(SecKeychainRef keychainRef, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef, SecKeychainItemRef *itemRef) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCopyRecordIdentifier @@ -98,7 +98,7 @@ OSStatus SecKeychainItemFindFirst(SecKeychainRef keychainRef, const SecKeychainA @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainItemCopyRecordIdentifier(SecKeychainItemRef itemRef, CFDataRef *recordIdentifier); +OSStatus SecKeychainItemCopyRecordIdentifier(SecKeychainItemRef itemRef, CFDataRef *recordIdentifier) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCopyFromRecordIdentifier @@ -111,7 +111,7 @@ OSStatus SecKeychainItemCopyRecordIdentifier(SecKeychainItemRef itemRef, CFDataR OSStatus SecKeychainItemCopyFromRecordIdentifier(SecKeychainRef keychain, SecKeychainItemRef *itemRef, - CFDataRef recordIdentifier); + CFDataRef recordIdentifier) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCopyAttributesAndEncryptedData @@ -128,7 +128,7 @@ OSStatus SecKeychainItemCopyFromRecordIdentifier(SecKeychainRef keychain, */ OSStatus SecKeychainItemCopyAttributesAndEncryptedData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, - UInt32 *length, void **outData); + UInt32 *length, void **outData) API_UNAVAILABLE(ios); /*! @function SecKeychainItemModifyEncryptedData @@ -140,7 +140,7 @@ OSStatus SecKeychainItemCopyAttributesAndEncryptedData(SecKeychainItemRef itemRe @result A result code. See "Security Error Codes" (SecBase.h). @discussion The keychain item is written to the keychain's permanent data store. If the keychain item has not previously been added to a keychain, a call to the SecKeychainItemModifyContent function does nothing and returns errSecSuccess. */ -OSStatus SecKeychainItemModifyEncryptedData(SecKeychainItemRef itemRef, UInt32 length, const void *data); +OSStatus SecKeychainItemModifyEncryptedData(SecKeychainItemRef itemRef, UInt32 length, const void *data) API_UNAVAILABLE(ios); /*! @function SecKeychainItemCreateFromEncryptedContent @@ -156,7 +156,7 @@ OSStatus SecKeychainItemModifyEncryptedData(SecKeychainItemRef itemRef, UInt32 l */ OSStatus SecKeychainItemCreateFromEncryptedContent(SecItemClass itemClass, UInt32 length, const void *data, SecKeychainRef keychainRef, SecAccessRef initialAccess, - SecKeychainItemRef *itemRef, CFDataRef *itemLocalID); + SecKeychainItemRef *itemRef, CFDataRef *itemLocalID) API_UNAVAILABLE(ios); /*! @function SecKeychainItemSetAccessWithPassword @@ -167,7 +167,7 @@ OSStatus SecKeychainItemCreateFromEncryptedContent(SecItemClass itemClass, UInt3 @param password A buffer containing the password for the keychain. if this password is incorrect, this call might fail---it will not prompt the user. @result A result code. See "Security Error Codes" (SecBase.h). */ - OSStatus SecKeychainItemSetAccessWithPassword(SecKeychainItemRef itemRef, SecAccessRef accessRef, UInt32 passwordLength, const void * password); + OSStatus SecKeychainItemSetAccessWithPassword(SecKeychainItemRef itemRef, SecAccessRef accessRef, UInt32 passwordLength, const void * password) API_UNAVAILABLE(ios); #if defined(__cplusplus) } #endif diff --git a/OSX/libsecurity_keychain/lib/SecKeychainPriv.h b/OSX/libsecurity_keychain/lib/SecKeychainPriv.h index 0847e8d5..54a6b539 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainPriv.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainPriv.h @@ -26,6 +26,7 @@ #include #include +#include #include #if defined(__cplusplus) @@ -48,7 +49,7 @@ OSStatus SecKeychainIsValid(SecKeychainRef keychainRef, Boolean* isValid) OSStatus SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void *oldPassword, UInt32 newPasswordLength, const void *newPassword) __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA); OSStatus SecKeychainOpenWithGuid(const CSSM_GUID *guid, uint32 subserviceId, uint32 subserviceType, const char* dbName, const CSSM_NET_ADDRESS *dbLocation, SecKeychainRef *keychain) - __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); + API_DEPRECATED("CSSM_GUID/CSSM_NET_ADDRESS is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios); OSStatus SecKeychainSetBatchMode (SecKeychainRef kcRef, Boolean mode, Boolean rollback) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); @@ -65,9 +66,9 @@ OSStatus SecKeychainRemoveFromSearchList(SecKeychainRef keychainRef) /* Login keychain support */ OSStatus SecKeychainLogin(UInt32 nameLength, const void* name, UInt32 passwordLength, const void* password) __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA); -OSStatus SecKeychainStash() +OSStatus SecKeychainStash(void) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA); -OSStatus SecKeychainLogout() +OSStatus SecKeychainLogout(void) __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA); OSStatus SecKeychainCopyLogin(SecKeychainRef *keychainRef) __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA); @@ -76,7 +77,7 @@ OSStatus SecKeychainResetLogin(UInt32 passwordLength, const void* password, Bool OSStatus SecKeychainVerifyKeyStorePassphrase(uint32_t retries) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA); -OSStatus SecKeychainChangeKeyStorePassphrase() +OSStatus SecKeychainChangeKeyStorePassphrase(void) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA); /* Keychain synchronization */ @@ -97,20 +98,20 @@ OSStatus SecKeychainCreateWithBlob(const char* fullPathName, CFDataRef dbBlob, S /* Keychain list manipulation */ OSStatus SecKeychainAddDBToKeychainList (SecPreferencesDomain domain, const char* dbName, const CSSM_GUID *guid, uint32 subServiceType) - __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); + API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios); OSStatus SecKeychainDBIsInKeychainList (SecPreferencesDomain domain, const char* dbName, const CSSM_GUID *guid, uint32 subServiceType) - __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); + API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios); OSStatus SecKeychainRemoveDBFromKeychainList (SecPreferencesDomain domain, const char* dbName, const CSSM_GUID *guid, uint32 subServiceType) - __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); + API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios); /* server operation (keychain inhibit) */ -void SecKeychainSetServerMode() +void SecKeychainSetServerMode(void) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); /* special calls */ -OSStatus SecKeychainCleanupHandles() +OSStatus SecKeychainCleanupHandles(void) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); -OSStatus SecKeychainSystemKeychainCheckWouldDeadlock() +OSStatus SecKeychainSystemKeychainCheckWouldDeadlock(void) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); OSStatus SecKeychainStoreUnlockKey(SecKeychainRef userKeychainRef, SecKeychainRef systemKeychainRef, CFStringRef username, CFStringRef password) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_NA); @@ -136,7 +137,7 @@ OSStatus SecKeychainGetUserPromptAttempts(uint32_t* attempts) @function SecKeychainMDSInstall Set up MDS. */ -OSStatus SecKeychainMDSInstall(); +OSStatus SecKeychainMDSInstall(void); #if defined(__cplusplus) } diff --git a/OSX/libsecurity_keychain/lib/SecPassword.h b/OSX/libsecurity_keychain/lib/SecPassword.h index 926e3c47..5d9afb93 100644 --- a/OSX/libsecurity_keychain/lib/SecPassword.h +++ b/OSX/libsecurity_keychain/lib/SecPassword.h @@ -65,7 +65,7 @@ enum { @param itemAttrList (in/opt) A list of attributes which will be used for item creation. @param itemRef (out) On return, a pointer to a password reference. Release this by calling the CFRelease function. */ -OSStatus SecGenericPasswordCreate(SecKeychainAttributeList *searchAttrList, SecKeychainAttributeList *itemAttrList, SecPasswordRef *itemRef); +OSStatus SecGenericPasswordCreate(SecKeychainAttributeList *searchAttrList, SecKeychainAttributeList *itemAttrList, SecPasswordRef *itemRef) API_UNAVAILABLE(ios); /*! @function SecPasswordAction @@ -80,13 +80,13 @@ OSStatus SecGenericPasswordCreate(SecKeychainAttributeList *searchAttrList, SecK @param data A pointer to a buffer containing the data to store. */ -OSStatus SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt32 *length, const void **data); +OSStatus SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt32 *length, const void **data) API_UNAVAILABLE(ios); /*! @function SecPasswordSetInitialAccess @abstract Set the initial access ref. Only used when a password is first added to the keychain. */ -OSStatus SecPasswordSetInitialAccess(SecPasswordRef itemRef, SecAccessRef accessRef); +OSStatus SecPasswordSetInitialAccess(SecPasswordRef itemRef, SecAccessRef accessRef) API_UNAVAILABLE(ios); #if defined(__cplusplus) } diff --git a/OSX/libsecurity_keychain/lib/SecPolicy.cpp b/OSX/libsecurity_keychain/lib/SecPolicy.cpp index 35ec80ec..56aeaefd 100644 --- a/OSX/libsecurity_keychain/lib/SecPolicy.cpp +++ b/OSX/libsecurity_keychain/lib/SecPolicy.cpp @@ -80,60 +80,73 @@ typedef struct oidmap_entry_s oidmap_entry_t; static_cast(&CSSMOID_APPLE_TP_APPLEID_SHARING), static_cast(&CSSMOID_APPLE_TP_TIMESTAMPING), */ -const oidmap_entry_t oidmap[] = { - { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC }, - { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL }, - { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME }, - { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP }, - { kSecPolicyAppleSWUpdateSigning, &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING }, - { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC }, - { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT }, - { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT }, - { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER }, - { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING }, - { kSecPolicyApplePackageSigning, &CSSMOID_APPLE_TP_PACKAGE_SIGNING }, - { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING }, - { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT }, - { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING }, - { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION }, - { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_OCSP }, - { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_CRL }, - { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING }, - { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE }, - { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE }, - { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING }, - { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING }, - { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE }, - { kSecPolicyApplePCSEscrowService, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE }, - { kSecPolicyAppleOSXProvisioningProfileSigning, &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING }, -}; -const oidmap_entry_t oidmap_priv[] = { - { CFSTR("basicX509"), &CSSMOID_APPLE_X509_BASIC }, - { CFSTR("sslServer"), &CSSMOID_APPLE_TP_SSL }, - { CFSTR("sslClient"), &CSSMOID_APPLE_TP_SSL }, - { CFSTR("SMIME"), &CSSMOID_APPLE_TP_SMIME }, - { CFSTR("eapServer"), &CSSMOID_APPLE_TP_EAP }, - { CFSTR("eapClient"), &CSSMOID_APPLE_TP_EAP }, - { CFSTR("AppleSWUpdateSigning"), &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING }, - { CFSTR("ipsecServer"), &CSSMOID_APPLE_TP_IP_SEC }, - { CFSTR("ipsecClient"), &CSSMOID_APPLE_TP_IP_SEC }, - { CFSTR("CodeSigning"), &CSSMOID_APPLE_TP_CODE_SIGNING }, - { CFSTR("PackageSigning"), &CSSMOID_APPLE_TP_PACKAGE_SIGNING }, - { CFSTR("AppleIDAuthority"), &CSSMOID_APPLE_TP_APPLEID_SHARING }, - { CFSTR("MacAppStoreReceipt"), &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT }, - { CFSTR("AppleTimeStamping"), &CSSMOID_APPLE_TP_TIMESTAMPING }, - { CFSTR("revocation"), &CSSMOID_APPLE_TP_REVOCATION }, - { CFSTR("ApplePassbook"), &CSSMOID_APPLE_TP_PASSBOOK_SIGNING }, - { CFSTR("AppleMobileStore"), &CSSMOID_APPLE_TP_MOBILE_STORE }, - { CFSTR("AppleEscrowService"), &CSSMOID_APPLE_TP_ESCROW_SERVICE }, - { CFSTR("AppleProfileSigner"), &CSSMOID_APPLE_TP_PROFILE_SIGNING }, - { CFSTR("AppleQAProfileSigner"), &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING }, - { CFSTR("AppleTestMobileStore"), &CSSMOID_APPLE_TP_TEST_MOBILE_STORE }, - { CFSTR("ApplePCSEscrowService"), &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE }, - { CFSTR("AppleOSXProvisioningProfileSigning"), &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING }, +static const size_t OIDMAP_LENGTH = 25; +static const oidmap_entry_t* oidmap_f() { + static const oidmap_entry_t oidmap_array[] = { + { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC }, + { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL }, + { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME }, + { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP }, + { kSecPolicyAppleSWUpdateSigning, &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING }, + { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC }, + { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT }, + { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT }, + { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER }, + { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING }, + { kSecPolicyApplePackageSigning, &CSSMOID_APPLE_TP_PACKAGE_SIGNING }, + { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING }, + { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT }, + { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING }, + { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION }, + { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_OCSP }, + { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_CRL }, + { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING }, + { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE }, + { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE }, + { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING }, + { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING }, + { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE }, + { kSecPolicyApplePCSEscrowService, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE }, + { kSecPolicyAppleOSXProvisioningProfileSigning, &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING }, + }; + static_assert(OIDMAP_LENGTH == (sizeof(oidmap_array)/sizeof(oidmap_entry_t)), "OIDMAP_LENGTH is incorrect; must match oidmap_array"); + + return oidmap_array; }; +static const size_t OIDMAP_PRIV_LENGTH = 23; +static const oidmap_entry_t* oidmap_priv_f() { + static const oidmap_entry_t oidmap_priv_array[] = { + { CFSTR("basicX509"), &CSSMOID_APPLE_X509_BASIC }, + { CFSTR("sslServer"), &CSSMOID_APPLE_TP_SSL }, + { CFSTR("sslClient"), &CSSMOID_APPLE_TP_SSL }, + { CFSTR("SMIME"), &CSSMOID_APPLE_TP_SMIME }, + { CFSTR("eapServer"), &CSSMOID_APPLE_TP_EAP }, + { CFSTR("eapClient"), &CSSMOID_APPLE_TP_EAP }, + { CFSTR("AppleSWUpdateSigning"), &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING }, + { CFSTR("ipsecServer"), &CSSMOID_APPLE_TP_IP_SEC }, + { CFSTR("ipsecClient"), &CSSMOID_APPLE_TP_IP_SEC }, + { CFSTR("CodeSigning"), &CSSMOID_APPLE_TP_CODE_SIGNING }, + { CFSTR("PackageSigning"), &CSSMOID_APPLE_TP_PACKAGE_SIGNING }, + { CFSTR("AppleIDAuthority"), &CSSMOID_APPLE_TP_APPLEID_SHARING }, + { CFSTR("MacAppStoreReceipt"), &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT }, + { CFSTR("AppleTimeStamping"), &CSSMOID_APPLE_TP_TIMESTAMPING }, + { CFSTR("revocation"), &CSSMOID_APPLE_TP_REVOCATION }, + { CFSTR("ApplePassbook"), &CSSMOID_APPLE_TP_PASSBOOK_SIGNING }, + { CFSTR("AppleMobileStore"), &CSSMOID_APPLE_TP_MOBILE_STORE }, + { CFSTR("AppleEscrowService"), &CSSMOID_APPLE_TP_ESCROW_SERVICE }, + { CFSTR("AppleProfileSigner"), &CSSMOID_APPLE_TP_PROFILE_SIGNING }, + { CFSTR("AppleQAProfileSigner"), &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING }, + { CFSTR("AppleTestMobileStore"), &CSSMOID_APPLE_TP_TEST_MOBILE_STORE }, + { CFSTR("ApplePCSEscrowService"), &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE }, + { CFSTR("AppleOSXProvisioningProfileSigning"), &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING }, + }; + static_assert(OIDMAP_PRIV_LENGTH == (sizeof(oidmap_priv_array)/sizeof(oidmap_entry_t)), "OIDMAP_PRIV_LENGTH is incorrect; must match oidmap_priv_array"); + + return oidmap_priv_array; +} + // // Sec API bridge functions // @@ -150,21 +163,21 @@ SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid) return errSecParam; // bad policy ref? } CSSM_OID *oidptr = NULL; - unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t); - for (i=0; i gUserAdminCertsLock; void SecTrustSettingsPurgeUserAdminCertsCache(void) { - StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Write); + StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Write); CFReleaseNull(gUserAdminCerts); gUserAdminCertsCacheBuilt = false; } @@ -946,7 +948,7 @@ OSStatus SecTrustSettingsCopyCertificatesForUserAdminDomains( OSStatus result = errSecSuccess; { /* Hold the read lock for the check */ - StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Read); + StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Read); if (gUserAdminCertsCacheBuilt) { if (gUserAdminCerts) { *certArray = (CFArrayRef)CFRetain(gUserAdminCerts); @@ -991,7 +993,7 @@ OSStatus SecTrustSettingsCopyCertificatesForUserAdminDomains( /* For valid results, update the global cache */ if (result == errSecSuccess || result == errSecNoTrustSettings) { - StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Write); + StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Write); CFReleaseNull(gUserAdminCerts); gUserAdminCerts = (CFArrayRef)CFRetainSafe(outArray); gUserAdminCertsCacheBuilt = true; diff --git a/OSX/libsecurity_keychain/lib/SecTrustedApplication.h b/OSX/libsecurity_keychain/lib/SecTrustedApplication.h index 18f9d39a..9995db4b 100644 --- a/OSX/libsecurity_keychain/lib/SecTrustedApplication.h +++ b/OSX/libsecurity_keychain/lib/SecTrustedApplication.h @@ -56,7 +56,7 @@ CFTypeID SecTrustedApplicationGetTypeID(void); @param app On return, a pointer to the trusted application reference. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecTrustedApplicationCreateFromPath(const char * __nullable path, SecTrustedApplicationRef * __nonnull CF_RETURNS_RETAINED app); +OSStatus SecTrustedApplicationCreateFromPath(const char * __nullable path, SecTrustedApplicationRef * __nonnull CF_RETURNS_RETAINED app) API_UNAVAILABLE(ios); /*! @function SecTrustedApplicationCopyData @@ -65,7 +65,7 @@ OSStatus SecTrustedApplicationCreateFromPath(const char * __nullable path, SecTr @param data On return, a pointer to a data reference of the trusted application. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecTrustedApplicationCopyData(SecTrustedApplicationRef appRef, CFDataRef * __nonnull CF_RETURNS_RETAINED data); +OSStatus SecTrustedApplicationCopyData(SecTrustedApplicationRef appRef, CFDataRef * __nonnull CF_RETURNS_RETAINED data) API_UNAVAILABLE(ios); /*! @function SecTrustedApplicationSetData @@ -74,7 +74,7 @@ OSStatus SecTrustedApplicationCopyData(SecTrustedApplicationRef appRef, CFDataRe @param data A reference to the data to set in the trusted application. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecTrustedApplicationSetData(SecTrustedApplicationRef appRef, CFDataRef data); +OSStatus SecTrustedApplicationSetData(SecTrustedApplicationRef appRef, CFDataRef data) API_UNAVAILABLE(ios); CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_keychain/lib/SecTrustedApplicationPriv.h b/OSX/libsecurity_keychain/lib/SecTrustedApplicationPriv.h index 9b549a47..ce5d6aa5 100644 --- a/OSX/libsecurity_keychain/lib/SecTrustedApplicationPriv.h +++ b/OSX/libsecurity_keychain/lib/SecTrustedApplicationPriv.h @@ -42,7 +42,7 @@ extern "C" { * Determine whether the application at path satisfies the trust expressed in appRef. */ OSStatus -SecTrustedApplicationValidateWithPath(SecTrustedApplicationRef appRef, const char *path); +SecTrustedApplicationValidateWithPath(SecTrustedApplicationRef appRef, const char *path) API_UNAVAILABLE(ios); /*! @function SecTrustedApplicationCreateFromRequirement @@ -60,7 +60,7 @@ SecTrustedApplicationValidateWithPath(SecTrustedApplicationRef appRef, const cha @result A result code. See SecBase.h and CSCommon.h. */ OSStatus SecTrustedApplicationCreateFromRequirement(const char *description, - SecRequirementRef requirement, SecTrustedApplicationRef *app); + SecRequirementRef requirement, SecTrustedApplicationRef *app) API_UNAVAILABLE(ios); /*! @function SecTrustedApplicationCopyRequirement @@ -78,7 +78,7 @@ OSStatus SecTrustedApplicationCreateFromRequirement(const char *description, no SecRequirementRef could be obtained. */ OSStatus SecTrustedApplicationCopyRequirement(SecTrustedApplicationRef appRef, - SecRequirementRef *requirement); + SecRequirementRef *requirement) API_UNAVAILABLE(ios); /*! @@ -101,7 +101,7 @@ OSStatus SecTrustedApplicationCopyRequirement(SecTrustedApplicationRef appRef, @result A result code. See SecBase.h and CSCommon.h. */ OSStatus SecTrustedApplicationCreateApplicationGroup(const char *groupName, - SecCertificateRef anchor, SecTrustedApplicationRef *app); + SecCertificateRef anchor, SecTrustedApplicationRef *app) API_UNAVAILABLE(ios); /*! @@ -118,7 +118,7 @@ OSStatus SecTrustedApplicationCreateApplicationGroup(const char *groupName, */ OSStatus SecTrustedApplicationCopyExternalRepresentation( SecTrustedApplicationRef appRef, - CFDataRef *externalRef); + CFDataRef *externalRef) API_UNAVAILABLE(ios); /*! @function SecTrustedApplicationCreateWithExternalRepresentation @@ -133,7 +133,7 @@ OSStatus SecTrustedApplicationCopyExternalRepresentation( */ OSStatus SecTrustedApplicationCreateWithExternalRepresentation( CFDataRef externalRef, - SecTrustedApplicationRef *appRef); + SecTrustedApplicationRef *appRef) API_UNAVAILABLE(ios); /* @@ -146,10 +146,10 @@ enum { OSStatus SecTrustedApplicationMakeEquivalent(SecTrustedApplicationRef oldRef, - SecTrustedApplicationRef newRef, UInt32 flags); + SecTrustedApplicationRef newRef, UInt32 flags) API_UNAVAILABLE(ios); OSStatus -SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 flags); +SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 flags) API_UNAVAILABLE(ios); /* @@ -157,7 +157,7 @@ SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 f * pre-emptive code equivalency establishment */ OSStatus -SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path); +SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path) API_UNAVAILABLE(ios); /* @@ -165,7 +165,7 @@ SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path * This is for system update installers (only)! */ OSStatus -SecTrustedApplicationUseAlternateSystem(const char *systemRoot); +SecTrustedApplicationUseAlternateSystem(const char *systemRoot) API_UNAVAILABLE(ios); #if defined(__cplusplus) diff --git a/OSX/libsecurity_keychain/lib/StorageManager.cpp b/OSX/libsecurity_keychain/lib/StorageManager.cpp index 0bd0760e..c8484cea 100644 --- a/OSX/libsecurity_keychain/lib/StorageManager.cpp +++ b/OSX/libsecurity_keychain/lib/StorageManager.cpp @@ -414,15 +414,17 @@ StorageManager::tickleKeychain(KeychainImpl *keychainImpl) { __block CFTypeRef kcHandle = kcImpl->handle(); // calls retain; this keychain object will stay around until our dispatch block fires. - dispatch_async(release_queue, ^() { + // You _must not_ call CFRelease while on this queue, due to the locking order mishmash. CFRelease takes a lock, so remember to do it later. + __block bool releaseImmediately = false; + + dispatch_sync(release_queue, ^() { if(kcImpl->mCacheTimer) { // Update the cache timer to be seconds from now dispatch_source_set_timer(kcImpl->mCacheTimer, dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, NSEC_PER_SEC/2); secdebug("keychain", "updating cache on %p %s", kcImpl, kcImpl->name()); - // We've added an extra retain to this keychain right before invoking this block. Release it. - CFRelease(kcHandle); - + // We've added an extra retain to this keychain right before invoking this block. Remember to release it. + releaseImmediately = true; } else { // No cache timer; make one. kcImpl->mCacheTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, release_queue); @@ -434,12 +436,21 @@ StorageManager::tickleKeychain(KeychainImpl *keychainImpl) { dispatch_source_cancel(kcImpl->mCacheTimer); dispatch_release(kcImpl->mCacheTimer); kcImpl->mCacheTimer = NULL; - CFRelease(kcHandle); + + // Since we're on the timer queue, we can't call CFRelease on the kcHandle (since that takes a lock). Dispatch_async it over to some other queue... + // This is better than using dispatch_async on the timer queue initially, since it's less dispatch_asyncs overall, even though it's more confusing. + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^{ + CFRelease(kcHandle); + }); }); dispatch_resume(kcImpl->mCacheTimer); } }); + + if(releaseImmediately) { + CFRelease(kcHandle); + } } // Create keychain if it doesn't exist, and optionally add it to the search list. diff --git a/OSX/libsecurity_keychain/lib/TokenLogin.cpp b/OSX/libsecurity_keychain/lib/TokenLogin.cpp index f0ec1fef..77bf44da 100644 --- a/OSX/libsecurity_keychain/lib/TokenLogin.cpp +++ b/OSX/libsecurity_keychain/lib/TokenLogin.cpp @@ -39,6 +39,14 @@ extern "C" { #include } +static os_log_t TOKEN_LOG_DEFAULT() { + static dispatch_once_t once; + static os_log_t log; + dispatch_once(&once, ^{ log = os_log_create("com.apple.security", "tokenlogin"); }); + return log; +}; +#define TL_LOG TOKEN_LOG_DEFAULT() + #define kSecTokenLoginDomain CFSTR("com.apple.security.tokenlogin") static CFStringRef CF_RETURNS_RETAINED cfDataToHex(CFDataRef bin) @@ -77,7 +85,7 @@ static CFStringRef getTokenId(CFDictionaryRef context) CFStringRef tokenId = (CFStringRef)CFDictionaryGetValue(context, kSecAttrTokenID); if (!tokenId || CFGetTypeID(tokenId) != CFStringGetTypeID()) { - secinfo("TokenLogin", "Invalid tokenId"); + os_log_debug(TL_LOG, "Invalid tokenId"); return NULL; } return tokenId; @@ -91,7 +99,7 @@ static CFDataRef getPubKeyHash(CFDictionaryRef context) CFDataRef pubKeyHash = (CFDataRef)CFDictionaryGetValue(context, kSecAttrPublicKeyHash); if (!pubKeyHash || CFGetTypeID(pubKeyHash) != CFDataGetTypeID()) { - secinfo("TokenLogin", "Invalid pubkeyhash"); + os_log_debug(TL_LOG, "Invalid pubkeyhash"); return NULL; } return pubKeyHash; @@ -105,7 +113,7 @@ static CFDataRef getPubKeyHashWrap(CFDictionaryRef context) CFDataRef pubKeyHashWrap = (CFDataRef)CFDictionaryGetValue(context, kSecAttrAccount); if (!pubKeyHashWrap || CFGetTypeID(pubKeyHashWrap) != CFDataGetTypeID()) { - secinfo("TokenLogin", "Invalid pubkeyhashwrap"); + os_log_debug(TL_LOG, "Invalid pubkeyhashwrap"); return NULL; } return pubKeyHashWrap; @@ -113,9 +121,10 @@ static CFDataRef getPubKeyHashWrap(CFDictionaryRef context) static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey, CFTypeRef *laCtx) { - if (!context) { - return errSecParam; - } + if (!context) { + os_log_error(TL_LOG, "private key for pubkeyhash wrong params"); + return errSecParam; + } CFRef tokenAttributes = makeCFMutableDictionary(1, kSecAttrTokenID, getTokenId(context)); CFRef error; @@ -124,14 +133,14 @@ static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey if (pin) { CFRef LAContext = LACreateNewContextWithACMContext(NULL, error.take()); if (!LAContext) { - secinfo("TokenLogin", "Failed to LA Context: %@", error.get()); + os_log_error(TL_LOG, "Failed to LA Context: %@", error.get()); return errSecParam; } if (laCtx) *laCtx = (CFTypeRef)CFRetain(LAContext); CFRef externalizedContext = LACopyACMContext(LAContext, error.take()); if (!externalizedContext) { - secinfo("TokenLogin", "Failed to get externalized context: %@", error.get()); + os_log_error(TL_LOG, "Failed to get externalized context: %@", error.get()); return errSecParam; } CFDictionarySetValue(tokenAttributes, kSecUseCredentialReference, externalizedContext.get()); @@ -140,13 +149,13 @@ static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey CFRef token = TKTokenCreate(tokenAttributes, error.take()); if (!token) { - secinfo("TokenLogin", "Failed to create token: %@", error.get()); + os_log_error(TL_LOG, "Failed to create token: %@", error.get()); return errSecParam; } CFRef identities = TKTokenCopyIdentities(token, TKTokenKeyUsageAny, error.take()); if (!identities || !CFArrayGetCount(identities)) { - secinfo("TokenLogin", "No identities found for token: %@", error.get()); + os_log_error(TL_LOG, "No identities found for token: %@", error.get()); return errSecParam; } @@ -157,7 +166,7 @@ static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey CFRef certificate; OSStatus result = SecIdentityCopyCertificate(identity, certificate.take()); if (result != errSecSuccess) { - secinfo("TokenLogin", "Failed to get certificate for identity: %d", (int) result); + os_log_error(TL_LOG, "Failed to get certificate for identity: %d", (int) result); continue; } @@ -165,7 +174,7 @@ static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey if (identityHash && CFEqual(desiredHash, identityHash)) { result = SecIdentityCopyPrivateKey(identity, privKey); if (result != errSecSuccess) { - secinfo("TokenLogin", "Failed to get identity private key: %d", (int) result); + os_log_error(TL_LOG, "Failed to get identity private key: %d", (int) result); } return result; } @@ -176,21 +185,22 @@ static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey OSStatus TokenLoginGetContext(const void *base64TokenLoginData, UInt32 base64TokenLoginDataLength, CFDictionaryRef *context) { - if (!base64TokenLoginData || !context) { - return errSecParam; - } + if (!base64TokenLoginData || !context) { + os_log_error(TL_LOG, "Get login context - wrong params"); + return errSecParam; + } // Token data are base64 encoded in password. size_t dataLen = SecBase64Decode((const char *)base64TokenLoginData, base64TokenLoginDataLength, NULL, 0); if (!dataLen) { - secinfo("TokenLogin", "Invalid base64 encoded token data"); + os_log_debug(TL_LOG, "Invalid base64 encoded token data"); return errSecParam; } CFRef data = CFDataCreateMutable(kCFAllocatorDefault, dataLen); dataLen = SecBase64Decode((const char *)base64TokenLoginData, base64TokenLoginDataLength, CFDataGetMutableBytePtr(data), dataLen); if (!dataLen) { - secinfo("TokenLogin", "Invalid base64 encoded token data"); + os_log_error(TL_LOG, "Invalid base64 encoded token data"); return errSecParam; } CFDataSetLength(data, dataLen); @@ -203,12 +213,12 @@ OSStatus TokenLoginGetContext(const void *base64TokenLoginData, UInt32 base64Tok NULL, error.take()); if (!*context || CFGetTypeID(*context) != CFDictionaryGetTypeID()) { - secinfo("TokenLogin", "Invalid token login data property list, %@", error.get()); + os_log_error(TL_LOG, "Invalid token login data property list, %@", error.get()); return errSecParam; } if (!getPin(*context) || !getTokenId(*context) || !getPubKeyHash(*context) || !getPubKeyHashWrap(*context)) { - secinfo("TokenLogin", "Invalid token login data context, %@", error.get()); + os_log_error(TL_LOG, "Invalid token login data context, %@", error.get()); return errSecParam; } @@ -217,25 +227,26 @@ OSStatus TokenLoginGetContext(const void *base64TokenLoginData, UInt32 base64Tok OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey) { - if (!context || !unlockKey) { - return errSecParam; - } + if (!context || !unlockKey) { + os_log_error(TL_LOG, "Get unlock key - wrong params"); + return errSecParam; + } CFRef loginData; OSStatus result = TokenLoginGetLoginData(context, loginData.take()); if (result != errSecSuccess) { - secinfo("TokenLogin", "Failed to get login data: %d", (int)result); + os_log_error(TL_LOG, "Failed to get login data: %d", (int)result); return result; } CFDataRef wrappedUnlockKey = (CFDataRef)CFDictionaryGetValue(loginData, kSecValueData); if (!wrappedUnlockKey) { - secinfo("TokenLogin", "Wrapped unlock key not found in unlock key data"); + os_log_error(TL_LOG, "Wrapped unlock key not found in unlock key data"); return errSecParam; } SecKeyAlgorithm algorithm = (SecKeyAlgorithm)CFDictionaryGetValue(loginData, kSecAttrService); if (!algorithm) { - secinfo("TokenLogin", "Algorithm not found in unlock key data"); + os_log_error(TL_LOG, "Algorithm not found in unlock key data"); return errSecParam; } @@ -243,13 +254,13 @@ OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey) CFRef LAContext; result = privKeyForPubKeyHash(context, privKey.take(), LAContext.take()); if (result != errSecSuccess) { - secinfo("TokenLogin", "Failed to get private key for public key hash: %d", (int)result); + os_log_error(TL_LOG, "Failed to get private key for public key hash: %d", (int)result); return result; } CFRef pubKey = SecKeyCopyPublicKey(privKey); if (!pubKey) { - secinfo("TokenLogin", "Failed to get public key from private key"); + os_log_error(TL_LOG, "Failed to get public key from private key"); return errSecParam; } CFRef error; @@ -258,14 +269,14 @@ OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey) wrappedUnlockKey, error.take()); if (!*unlockKey) { - secinfo("TokenLogin", "Failed to unwrap unlock key: %@", error.get()); + os_log_error(TL_LOG, "Failed to unwrap unlock key: %@", error.get()); return errSecDecode; } // we need to re-wrap already unwrapped data to avoid capturing and reusing communication with the smartcard CFRef reWrappedUnlockKey = SecKeyCreateEncryptedData(pubKey, algorithm, *unlockKey, error.take()); if (!reWrappedUnlockKey) { - secinfo("TokenLogin", "Failed to rewrap unlock key: %@", error.get()); + os_log_error(TL_LOG, "Failed to rewrap unlock key: %@", error.get()); TokenLoginDeleteUnlockData(getPubKeyHash(context)); return errSecParam; } @@ -281,15 +292,30 @@ OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey) OSStatus TokenLoginGetLoginData(CFDictionaryRef context, CFDictionaryRef *loginData) { - if (!loginData || !context) { - return errSecParam; - } + os_log(TL_LOG, "secinfo TokenLoginGetLoginData"); + secinfo("TokenLogin", "secinfo TokenLoginGetLoginData"); + + os_log(TL_LOG, "secerror"); + secerror("secerror"); + + os_log(TL_LOG, "secwarning"); + secwarning("secwarning"); + + if (!loginData || !context) { + os_log_error(TL_LOG, "Get login data - wrong params"); + return errSecParam; + } CFRef pubKeyHashHex = cfDataToHex(getPubKeyHash(context)); + os_log(TL_LOG, "pubkeyhash %@", pubKeyHashHex.get()); + CFPreferencesSynchronize(kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); CFRef storedData = (CFDataRef)CFPreferencesCopyValue(pubKeyHashHex, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); - if (!storedData) { - secinfo("TokenLogin", "Failed to read token login plist"); + os_log(TL_LOG, "stored data %@", storedData.get()); + + if (!storedData) { + os_log_debug(TL_LOG, "Failed to read token login plist"); + os_log(TL_LOG, "Failed to read token login plist"); return errSecIO; } @@ -300,7 +326,7 @@ OSStatus TokenLoginGetLoginData(CFDictionaryRef context, CFDictionaryRef *loginD NULL, error.take()); if (!*loginData || CFGetTypeID(*loginData) != CFDictionaryGetTypeID()) { - secinfo("TokenLogin", "Failed to deserialize unlock key data: %@", error.get()); + os_log_error(TL_LOG, "Failed to deserialize unlock key data: %@", error.get()); return errSecParam; } @@ -319,14 +345,15 @@ OSStatus TokenLoginGetPin(CFDictionaryRef context, CFStringRef *pin) OSStatus TokenLoginUpdateUnlockData(CFDictionaryRef context, CFStringRef password) { - if (!context) { - return errSecParam; - } + if (!context) { + os_log_error(TL_LOG, "Updating unlock data - wrong params"); + return errSecParam; + } CFRef loginKeychain; OSStatus result = SecKeychainCopyLogin(loginKeychain.take()); if (result != errSecSuccess) { - secinfo("TokenLogin", "Failed to get user keychain: %d", (int) result); + os_log_error(TL_LOG, "Failed to get user keychain: %d", (int) result); return result; } @@ -335,8 +362,10 @@ OSStatus TokenLoginUpdateUnlockData(CFDictionaryRef context, CFStringRef passwor OSStatus TokenLoginCreateLoginData(CFStringRef tokenId, CFDataRef pubKeyHash, CFDataRef pubKeyHashWrap, CFDataRef unlockKey, CFDataRef scBlob) { - if (!tokenId || !pubKeyHash || !pubKeyHashWrap || !unlockKey || !scBlob) - return errSecParam; + if (!tokenId || !pubKeyHash || !pubKeyHashWrap || !unlockKey || !scBlob) { + os_log_error(TL_LOG, "Create login data - wrong params"); + return errSecParam; + } CFRef ctx = makeCFDictionary(3, kSecAttrTokenID, tokenId, @@ -346,13 +375,13 @@ OSStatus TokenLoginCreateLoginData(CFStringRef tokenId, CFDataRef pubKeyHash, CF CFRef privKey; OSStatus result = privKeyForPubKeyHash(ctx, privKey.take(), NULL); if (result != errSecSuccess) { - secinfo("TokenLogin", "Failed to get private key for public key hash: %d", (int) result); + os_log_error(TL_LOG, "Failed to get private key for public key hash: %d", (int) result); return result; } CFRef pubKey = SecKeyCopyPublicKey(privKey); if (!pubKey) { - secinfo("TokenLogin", "Failed to get public key from private key"); + os_log_error(TL_LOG, "Failed to get public key from private key"); return errSecParam; } @@ -378,14 +407,14 @@ OSStatus TokenLoginCreateLoginData(CFStringRef tokenId, CFDataRef pubKeyHash, CF } } if (algorithm == NULL) { - secinfo("SecKeychain", "Failed to find supported wrap algorithm"); + os_log_error(TL_LOG, "Failed to find supported wrap algorithm"); return errSecParam; } CFRef error; CFRef wrappedUnlockKey = SecKeyCreateEncryptedData(pubKey, algorithm, unlockKey, error.take()); if (!wrappedUnlockKey) { - secinfo("TokenLogin", "Failed to wrap unlock key: %@", error.get()); + os_log_error(TL_LOG, "Failed to wrap unlock key: %@", error.get()); return errSecParam; } @@ -400,6 +429,7 @@ OSStatus TokenLoginCreateLoginData(CFStringRef tokenId, CFDataRef pubKeyHash, CF OSStatus TokenLoginStoreUnlockData(CFDictionaryRef context, CFDictionaryRef loginData) { + os_log(TL_LOG, "Storing unlock data"); CFRef error; CFRef data = CFPropertyListCreateData(kCFAllocatorDefault, @@ -408,18 +438,24 @@ OSStatus TokenLoginStoreUnlockData(CFDictionaryRef context, CFDictionaryRef logi 0, error.take()); if (!data) { - secdebug("TokenLogin", "Failed to create unlock data: %@", error.get()); + os_log_error(TL_LOG, "Failed to create unlock data: %@", error.get()); return errSecInternal; } CFRef pubKeyHashHex = cfDataToHex(getPubKeyHash(context)); - CFPreferencesSetValue(pubKeyHashHex, data, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + os_log(TL_LOG, "Pubkeyhash %@", pubKeyHashHex.get()); + + CFPreferencesSetValue(pubKeyHashHex, data, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + os_log(TL_LOG, "Pubkeyhash %@", pubKeyHashHex.get()); + CFPreferencesSynchronize(kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); CFRef storedData = (CFDataRef)CFPreferencesCopyValue(pubKeyHashHex, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + os_log(TL_LOG, "Stored data %@", storedData.get()); if (!storedData || !CFEqual(storedData, data)) { - secinfo("TokenLogin", "Failed to write token login plist"); + os_log_error(TL_LOG, "Failed to write token login plist"); return errSecIO; } + os_log(TL_LOG, "Original data %@. Everything is OK", data.get()); return errSecSuccess; } @@ -432,7 +468,7 @@ OSStatus TokenLoginDeleteUnlockData(CFDataRef pubKeyHash) CFRef storedData = (CFDataRef)CFPreferencesCopyValue(pubKeyHashHex, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); if (storedData) { - secinfo("TokenLogin", "Failed to remove unlock data"); + os_log_error(TL_LOG, "Failed to remove unlock data"); return errSecIO; } @@ -442,7 +478,7 @@ OSStatus TokenLoginDeleteUnlockData(CFDataRef pubKeyHash) OSStatus TokenLoginGetScBlob(CFDataRef pubKeyHashWrap, CFStringRef tokenId, CFStringRef password, CFDataRef *scBlob) { if (scBlob == NULL || password == NULL || pubKeyHashWrap == NULL || tokenId == NULL) { - secinfo("TokenLogin", "TokenLoginGetScBlob wrong params"); + os_log_error(TL_LOG, "TokenLoginGetScBlob wrong params"); return errSecParam; } @@ -454,19 +490,19 @@ OSStatus TokenLoginGetScBlob(CFDataRef pubKeyHashWrap, CFStringRef tokenId, CFSt CFRef privKey; OSStatus retval = privKeyForPubKeyHash(ctx, privKey.take(), NULL); if (retval != errSecSuccess) { - secinfo("TokenLogin", "TokenLoginGetScBlob failed to get private key for public key hash: %d", (int) retval); + os_log_error(TL_LOG, "TokenLoginGetScBlob failed to get private key for public key hash: %d", (int) retval); return retval; } CFRef pubKey = SecKeyCopyPublicKey(privKey); if (!pubKey) { - secinfo("TokenLogin", "TokenLoginGetScBlob no pubkey"); + os_log_error(TL_LOG, "TokenLoginGetScBlob no pubkey"); return errSecInternal; } CFRef attributes = SecKeyCopyAttributes(pubKey); if (!attributes) { - secinfo("TokenLogin", "TokenLoginGetScBlob no attributes"); + os_log_error(TL_LOG, "TokenLoginGetScBlob no attributes"); return errSecInternal; } @@ -477,25 +513,25 @@ OSStatus TokenLoginGetScBlob(CFDataRef pubKeyHashWrap, CFStringRef tokenId, CFSt else if (CFEqual(type, kSecAttrKeyTypeEC)) mode = AKS_SMARTCARD_MODE_ECDH; else { - secinfo("TokenLogin", "TokenLoginGetScBlob bad type"); + os_log_error(TL_LOG, "TokenLoginGetScBlob bad type"); return errSecNotAvailable; } CFRef publicBytes = SecKeyCopyExternalRepresentation(pubKey, NULL); if (!publicBytes) { - secinfo("TokenLogin", "TokenLoginGetScBlob cannot get public bytes"); + os_log_error(TL_LOG, "TokenLoginGetScBlob cannot get public bytes"); return retval; } CFIndex maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(password), kCFStringEncodingUTF8) + 1; char* buf = (char*)malloc(maxLength); if (buf == NULL) { - secinfo("TokenLogin", "TokenLoginGetScBlob no mem for buffer"); + os_log_error(TL_LOG, "TokenLoginGetScBlob no mem for buffer"); return retval; } if (CFStringGetCString(password, buf, maxLength, kCFStringEncodingUTF8) == FALSE) { - secinfo("TokenLogin", "TokenLoginGetScBlob no pwd cstr"); + os_log_error(TL_LOG, "TokenLoginGetScBlob no pwd cstr"); free(buf); return retval; } @@ -505,7 +541,7 @@ OSStatus TokenLoginGetScBlob(CFDataRef pubKeyHashWrap, CFStringRef tokenId, CFSt aks_smartcard_unregister(session_keybag_handle); // just to be sure no previous registration exist kern_return_t aks_retval = aks_smartcard_register(session_keybag_handle, (uint8_t *)buf, strlen(buf), mode, (uint8_t *)CFDataGetBytePtr(publicBytes), (size_t)CFDataGetLength(publicBytes), &sc_blob, &sc_len); free(buf); - secinfo("TokenLogin", "TokenLoginGetScBlob register result %d", aks_retval); + os_log_debug(TL_LOG, "TokenLoginGetScBlob register result %d", aks_retval); if (sc_blob) { *scBlob = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)sc_blob, (CFIndex)sc_len); @@ -522,7 +558,7 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa CFDataRef scBlob = (CFDataRef)CFDictionaryGetValue(loginData, kSecClassKey); if (scBlob == NULL) { - secinfo("TokenLogin", "Failed to get scblob"); + os_log_error(TL_LOG, "Failed to get scblob"); return errSecInternal; } @@ -531,19 +567,19 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa CFRef LAContext; OSStatus retval = privKeyForPubKeyHash(context, privKey.take(), LAContext.take()); if (retval != errSecSuccess) { - secinfo("TokenLogin", "Failed to get private key for public key hash: %d", (int) retval); + os_log_error(TL_LOG, "Failed to get private key for public key hash: %d", (int) retval); return retval; } CFRef pubKey = SecKeyCopyPublicKey(privKey); if (!pubKey) { - secinfo("TokenLogin", "Failed to get pubkey"); + os_log_error(TL_LOG, "Failed to get pubkey"); return retval; } CFRef attributes = SecKeyCopyAttributes(pubKey); if (!attributes) { - secinfo("TokenLogin", "TokenLoginUnlockKeybag no attributes"); + os_log_error(TL_LOG, "TokenLoginUnlockKeybag no attributes"); return errSecInternal; } @@ -554,7 +590,7 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa else if (CFEqual(type, kSecAttrKeyTypeEC)) mode = AKS_SMARTCARD_MODE_ECDH; else { - secinfo("TokenLogin", "TokenLoginUnlockKeybag bad type"); + os_log_error(TL_LOG, "TokenLoginUnlockKeybag bad type"); return errSecNotAvailable; } @@ -562,7 +598,7 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa size_t scChallengeLen = 0; int res = aks_smartcard_request_unlock(session_keybag_handle, (uint8_t *)CFDataGetBytePtr(scBlob), (size_t)CFDataGetLength(scBlob), &scChallenge, &scChallengeLen); if (res != 0) { - secinfo("TokenLogin", "TokenLoginUnlockKeybag cannot request unlock: %x", res); + os_log_error(TL_LOG, "TokenLoginUnlockKeybag cannot request unlock: %x", res); return errSecInternal; } const void *scUsk = NULL; @@ -571,7 +607,7 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa if (res != 0 || scUsk == NULL) { free(scChallenge); - secinfo("TokenLogin", "TokenLoginUnlockKeybag cannot get usk: %x", res); + os_log_error(TL_LOG, "TokenLoginUnlockKeybag cannot get usk: %x", res); return errSecInternal; } @@ -582,13 +618,13 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa res = aks_smartcard_get_ec_pub(scChallenge, scChallengeLen, &ecPub, &ecPubLen); if (res != 0 || ecPub == NULL) { free(scChallenge); - secinfo("TokenLogin", "TokenLoginUnlockKeybag cannot get ecpub: %x", res); + os_log_error(TL_LOG, "TokenLoginUnlockKeybag cannot get ecpub: %x", res); return errSecInternal; } wrappedUsk = CFDataCreateMutable(kCFAllocatorDefault, ecPubLen + scUskLen); if (!wrappedUsk) { free(scChallenge); - secinfo("TokenLogin", "TokenLoginUnlockKeybag no mem for ecpubusk"); + os_log_error(TL_LOG, "TokenLoginUnlockKeybag no mem for ecpubusk"); return errSecInternal; } CFDataAppendBytes((CFMutableDataRef)wrappedUsk.get(), (const UInt8 *)ecPub, (CFIndex)ecPubLen); @@ -603,7 +639,7 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa (CFDataRef)wrappedUsk.get(), error.take()); if (!unwrappedUsk) { - secinfo("TokenLogin", "TokenLoginUnlockKeybag failed to unwrap blob: %@", error.get()); + os_log_error(TL_LOG, "TokenLoginUnlockKeybag failed to unwrap blob: %@", error.get()); return errSecInternal; } @@ -618,6 +654,8 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa CFDictionarySetValue(newDict, kSecClassKey, newBlobData.get()); TokenLoginStoreUnlockData(context, newDict); } - } + } else { + os_log_error(TL_LOG, "TokenLoginUnlockKeybag no new scblob received: %d", res); + } return res; } diff --git a/OSX/libsecurity_keychain/lib/Trust.cpp b/OSX/libsecurity_keychain/lib/Trust.cpp index a10e0528..ae9d4ee3 100644 --- a/OSX/libsecurity_keychain/lib/Trust.cpp +++ b/OSX/libsecurity_keychain/lib/Trust.cpp @@ -82,8 +82,8 @@ TrustKeychains::TrustKeychains() : { if (GetServerMode()) // in server mode? Don't go through StorageManager to make a keychain { - mRootStoreDL = new DL(gGuidAppleFileDL), - mRootStoreDb = new Db(*mRootStoreDL, SYSTEM_ROOT_STORE_PATH), + mRootStoreDL = new DL(gGuidAppleFileDL); + mRootStoreDb = new Db(*mRootStoreDL, SYSTEM_ROOT_STORE_PATH); mRootStore = new Keychain(*mRootStoreDb); } else diff --git a/OSX/libsecurity_keychain/lib/TrustAdditions.cpp b/OSX/libsecurity_keychain/lib/TrustAdditions.cpp index b8163183..4465256b 100644 --- a/OSX/libsecurity_keychain/lib/TrustAdditions.cpp +++ b/OSX/libsecurity_keychain/lib/TrustAdditions.cpp @@ -416,7 +416,6 @@ static SecCertificateRef _rootCertificateWithSubjectOfCertificate(SecCertificate SecKeyRef keyRef = NULL; SecCertificateRef resultCert = NULL; // note: Sec* APIs are not re-entrant due to the API lock - // status = SecCertificateCopyPublicKey(certificate, &keyRef); BEGIN_SECAPI_INTERNAL_CALL keyRef = Certificate::required(certificate)->publicKey()->handle(); END_SECAPI_INTERNAL_CALL diff --git a/OSX/libsecurity_keychain/regressions/kc-15-key-update-valueref.c b/OSX/libsecurity_keychain/regressions/kc-15-key-update-valueref.c index 4bd7779e..68954040 100644 --- a/OSX/libsecurity_keychain/regressions/kc-15-key-update-valueref.c +++ b/OSX/libsecurity_keychain/regressions/kc-15-key-update-valueref.c @@ -78,9 +78,9 @@ static void PrintCFStringWithFormat(const char *formatStr, CFStringRef inStr) } } -const CFStringRef gPrefix = CFSTR("Test Key"); -const CFStringRef gLabel = CFSTR("Test AES Encryption Key"); -const CFStringRef gUUID = CFSTR("550e8400-e29b-41d4-a716-446655441234"); +const CFStringRef g15Prefix = CFSTR("Test Key"); +const CFStringRef g15Label = CFSTR("Test AES Encryption Key"); +const CFStringRef g15UUID = CFSTR("550e8400-e29b-41d4-a716-446655441234"); // CreateSymmetricKey will create a new AES-128 symmetric encryption key // with the provided label, application label, and application tag. @@ -115,7 +115,7 @@ static int CreateSymmetricKey( // note: the access descriptor should be the same string as will be used for the item's label, // since it's the string that is displayed by the access confirmation dialog to describe the item. SecAccessRef access = NULL; - status = SecAccessCreate(gLabel, NULL, &access); + status = SecAccessCreate(g15Label, NULL, &access); // create a dictionary of parameters describing the key we want to create CFMutableDictionaryRef params = CFDictionaryCreateMutable(NULL, 0, @@ -180,10 +180,10 @@ static int TestUpdateItems(SecKeychainRef keychain) // first, create a symmetric key CFGregorianDate curGDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), NULL); CFStringRef curDateLabel = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%4d-%02d-%02d)"), - gPrefix, (int) (curGDate.year), (int) (curGDate.month), (int) (curGDate.day)); + g15Prefix, (int) (curGDate.year), (int) (curGDate.month), (int) (curGDate.day)); CFStringRef curAppTag = CFSTR("SecItemUpdate"); - status = CreateSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, noErr); + status = CreateSymmetricKey(keychain, curDateLabel, g15UUID, curAppTag, noErr); CFReleaseNull(curDateLabel); if (status && status != errSecDuplicateItem) ++result; diff --git a/OSX/libsecurity_keychain/regressions/kc-18-find-combined.c b/OSX/libsecurity_keychain/regressions/kc-18-find-combined.c index ca92be7e..b85f36ea 100644 --- a/OSX/libsecurity_keychain/regressions/kc-18-find-combined.c +++ b/OSX/libsecurity_keychain/regressions/kc-18-find-combined.c @@ -2507,9 +2507,9 @@ static int FindMailPassword(SecKeychainRef keychain, -const CFStringRef gPrefix = CFSTR("Test Key"); -const CFStringRef gLabel = CFSTR("Test AES Encryption Key"); -const CFStringRef gUUID = CFSTR("550e8400-e29b-41d4-a716-446655441234"); +const CFStringRef g18Prefix = CFSTR("Test Key"); +const CFStringRef g18Label = CFSTR("Test AES Encryption Key"); +const CFStringRef g18UUID = CFSTR("550e8400-e29b-41d4-a716-446655441234"); // CreateSymmetricKey will create a new AES-128 symmetric encryption key // with the provided label, application label, and application tag. @@ -2536,7 +2536,7 @@ static int CreateSymmetricKey( // note: the access descriptor should be the same string as will be used for the item's label, // since it's the string that is displayed by the access confirmation dialog to describe the item. SecAccessRef access = NULL; - status = SecAccessCreate(gLabel, NULL, &access); + status = SecAccessCreate(g18Label, NULL, &access); // create a dictionary of parameters describing the key we want to create CFMutableDictionaryRef params = CFDictionaryCreateMutable(NULL, 0, @@ -3055,12 +3055,12 @@ static int TestSymmetricKeyLookup(SecKeychainRef keychain) int result = 0; // look up our symmetric key by label and UUID (it might not exist yet) - if (FindSymmetricKey(keychain, gLabel, gUUID, NULL, errSecItemNotFound) != errSecSuccess) { + if (FindSymmetricKey(keychain, g18Label, g18UUID, NULL, errSecItemNotFound) != errSecSuccess) { // create test key (unique by UUID only) - if (CreateSymmetricKey(keychain, gLabel, gUUID, NULL, errSecSuccess) != errSecSuccess) + if (CreateSymmetricKey(keychain, g18Label, g18UUID, NULL, errSecSuccess) != errSecSuccess) ++result; // look it up again (it should exist now!) - if (FindSymmetricKey(keychain, gLabel, gUUID, NULL, errSecSuccess) != errSecSuccess) + if (FindSymmetricKey(keychain, g18Label, g18UUID, NULL, errSecSuccess) != errSecSuccess) ++result; } @@ -3068,7 +3068,7 @@ static int TestSymmetricKeyLookup(SecKeychainRef keychain) // (so we can make sure on a daily basis that SecKeyGenerateSymmetric is still working) CFGregorianDate curGDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), NULL); CFStringRef curDateLabel = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%4d-%02d-%02d)"), - gPrefix, (int32_t) curGDate.year, (int8_t) curGDate.month, (int8_t) curGDate.day); + g18Prefix, (int32_t) curGDate.year, (int8_t) curGDate.month, (int8_t) curGDate.day); // //%%% FIXME Creating a symmetric key with attributes that would duplicate an existing @@ -3078,17 +3078,17 @@ static int TestSymmetricKeyLookup(SecKeychainRef keychain) CFStringRef curAppTag = CFSTR("SecItemFind"); // look up our date-based symmetric key by label, UUID, and tag (it might not exist yet) - if (FindSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, errSecItemNotFound) != errSecSuccess) { + if (FindSymmetricKey(keychain, curDateLabel, g18UUID, curAppTag, errSecItemNotFound) != errSecSuccess) { // create test key (unique by combination of UUID and application tag) - if (CreateSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, errSecSuccess) != errSecSuccess) + if (CreateSymmetricKey(keychain, curDateLabel, g18UUID, curAppTag, errSecSuccess) != errSecSuccess) ++result; // look it up again (it should exist now!) - if (FindSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, errSecSuccess) != errSecSuccess) + if (FindSymmetricKey(keychain, curDateLabel, g18UUID, curAppTag, errSecSuccess) != errSecSuccess) ++result; } // test handling of duplicate symmetric key items () - if (CreateSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, errSecDuplicateItem) != errSecDuplicateItem) + if (CreateSymmetricKey(keychain, curDateLabel, g18UUID, curAppTag, errSecDuplicateItem) != errSecDuplicateItem) ++result; CFRelease(curDateLabel); @@ -3270,11 +3270,11 @@ static int TestDeleteItems(SecKeychainRef keychain) ++result; // delete our test symmetric keys (no partial string matching for key items! need an ER Radar...) - if (FindAndDeleteItemsByName(keychain, gLabel, NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr)) + if (FindAndDeleteItemsByName(keychain, g18Label, NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr)) ++result; CFGregorianDate curGDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), NULL); CFStringRef curDateLabel = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%4d-%02d-%02d)"), - gPrefix, (int32_t) curGDate.year, (int8_t) curGDate.month, (int8_t) curGDate.day); + g18Prefix, (int32_t) curGDate.year, (int8_t) curGDate.month, (int8_t) curGDate.day); if (FindAndDeleteItemsByName(keychain, curDateLabel, NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr)) ++result; CFRelease(curDateLabel); diff --git a/OSX/libsecurity_keychain/regressions/kc-20-item-find-stress.c b/OSX/libsecurity_keychain/regressions/kc-20-item-find-stress.c index 937449b9..a99aab30 100644 --- a/OSX/libsecurity_keychain/regressions/kc-20-item-find-stress.c +++ b/OSX/libsecurity_keychain/regressions/kc-20-item-find-stress.c @@ -55,7 +55,7 @@ static void tests() { CFMutableDictionaryRef query = createQueryCustomItemDictionaryWithService(kc, kSecClassInternetPassword, CFSTR("test_service"), CFSTR("test_service")); CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne); - ok_status(SecItemCopyMatching(query, (CFTypeRef*) &blockItem), "%s: SecItemCopyMatching (%d)", testName, iteration); + ok_status(SecItemCopyMatching(query, (CFTypeRef*) &blockItem), "%s: SecItemCopyMatching", testName); CFReleaseNull(query); CFReleaseNull(blockItem); diff --git a/OSX/libsecurity_keychain/regressions/kc-28-p12-import.m b/OSX/libsecurity_keychain/regressions/kc-28-p12-import.m index df90e70f..77641dda 100644 --- a/OSX/libsecurity_keychain/regressions/kc-28-p12-import.m +++ b/OSX/libsecurity_keychain/regressions/kc-28-p12-import.m @@ -53,6 +53,138 @@ // Turn off deprecated API warnings //#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +unsigned char test_import_p12[] = { + 0x30, 0x82, 0x09, 0xbf, 0x02, 0x01, 0x03, 0x30, 0x82, 0x09, 0x86, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x07, 0x01, 0xa0, 0x82, 0x09, 0x77, 0x04, 0x82, 0x09, 0x73, 0x30, 0x82, 0x09, 0x6f, 0x30, 0x82, 0x03, 0xff, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x03, 0xec, 0x02, 0x01, 0x00, + 0x30, 0x82, 0x03, 0xe5, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xcb, 0xa2, 0x8c, 0x60, 0xc2, 0x36, 0x55, + 0x05, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03, 0xb8, 0x57, 0x1d, 0x4c, 0x1f, 0xc7, 0x4c, 0x00, 0x82, 0xa3, 0xc9, 0x6f, + 0x2e, 0x00, 0x03, 0x1b, 0x55, 0xaa, 0xe5, 0x89, 0x58, 0x18, 0x71, 0xb8, 0xff, 0x40, 0x13, 0xd5, 0xac, 0x7f, 0xf1, 0x48, + 0xb2, 0x7e, 0x6e, 0xeb, 0x6e, 0xde, 0xe8, 0x35, 0x22, 0xa5, 0x45, 0x5a, 0xa6, 0x2e, 0xed, 0x0d, 0xe0, 0x8f, 0x2f, 0x60, + 0x5c, 0xd8, 0x49, 0x89, 0x26, 0x42, 0xd6, 0xe0, 0x24, 0x1c, 0x59, 0x9c, 0xe0, 0xbf, 0x98, 0x0c, 0xc3, 0x81, 0x20, 0x47, + 0x03, 0x03, 0xe2, 0x73, 0x90, 0x13, 0x6e, 0x96, 0x31, 0x68, 0xb7, 0x8f, 0xaa, 0x25, 0x4b, 0x27, 0x95, 0x3f, 0xef, 0xa3, + 0x2b, 0x96, 0x10, 0x85, 0xf3, 0x49, 0x3c, 0x6f, 0x9a, 0x20, 0x02, 0x17, 0x42, 0xe9, 0x9c, 0x5e, 0x5d, 0x4b, 0x3c, 0x88, + 0x65, 0xf5, 0x67, 0x61, 0x3e, 0xa6, 0x1a, 0x0f, 0x5b, 0x1e, 0x35, 0x18, 0x4e, 0xf3, 0x98, 0x93, 0x7e, 0x76, 0x77, 0x31, + 0x3b, 0x00, 0x78, 0x8c, 0x50, 0x28, 0x76, 0xca, 0xc8, 0x39, 0xc5, 0xf5, 0x79, 0x23, 0x4a, 0xea, 0x9a, 0xf0, 0xb5, 0xb6, + 0x50, 0x8d, 0x16, 0xd9, 0x39, 0x74, 0x36, 0x1d, 0x26, 0xcb, 0xbf, 0xb7, 0x72, 0x5e, 0x77, 0xf5, 0xb8, 0x35, 0xfc, 0x66, + 0x4d, 0xdc, 0xd6, 0x20, 0x50, 0x70, 0xc6, 0xf7, 0x13, 0x55, 0xb1, 0x97, 0x7e, 0x1d, 0x6a, 0x7d, 0x73, 0xc2, 0x71, 0x49, + 0xd1, 0x15, 0xe7, 0x30, 0xa7, 0x52, 0x1f, 0x24, 0xe8, 0x7b, 0xd7, 0x81, 0x53, 0x27, 0x94, 0xd0, 0x31, 0xe5, 0x11, 0xe4, + 0x90, 0x8a, 0x02, 0x46, 0x70, 0x82, 0xe7, 0xc4, 0xfe, 0xb5, 0xed, 0xb0, 0x1b, 0xcb, 0xa2, 0x23, 0x5c, 0xd2, 0x95, 0xe6, + 0x2c, 0x5f, 0x2d, 0x07, 0xb1, 0xd8, 0xe8, 0xa0, 0x39, 0xe7, 0xdd, 0x2e, 0x36, 0xac, 0x38, 0xfc, 0x65, 0x99, 0x2c, 0xda, + 0x3d, 0x26, 0x5d, 0x1e, 0x2f, 0xbc, 0x31, 0x36, 0x3e, 0x87, 0x55, 0x5f, 0x40, 0xf1, 0x77, 0x7a, 0x15, 0xa2, 0xc3, 0xe4, + 0x21, 0xc0, 0xe1, 0x11, 0x15, 0x31, 0xf4, 0x7a, 0x51, 0xc3, 0x78, 0x70, 0xfc, 0x3b, 0xed, 0x04, 0x7f, 0x5c, 0xaf, 0x22, + 0x37, 0x1c, 0x80, 0xb6, 0x7b, 0xdf, 0x11, 0x90, 0x52, 0xc1, 0x0d, 0xfb, 0xaa, 0xd0, 0x43, 0x47, 0xe9, 0xdb, 0x31, 0xb7, + 0xfc, 0x35, 0xbf, 0xce, 0x00, 0x15, 0x0d, 0x51, 0xb1, 0x78, 0x99, 0x55, 0x91, 0x1f, 0xf1, 0x4c, 0x36, 0xfa, 0xc1, 0xa0, + 0xce, 0x86, 0xc9, 0x79, 0x60, 0x07, 0x58, 0xa7, 0xe5, 0x28, 0x28, 0x84, 0x92, 0x03, 0x2c, 0x43, 0xda, 0x69, 0xce, 0x75, + 0x25, 0x01, 0x51, 0x37, 0xd4, 0xfd, 0xa2, 0xc4, 0x09, 0xfb, 0xa0, 0xf5, 0x1f, 0x23, 0x7b, 0xd6, 0x63, 0xd1, 0xb5, 0x5b, + 0xc5, 0xd9, 0xbc, 0xe7, 0xd4, 0x5e, 0x8b, 0x62, 0xee, 0xdb, 0xb7, 0x1e, 0xd2, 0x8b, 0x6e, 0xe4, 0x8c, 0xfd, 0x11, 0x25, + 0xda, 0xac, 0x2a, 0x7a, 0x9a, 0xad, 0x6c, 0x29, 0xe1, 0x1c, 0x68, 0x4f, 0xb3, 0x99, 0x06, 0xb4, 0x72, 0x2a, 0x5a, 0x70, + 0xd6, 0xf6, 0x7c, 0x22, 0x0f, 0x85, 0xf1, 0xc4, 0x30, 0x9f, 0x32, 0x53, 0xa1, 0xb2, 0x1a, 0x41, 0x01, 0xa2, 0x92, 0x58, + 0xa2, 0x27, 0xe8, 0x09, 0xed, 0x75, 0x84, 0x41, 0xcd, 0x19, 0x46, 0x47, 0x86, 0x7d, 0xa0, 0x49, 0xc4, 0x72, 0x94, 0x9f, + 0x43, 0xf2, 0x09, 0x3a, 0x59, 0x56, 0x7c, 0x3b, 0x34, 0x79, 0x1b, 0x58, 0x82, 0xc7, 0x64, 0x19, 0x7c, 0x32, 0x7b, 0x42, + 0x66, 0x9f, 0x32, 0xef, 0x48, 0xb4, 0xf7, 0xd0, 0x74, 0x1f, 0x1c, 0xbe, 0xd4, 0x7a, 0x2a, 0x02, 0xb2, 0x3d, 0x47, 0x15, + 0x40, 0xa8, 0xd5, 0x57, 0xc8, 0xe7, 0x7d, 0x8d, 0xa6, 0xea, 0xe5, 0x21, 0x6a, 0xbe, 0x39, 0x8c, 0xfd, 0x78, 0x26, 0xaf, + 0x31, 0x93, 0x0f, 0x94, 0x07, 0x87, 0x6c, 0xa8, 0x56, 0xd8, 0xc6, 0x79, 0xcf, 0x1d, 0x36, 0xee, 0xab, 0x33, 0x5b, 0x63, + 0xe8, 0x34, 0x00, 0x0c, 0x95, 0x48, 0x34, 0xac, 0xe2, 0xda, 0x61, 0x7a, 0x97, 0x3e, 0x41, 0xe4, 0xb7, 0x30, 0xb0, 0xb3, + 0x96, 0xed, 0x91, 0xb8, 0x5b, 0x20, 0x30, 0xfa, 0xf0, 0xfa, 0xc7, 0xc2, 0x97, 0x14, 0x9b, 0x81, 0xa9, 0x70, 0x8a, 0x10, + 0xf1, 0x75, 0xe4, 0xec, 0x54, 0x3e, 0xd9, 0xa8, 0x94, 0xcd, 0x3a, 0x82, 0xf7, 0xe3, 0xb8, 0x75, 0xd7, 0x49, 0x6c, 0x80, + 0x97, 0xd8, 0xdf, 0x56, 0x66, 0x93, 0xe6, 0xef, 0xa3, 0xc3, 0xd6, 0x34, 0xb7, 0x6f, 0x9b, 0x51, 0xaa, 0x7c, 0x1e, 0x16, + 0x8f, 0x21, 0x8a, 0x0a, 0x9f, 0x0e, 0xbe, 0x6b, 0x96, 0x8b, 0x95, 0x95, 0x5d, 0x11, 0x39, 0x15, 0x8c, 0xca, 0x9d, 0xec, + 0x26, 0x39, 0x49, 0x1e, 0xf6, 0x16, 0x09, 0x36, 0x95, 0xae, 0xa0, 0x55, 0xbf, 0x94, 0xf2, 0x6f, 0x1b, 0x74, 0x93, 0x97, + 0x6d, 0xd8, 0x00, 0x0c, 0xf0, 0x9e, 0x24, 0xb9, 0xfe, 0x04, 0xfa, 0x30, 0x63, 0x90, 0x28, 0xcb, 0x0d, 0x8e, 0xe8, 0xf0, + 0x7f, 0x9a, 0x69, 0x54, 0xf2, 0xbc, 0x9f, 0x24, 0x0b, 0xd1, 0xda, 0x2f, 0x22, 0x81, 0x22, 0x31, 0x03, 0xc2, 0x60, 0x41, + 0x2e, 0xe0, 0xc6, 0x52, 0x7b, 0x5a, 0x35, 0xbc, 0x00, 0xfd, 0x71, 0x00, 0x19, 0xd3, 0xa4, 0xa8, 0x5b, 0xbc, 0xfc, 0xae, + 0x24, 0x10, 0xb4, 0x21, 0x8c, 0x3c, 0x15, 0xad, 0x2d, 0x1e, 0x33, 0x09, 0x58, 0x93, 0xb4, 0x29, 0x3a, 0xbc, 0x6f, 0x7d, + 0x51, 0x3b, 0x5b, 0x97, 0xfe, 0x67, 0xe1, 0x9e, 0xff, 0x6b, 0xdc, 0xf2, 0xb0, 0x6f, 0xa1, 0x4e, 0x4b, 0xf2, 0xdf, 0xd6, + 0xa4, 0xec, 0x8d, 0x19, 0x6d, 0x30, 0x67, 0xde, 0x04, 0x5e, 0xaf, 0xd7, 0xd4, 0x42, 0xf8, 0xbc, 0xca, 0xfc, 0x49, 0xc0, + 0xe7, 0xcd, 0xfc, 0xab, 0xca, 0x3f, 0x67, 0xff, 0xfb, 0x41, 0xc0, 0xe4, 0xe8, 0x0c, 0xe8, 0x2e, 0xca, 0x43, 0xfb, 0xec, + 0xe0, 0xeb, 0xea, 0x30, 0x14, 0xca, 0x30, 0x8d, 0x49, 0xaa, 0x99, 0x71, 0xcb, 0x85, 0xa4, 0x68, 0xda, 0xd1, 0xbe, 0xa9, + 0xc6, 0xee, 0x26, 0xdf, 0x3f, 0xde, 0x39, 0x29, 0x6c, 0x45, 0x9e, 0x41, 0x88, 0x63, 0xd8, 0x31, 0x47, 0x8e, 0xdc, 0xc8, + 0xe4, 0x28, 0x25, 0x75, 0x11, 0x99, 0xdd, 0x28, 0x25, 0xa7, 0x5e, 0xac, 0x7f, 0x0c, 0xb5, 0x2b, 0x62, 0x9d, 0xe0, 0xda, + 0xe3, 0xc2, 0xd8, 0x8d, 0xc6, 0x25, 0x5f, 0x08, 0x6e, 0xfc, 0xcd, 0xae, 0x4c, 0x99, 0x41, 0xc4, 0x75, 0x3e, 0x5e, 0x51, + 0xa1, 0x76, 0x47, 0x93, 0x4a, 0x83, 0x51, 0x91, 0xf3, 0x92, 0xd0, 0x29, 0xa6, 0x44, 0x3c, 0x2a, 0x91, 0x3f, 0x01, 0x75, + 0xeb, 0x6f, 0xf3, 0x3c, 0x04, 0xd3, 0x74, 0x7a, 0xfc, 0x7a, 0x39, 0x70, 0xc8, 0x3a, 0x89, 0x93, 0xbd, 0xfd, 0xd7, 0x41, + 0x2c, 0xb0, 0xd3, 0xef, 0xd0, 0xd5, 0x75, 0x24, 0xb1, 0x0e, 0x3d, 0x89, 0x8e, 0xde, 0xa7, 0x40, 0x80, 0xd2, 0x05, 0xe5, + 0x18, 0xa2, 0xf3, 0x30, 0x22, 0x56, 0x0b, 0xbc, 0x05, 0xb0, 0x48, 0x9a, 0x42, 0xb7, 0xe1, 0x32, 0xba, 0x52, 0x99, 0x22, + 0xf6, 0x30, 0x82, 0x05, 0x68, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0x59, + 0x04, 0x82, 0x05, 0x55, 0x30, 0x82, 0x05, 0x51, 0x30, 0x82, 0x05, 0x4d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, 0xea, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x8e, 0x7e, 0x90, 0x94, 0xaf, 0x09, 0xc5, 0xbc, 0x02, + 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0x0c, 0x7c, 0x7f, 0x58, 0x8b, 0x41, 0x9a, 0xb8, 0x70, 0xbf, 0x6c, 0x4c, 0xb8, + 0x7d, 0x72, 0xa5, 0x50, 0xe6, 0xc4, 0xaf, 0x74, 0x0e, 0x88, 0xbf, 0x83, 0x51, 0xbc, 0xe1, 0x66, 0x8a, 0x9f, 0x42, 0x11, + 0x2b, 0x3d, 0x8c, 0x10, 0xa3, 0xc2, 0xdf, 0xb9, 0x36, 0x74, 0xc1, 0x18, 0x23, 0x1e, 0x9a, 0xbf, 0x8d, 0x0a, 0x4b, 0x63, + 0xd5, 0x20, 0x1b, 0xae, 0xb0, 0x64, 0xfc, 0xe1, 0x5c, 0xe7, 0xde, 0xa3, 0x6f, 0x8e, 0xe3, 0xc9, 0x8d, 0x18, 0x63, 0x7f, + 0x26, 0x4a, 0x3d, 0x41, 0x76, 0xa6, 0xaa, 0x3f, 0x27, 0x75, 0xec, 0x2f, 0x78, 0xd2, 0x40, 0x28, 0xe7, 0xf5, 0xee, 0x61, + 0x6d, 0x49, 0xe0, 0x64, 0x33, 0xc9, 0x9e, 0xf6, 0xda, 0x86, 0x3a, 0xad, 0x47, 0x13, 0xe2, 0x8a, 0x0b, 0x98, 0xe7, 0x73, + 0xea, 0x08, 0x59, 0xfe, 0x74, 0x6f, 0x10, 0x7d, 0xbc, 0x0b, 0xb9, 0xcf, 0xe7, 0xe7, 0x28, 0xe8, 0xfe, 0x20, 0x8a, 0x98, + 0x40, 0x00, 0x52, 0xa0, 0x0c, 0x5c, 0xfa, 0x48, 0x5b, 0xf4, 0x3c, 0x76, 0x5d, 0xf4, 0x33, 0x53, 0xd4, 0x51, 0x43, 0x47, + 0x29, 0xda, 0xff, 0xbd, 0xfe, 0x71, 0x5b, 0x50, 0xa1, 0xa5, 0x25, 0xe9, 0xcc, 0x68, 0x74, 0x9f, 0x7f, 0x39, 0x65, 0x5e, + 0xb9, 0x71, 0x8f, 0x25, 0x68, 0xe6, 0x71, 0x06, 0x10, 0xa2, 0xfb, 0x08, 0x54, 0x21, 0xca, 0x28, 0xfc, 0xf1, 0x89, 0xb9, + 0x29, 0x11, 0x67, 0x00, 0x19, 0xdd, 0x00, 0xd8, 0x48, 0x89, 0x46, 0x0d, 0x39, 0x0c, 0x7e, 0x94, 0x02, 0x80, 0x37, 0xa0, + 0x01, 0x45, 0x25, 0xbd, 0x8b, 0x44, 0xcc, 0xdf, 0x43, 0xa1, 0x1d, 0xf5, 0x59, 0x4b, 0x07, 0xe6, 0xab, 0x15, 0x93, 0x3d, + 0xea, 0x7d, 0xd6, 0xaa, 0xb0, 0x97, 0xed, 0x1d, 0x5e, 0xc2, 0xf0, 0xea, 0x1b, 0xc2, 0xcc, 0x88, 0x47, 0x3e, 0xe4, 0x54, + 0xc3, 0x02, 0xac, 0x5e, 0x88, 0xb9, 0x2f, 0x82, 0xd4, 0xd0, 0x5d, 0xb2, 0x2a, 0xee, 0x94, 0x3d, 0xdb, 0x82, 0x93, 0xc6, + 0x69, 0x5f, 0x40, 0x83, 0xf0, 0x07, 0x8d, 0x9f, 0x7f, 0x29, 0x3f, 0x4d, 0x3b, 0x08, 0xd9, 0x29, 0xf5, 0x1c, 0x0f, 0x18, + 0x42, 0x4b, 0xd9, 0x01, 0xda, 0x71, 0x92, 0xa8, 0x32, 0xa7, 0x53, 0x6f, 0xd0, 0x74, 0x4a, 0xee, 0x39, 0x04, 0xf1, 0x2d, + 0xee, 0x50, 0xbe, 0x48, 0xb1, 0x90, 0x21, 0x24, 0x28, 0x40, 0xa9, 0x85, 0xe1, 0x81, 0x77, 0x37, 0xa8, 0x86, 0x15, 0x7d, + 0x16, 0xb2, 0xe7, 0xcc, 0xe0, 0xa2, 0x7e, 0x58, 0xb3, 0xdc, 0xf9, 0x41, 0xae, 0x36, 0xba, 0x55, 0x87, 0x64, 0x01, 0xfd, + 0xc9, 0x0e, 0xa1, 0xfe, 0x55, 0xc3, 0x2a, 0x66, 0xd5, 0x83, 0x39, 0x7e, 0x5a, 0xe8, 0x28, 0x76, 0x36, 0xbb, 0x39, 0xa9, + 0xb7, 0xc6, 0xcf, 0x99, 0x56, 0xe5, 0xbf, 0x4d, 0xb2, 0xa0, 0xac, 0x64, 0x00, 0xc9, 0x42, 0x79, 0x47, 0x46, 0xd7, 0x9c, + 0x4a, 0x33, 0x03, 0x55, 0x07, 0x7f, 0x05, 0x23, 0xe3, 0x51, 0x35, 0xa9, 0x32, 0xe9, 0xa6, 0xf2, 0xe2, 0x42, 0x4d, 0x00, + 0xbb, 0xdb, 0xc3, 0x85, 0x05, 0xcb, 0xe4, 0xb1, 0x0a, 0x03, 0xf4, 0xe5, 0x27, 0x28, 0x12, 0xec, 0x1e, 0xd4, 0xd7, 0x43, + 0xe3, 0x05, 0xc7, 0x92, 0xd2, 0x8e, 0xf7, 0xae, 0x55, 0x1a, 0x50, 0x88, 0x2f, 0x91, 0x05, 0x65, 0x4b, 0xe3, 0xba, 0xc0, + 0x42, 0x86, 0x19, 0x2b, 0x64, 0xfc, 0x46, 0x31, 0x9b, 0xd2, 0x88, 0x32, 0xf8, 0x4d, 0x91, 0xd4, 0xc6, 0x77, 0xcb, 0x29, + 0x00, 0x5e, 0xd2, 0x48, 0x99, 0x0e, 0x3f, 0x2d, 0x4f, 0xdb, 0x9b, 0x05, 0xea, 0xa1, 0x3d, 0x9f, 0x21, 0x83, 0x6f, 0xcf, + 0xe9, 0x1c, 0x65, 0x40, 0x3c, 0x8b, 0x2a, 0x38, 0x8f, 0x1b, 0x5a, 0x3c, 0x73, 0x7a, 0xfc, 0x81, 0x69, 0xb3, 0xff, 0xb6, + 0x25, 0x12, 0x3f, 0xda, 0x50, 0xe7, 0xde, 0xfe, 0xd3, 0x31, 0x2f, 0xb4, 0x99, 0x87, 0xae, 0x17, 0xaf, 0xe4, 0xb8, 0x35, + 0xf7, 0x3c, 0xc0, 0x99, 0x0e, 0x75, 0x72, 0xb6, 0x46, 0xa1, 0x55, 0xef, 0xff, 0x48, 0x3b, 0x5c, 0x85, 0xf7, 0xc3, 0x03, + 0x0a, 0x49, 0x0f, 0x11, 0x48, 0x13, 0x8b, 0x90, 0x73, 0x33, 0xb6, 0x22, 0x35, 0x45, 0x07, 0x80, 0x1a, 0xf9, 0x91, 0x80, + 0x9d, 0x8b, 0xc7, 0x8e, 0xcc, 0x3a, 0x52, 0x93, 0x8f, 0xf6, 0x59, 0x3c, 0x69, 0xf7, 0x52, 0x9a, 0x8d, 0x8e, 0xfe, 0x8a, + 0x41, 0xb0, 0x43, 0x74, 0x04, 0xe8, 0x0e, 0xf5, 0xc1, 0x4c, 0xa3, 0x8d, 0xe3, 0x98, 0x25, 0xf6, 0xd5, 0x0d, 0xa9, 0x2d, + 0xb7, 0x6f, 0x52, 0x22, 0x43, 0x59, 0x30, 0x6d, 0x54, 0xb6, 0xad, 0x73, 0xa1, 0xe8, 0xee, 0x10, 0xbd, 0x55, 0xa4, 0x7f, + 0xc3, 0x1d, 0xad, 0x8e, 0x72, 0xf1, 0x26, 0x6d, 0xa1, 0xaf, 0xda, 0x82, 0x37, 0xa1, 0x6d, 0xfe, 0x78, 0xd1, 0x88, 0x65, + 0x6a, 0xb2, 0x33, 0x23, 0xcd, 0xba, 0xbe, 0x09, 0x66, 0x61, 0x33, 0xdc, 0x69, 0xed, 0x4f, 0xe6, 0xfb, 0x2f, 0x7d, 0xd0, + 0xfd, 0x7a, 0x21, 0x69, 0x2d, 0x1f, 0xd4, 0xc4, 0x93, 0x7c, 0x34, 0x7d, 0x67, 0x2c, 0xe9, 0x2a, 0x9a, 0x53, 0xc2, 0xbf, + 0xf9, 0x06, 0x10, 0xa6, 0xa8, 0x60, 0xe3, 0x01, 0xcb, 0x2b, 0x03, 0xdb, 0xb7, 0x27, 0xe9, 0x86, 0xe8, 0x7d, 0x75, 0xce, + 0x80, 0xdb, 0xaf, 0xe9, 0x7e, 0x75, 0xad, 0xe3, 0xd4, 0xc4, 0xf3, 0x10, 0x89, 0x16, 0xcb, 0xc6, 0x23, 0x5a, 0x58, 0x66, + 0xb6, 0x2a, 0xd7, 0xc9, 0x69, 0xd3, 0x7f, 0xa2, 0x9a, 0x5c, 0x1c, 0xd4, 0xf8, 0xe3, 0xe0, 0x63, 0x01, 0x88, 0x14, 0xb3, + 0x20, 0xe3, 0x22, 0x45, 0x3d, 0xae, 0xaf, 0x0b, 0x55, 0xa1, 0x65, 0xec, 0x16, 0x0b, 0x35, 0x37, 0x6f, 0x12, 0x5f, 0x29, + 0x47, 0xee, 0xdd, 0xbb, 0xcf, 0x9f, 0x87, 0xaf, 0x7d, 0xaa, 0xf4, 0x01, 0x45, 0xea, 0x5f, 0x00, 0x87, 0x1e, 0xeb, 0x2f, + 0x77, 0x2b, 0x92, 0x42, 0x04, 0x45, 0x33, 0xf2, 0xfb, 0x6b, 0xac, 0xca, 0x98, 0x79, 0x56, 0x6f, 0xe7, 0x5b, 0xbd, 0x63, + 0xc7, 0x3a, 0x8c, 0xfd, 0x93, 0xb1, 0x13, 0x4e, 0xc2, 0x05, 0x7f, 0xde, 0x44, 0xa8, 0xb7, 0xc4, 0x9c, 0xba, 0x57, 0x58, + 0x3b, 0xba, 0xb5, 0x74, 0x73, 0x97, 0x20, 0x53, 0x70, 0x70, 0x65, 0xf1, 0x81, 0xea, 0x07, 0xc2, 0xbe, 0x57, 0x71, 0x62, + 0x3b, 0xc0, 0x3c, 0x07, 0x65, 0xf4, 0x22, 0xfb, 0xd3, 0xf9, 0x2d, 0xb3, 0x20, 0xdd, 0x66, 0x51, 0x89, 0x54, 0x57, 0xcd, + 0xd7, 0xc7, 0x1a, 0xd9, 0xfe, 0xe0, 0x13, 0x9d, 0x7d, 0xe7, 0xe3, 0x2f, 0x65, 0x3e, 0xf0, 0xb2, 0xd9, 0x0c, 0x1a, 0xa9, + 0xaa, 0xba, 0x3b, 0x79, 0x86, 0xed, 0x6c, 0xbf, 0x9e, 0x9b, 0xb5, 0x78, 0xd8, 0x9e, 0x2f, 0x95, 0xcc, 0x31, 0xb4, 0x5f, + 0xd3, 0x63, 0xff, 0xb9, 0x62, 0x34, 0xfd, 0x78, 0x1f, 0xac, 0xe7, 0xbd, 0x29, 0x09, 0x2a, 0x1c, 0x94, 0xc5, 0x28, 0x6c, + 0x04, 0x59, 0xeb, 0xd6, 0x7c, 0x0d, 0x45, 0x07, 0xd9, 0xde, 0x89, 0xa1, 0xd8, 0x38, 0x8a, 0x2b, 0x9f, 0xc3, 0xdb, 0x55, + 0x89, 0x90, 0xc6, 0x75, 0xd0, 0x2f, 0x85, 0x9b, 0x0a, 0x5e, 0x04, 0xa1, 0xf9, 0xf7, 0x16, 0x35, 0x9d, 0x97, 0xfe, 0x7c, + 0x4b, 0x27, 0x4c, 0xc3, 0x8a, 0x2a, 0x56, 0x6a, 0x41, 0xe5, 0xd3, 0x82, 0xeb, 0xd2, 0x62, 0x4e, 0x11, 0x1e, 0x4e, 0xae, + 0xa4, 0x79, 0x89, 0x20, 0x82, 0x6e, 0x39, 0x7d, 0x70, 0xf8, 0x17, 0xd6, 0xe3, 0x67, 0x9a, 0x14, 0xd7, 0xc8, 0x80, 0xbe, + 0x62, 0x52, 0xe7, 0x69, 0xab, 0x98, 0xa9, 0x14, 0x98, 0xbd, 0x30, 0xf4, 0xab, 0x2c, 0x22, 0x6b, 0x5f, 0xee, 0x58, 0xf3, + 0x6f, 0x15, 0xea, 0xce, 0xd3, 0x1b, 0x07, 0xfa, 0xe6, 0x4c, 0xeb, 0xeb, 0x30, 0xa6, 0xff, 0x03, 0xc9, 0x75, 0x94, 0xa5, + 0x5b, 0x68, 0xd3, 0x42, 0x85, 0x3f, 0xa4, 0x87, 0xee, 0x3f, 0x14, 0x63, 0x16, 0x52, 0x26, 0x3b, 0x1a, 0xee, 0x48, 0x77, + 0x6e, 0x4a, 0x56, 0x01, 0x53, 0x54, 0x1b, 0xa6, 0xd7, 0x72, 0x98, 0x89, 0xd5, 0xf7, 0x11, 0x3a, 0x86, 0xac, 0x64, 0xe6, + 0x59, 0xba, 0x07, 0xea, 0x23, 0x21, 0x05, 0xd6, 0x14, 0xed, 0x88, 0x2e, 0x96, 0xb3, 0x90, 0xc3, 0xb7, 0xc4, 0x5b, 0x8f, + 0x0e, 0xcd, 0x56, 0xba, 0xb8, 0x4b, 0x7b, 0xfd, 0xd4, 0x7d, 0x0c, 0xcb, 0xe1, 0xff, 0xaf, 0x3e, 0x2a, 0x7c, 0x1a, 0xe5, + 0x66, 0x65, 0x59, 0x42, 0xd7, 0x3b, 0xd2, 0x2e, 0x89, 0x1d, 0x64, 0xc0, 0xbd, 0xec, 0x8c, 0xaa, 0x06, 0xb8, 0x5a, 0x7c, + 0xb8, 0xd0, 0xa5, 0xef, 0x5a, 0xf3, 0x92, 0x4c, 0x2f, 0x60, 0x98, 0x34, 0x73, 0x49, 0x92, 0x7a, 0x5d, 0x7c, 0x2c, 0xcd, + 0x0b, 0xfb, 0x28, 0xd9, 0x3e, 0xfa, 0xbd, 0x76, 0x0f, 0xaa, 0x71, 0xfa, 0x98, 0x36, 0x94, 0x97, 0xaa, 0x97, 0x1f, 0x34, + 0x21, 0x72, 0xc6, 0x19, 0xb4, 0xe3, 0xaa, 0x05, 0x16, 0xda, 0xaa, 0x92, 0x04, 0x49, 0xc7, 0x97, 0x42, 0x58, 0xd0, 0x80, + 0xdc, 0x9e, 0xcf, 0xfa, 0x5f, 0x4b, 0xbc, 0x78, 0xff, 0x95, 0x39, 0x31, 0x4c, 0x30, 0x25, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31, 0x18, 0x1e, 0x16, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5f, + 0x00, 0x69, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x74, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xf6, 0x4d, 0x65, 0x40, 0x9d, 0xff, 0x26, 0x84, 0x3f, 0x6e, 0x6b, + 0x99, 0x75, 0xb0, 0xae, 0x60, 0x01, 0x8c, 0xf0, 0xf9, 0x30, 0x30, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, + 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x3d, 0xbb, 0x58, 0x44, 0x6c, 0xa3, 0x3c, 0x48, 0xaa, 0x52, 0x76, 0xd1, 0xef, 0x3a, + 0xe2, 0xa4, 0x23, 0xcc, 0x4d, 0x38, 0x04, 0x08, 0x11, 0xa4, 0xda, 0x79, 0x3e, 0xdd, 0xba, 0xfa, 0x02, 0x01, 0x01 +}; +unsigned int test_import_p12_len = 2499; + +// test_import_p12's password: "password" + static void verifyPrivateKeyExtractability(BOOL extractable, NSArray *items) { diff --git a/OSX/libsecurity_keychain/regressions/kc-40-seckey.m b/OSX/libsecurity_keychain/regressions/kc-40-seckey.m index da3a3eac..c0b3543a 100644 --- a/OSX/libsecurity_keychain/regressions/kc-40-seckey.m +++ b/OSX/libsecurity_keychain/regressions/kc-40-seckey.m @@ -1157,7 +1157,7 @@ static void testcopypubkfromcert() { options:NSDataBase64DecodingIgnoreUnknownCharacters]; SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData); SecKeyRef pubKey = NULL; - ok_status(SecCertificateCopyPublicKey(cert, &pubKey), "export public key from certificate"); + ok(pubKey = SecCertificateCopyKey(cert), "export public key from certificate"); NSData *pubKeyData = (__bridge_transfer NSData *)SecKeyCopyExternalRepresentation(pubKey, NULL); eq_cf( (__bridge CFTypeRef) pubKeyData, (__bridge CFTypeRef) pubKData, "public key exports itself into expected data"); CFReleaseNull(pubKey); diff --git a/OSX/libsecurity_keychain/regressions/kc-41-sececkey.m b/OSX/libsecurity_keychain/regressions/kc-41-sececkey.m index 2c5678b9..9bbf0759 100644 --- a/OSX/libsecurity_keychain/regressions/kc-41-sececkey.m +++ b/OSX/libsecurity_keychain/regressions/kc-41-sececkey.m @@ -136,48 +136,6 @@ static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) { } #endif - -#if !TARGET_OS_IPHONE -/* This is part of Security.framework on iOS */ - -enum { - // kSecKeyKeySizeInBits = 0, // already exists on osx - kSecKeySignatureSize = 101, - kSecKeyEncryptedDataSize = 102, - // More might belong here, but we aren't settled on how - // to take into account padding and/or digest types. -}; - -static -size_t SecKeyGetSize(SecKeyRef key, int whichSize) -{ - /* SecKeyGetBlockSize return the signature size on OS X -- smh */ - size_t result = SecKeyGetBlockSize(key); - - result = (result - 2)/2 - 3; - - /* in this test, this is always an ECDSA key */ - switch (whichSize) { - case kSecKeyEncryptedDataSize: - result = 0; - break; - case kSecKeySignatureSize: - result = (result >= 66 ? 9 : 8) + 2 * result; - break; - case kSecKeyKeySizeInBits: - if (result >= 66) - return 521; - } - - if (whichSize == kSecKeyKeySizeInBits) - result *= 8; - - return result; - -} -#endif - - static void testkeygen(size_t keySizeInBits) { SecKeyRef pubKey = NULL, privKey = NULL; size_t keySizeInBytes = (keySizeInBits + 7) / 8; @@ -211,8 +169,6 @@ SKIP: { skip("keygen failed", 8, status == errSecSuccess); ok(pubKey, "pubKey returned"); ok(privKey, "privKey returned"); - is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok"); - is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok"); /* Sign something. */ uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, }; @@ -302,8 +258,6 @@ SKIP: { skip("keygen failed", 8, status == errSecSuccess); ok(pubKey, "pubKey returned"); ok(privKey, "privKey returned"); - is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok"); - is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok"); SecKeyRef pubKey2, privKey2; CFDictionaryAddValue(pubd, kSecClass, kSecClassKey); @@ -320,7 +274,7 @@ SKIP: { /* Sign something. */ uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, }; - size_t sigLen = SecKeyGetSize(privKey2, kSecKeySignatureSize); + size_t sigLen = (((keySizeInBits + 7) / 8) + 3) * 2 + 3; uint8_t sig[sigLen]; ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1, something, sizeof(something), sig, &sigLen), "sign something"); @@ -674,7 +628,7 @@ static void tests(void) int kc_41_sececkey(int argc, char *const *argv) { - plan_tests(288); + plan_tests(272); tests(); diff --git a/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m b/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m index 7577325a..52cddf2e 100644 --- a/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m +++ b/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m @@ -244,6 +244,13 @@ static void test_store_cert_to_ios() { SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData); ok(cert != NULL, "create certificate from data"); + // Clean up any pre-existing data, but don't fail if nothing is deleted. + SecItemDelete((CFDictionaryRef)@{ + (id)kSecClass: (id)kSecClassCertificate, + (id)kSecAttrLabel: @"sectests:store_cert_to_ios", + (id)kSecAttrNoLegacy: @YES, + }); + // Store certificate to modern keychain. NSDictionary *attrs = @{ (id)kSecValueRef: (__bridge id)cert, diff --git a/OSX/libsecurity_keychain/regressions/kc-helpers.h b/OSX/libsecurity_keychain/regressions/kc-helpers.h index 60fc2583..fe6fde0b 100644 --- a/OSX/libsecurity_keychain/regressions/kc-helpers.h +++ b/OSX/libsecurity_keychain/regressions/kc-helpers.h @@ -33,6 +33,12 @@ #include "kc-keychain-file-helpers.h" +extern char keychainFile[1000]; +extern char keychainDbFile[1000]; +extern char keychainTempFile[1000]; +extern char keychainName[1000]; +extern char testName[1000]; + /* redefine this since the headers are mixed up */ static inline bool CFEqualSafe(CFTypeRef left, CFTypeRef right) { @@ -42,233 +48,40 @@ static inline bool CFEqualSafe(CFTypeRef left, CFTypeRef right) return CFEqual(left, right); } -static char keychainFile[1000]; -static char keychainDbFile[1000]; -static char keychainTempFile[1000]; -static char keychainName[1000]; -static char testName[1000]; -static uint32_t promptAttempts; - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-variable" -#pragma clang diagnostic ignored "-Wunused-function" - -static void startTest(const char* thisTestName) { - strlcpy(testName, thisTestName, sizeof(testName)); -} +void startTest(const char* thisTestName); -static void initializeKeychainTests(const char* thisTestName) { - const char *home_dir = getenv("HOME"); - snprintf(keychainName, sizeof(keychainName), "test-%s.asdf", thisTestName); - snprintf(keychainFile, sizeof(keychainFile), "%s/Library/Keychains/%s", home_dir, keychainName); - snprintf(keychainDbFile, sizeof(keychainDbFile), "%s/Library/Keychains/%s-db", home_dir, keychainName); - snprintf(keychainTempFile, sizeof(keychainTempFile), "%s/Library/Keychains/test_temp", home_dir); - - deleteKeychainFiles(keychainFile); - - startTest(thisTestName); - - SecKeychainGetUserPromptAttempts(&promptAttempts); - SecKeychainSetUserInteractionAllowed(FALSE); -} +void initializeKeychainTests(const char* thisTestName); // Use this at the bottom of every test to make sure everything is gone -static void deleteTestFiles() { - deleteKeychainFiles(keychainFile); -} - -static SecKeychainRef CF_RETURNS_RETAINED getPopulatedTestKeychain() { - deleteKeychainFiles(keychainFile); - - writeFile(keychainFile, test_keychain, sizeof(test_keychain)); - - SecKeychainRef kc = NULL; - ok_status(SecKeychainOpen(keychainFile, &kc), "%s: getPopulatedTestKeychain: SecKeychainOpen", testName); - ok_status(SecKeychainUnlock(kc, (UInt32) strlen(test_keychain_password), test_keychain_password, true), "%s: getPopulatedTestKeychain: SecKeychainUnlock", testName); - return kc; -} -#define getPopulatedTestKeychainTests 2 - -static SecKeychainRef CF_RETURNS_RETAINED getEmptyTestKeychain() { - deleteKeychainFiles(keychainFile); - - SecKeychainRef kc = NULL; - ok_status(SecKeychainCreate(keychainFile, (UInt32) strlen(test_keychain_password), test_keychain_password, false, NULL, &kc), "%s: getPopulatedTestKeychain: SecKeychainCreate", testName); - return kc; -} -#define getEmptyTestKeychainTests 1 - - -static void addToSearchList(SecKeychainRef keychain) { - CFArrayRef searchList = NULL; - SecKeychainCopySearchList(&searchList); - CFMutableArrayRef mutableSearchList = CFArrayCreateMutableCopy(NULL, CFArrayGetCount(searchList) + 1, searchList); - CFArrayAppendValue(mutableSearchList, keychain); - SecKeychainSetSearchList(mutableSearchList); - CFRelease(searchList); - CFRelease(mutableSearchList); -} +void deleteTestFiles(void); +void addToSearchList(SecKeychainRef keychain); /* Checks to be sure there are N elements in this search, and returns the first * if it exists. */ -static SecKeychainItemRef checkNCopyFirst(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n) { - CFArrayRef results = NULL; - if(n > 0) { - ok_status(SecItemCopyMatching(query, (CFTypeRef*) &results), "%s: SecItemCopyMatching", testName); - } else { - is(SecItemCopyMatching(query, (CFTypeRef*) &results), errSecItemNotFound, "%s: SecItemCopyMatching (for no items)", testName); - } - - SecKeychainItemRef item = NULL; - if(results) { - is(CFArrayGetCount(results), n, "%s: Wrong number of results", testName); - if(n >= 1) { - ok(item = (SecKeychainItemRef) CFArrayGetValueAtIndex(results, 0), "%s: Couldn't get item", testName); - } else { - pass("make test numbers match"); - } - } else if((!results) && n == 0) { - pass("%s: no results found (and none expected)", testName); - pass("make test numbers match"); - } else { - fail("%s: no results found (and %d expected)", testName, n); - fflush(stdout); CFShow(query); fflush(stdout); - pass("make test numbers match"); - } - - CFRetainSafe(item); - CFReleaseNull(results); - - CFRelease(query); - return item; -} - -static void checkN(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n) { - SecKeychainItemRef item = checkNCopyFirst(testName, query, n); - CFReleaseSafe(item); -} +SecKeychainItemRef checkNCopyFirst(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n); +void checkN(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n); #define checkNTests 3 - -static void readPasswordContentsWithResult(SecKeychainItemRef item, OSStatus expectedResult, CFStringRef expectedContents) { - if(!item) { - fail("no item passed to readPasswordContentsWithResult"); - fail("Match test numbers"); - fail("Match test numbers"); - return; - } - - CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne); - CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue); - - CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks); - CFArrayAppendValue((CFMutableArrayRef)itemList, item); - CFDictionarySetValue(query, kSecUseItemList, itemList); - - CFTypeRef results = NULL; - if(expectedContents) { - is(SecItemCopyMatching(query, (CFTypeRef*) &results), expectedResult, "%s: readPasswordContents: SecItemCopyMatching", testName); - CFReleaseNull(query); - - if(results) { - ok(CFGetTypeID(results) == CFDataGetTypeID(), "%s: result is not a data", testName); - - CFDataRef data = (CFDataRef) results; - CFStringRef str = CFStringCreateWithBytes(NULL, CFDataGetBytePtr(data), CFDataGetLength(data), kCFStringEncodingUTF8, false); - eq_cf(str, expectedContents, "%s: contents do not match", testName); - CFReleaseNull(str); - CFReleaseNull(results); - } else { - fail("Didn't get any results"); - fail("Match test numbers"); - } - } else { - is(SecItemCopyMatching(query, (CFTypeRef*) &results), expectedResult, "%s: readPasswordContents: expecting error %d", testName, (int) expectedResult); - pass("Match test numbers"); - pass("Match test numbers"); - } -} +void readPasswordContentsWithResult(SecKeychainItemRef item, OSStatus expectedResult, CFStringRef expectedContents); #define readPasswordContentsWithResultTests 3 -static void readPasswordContents(SecKeychainItemRef item, CFStringRef expectedContents) { - return readPasswordContentsWithResult(item, errSecSuccess, expectedContents); -} +void readPasswordContents(SecKeychainItemRef item, CFStringRef expectedContents); #define readPasswordContentsTests readPasswordContentsWithResultTests -static void changePasswordContents(SecKeychainItemRef item, CFStringRef newPassword) { - if(!item) { - fail("no item passed to changePasswordContents"); - return; - } - - CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne); - - CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks); - CFArrayAppendValue((CFMutableArrayRef)itemList, item); - CFDictionarySetValue(query, kSecUseItemList, itemList); - - CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDataRef data = CFDataCreate(NULL, (const UInt8*) CFStringGetCStringPtr(newPassword, kCFStringEncodingUTF8), CFStringGetLength(newPassword)); - CFDictionarySetValue(attrs, kSecValueData, data); - CFReleaseNull(data); - - ok_status(SecItemUpdate(query, attrs), "%s: SecItemUpdate", testName); -} +void changePasswordContents(SecKeychainItemRef item, CFStringRef newPassword); #define changePasswordContentsTests 1 -static void deleteItem(SecKeychainItemRef item) { - CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks); - CFArrayAppendValue((CFMutableArrayRef)itemList, item); - CFDictionarySetValue(query, kSecUseItemList, itemList); - - ok_status(SecItemDelete(query), "%s: SecItemDelete single item", testName); - CFReleaseNull(query); -} +void deleteItem(SecKeychainItemRef item); #define deleteItemTests 1 -static void deleteItems(CFArrayRef items) { - if(!items) { - fail("no items passed to deleteItems"); - return; - } - - CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(query, kSecUseItemList, items); - - size_t count = (size_t) CFArrayGetCount(items); - if(count > 0) { - ok_status(SecItemDelete(query), "%s: SecItemDelete %ld items", testName, count); - } else { - is(SecItemDelete(query), errSecItemNotFound, "%s: SecItemDelete no items", testName); - } - CFReleaseNull(query); -} +void deleteItems(CFArrayRef items); #define deleteItemsTests 1 /* Checks in with securityd to see how many prompts were generated since the last call to this function, and tests against the number expected. Returns the number generated since the last call. */ -static uint32_t checkPrompts(uint32_t expectedSinceLastCall, char* explanation) { - uint32_t currentPrompts = UINT_MAX; - uint32_t newPrompts = UINT_MAX; - ok_status(SecKeychainGetUserPromptAttempts(¤tPrompts), "%s: SecKeychainGetUserPromptAttempts", testName); - - newPrompts = currentPrompts - promptAttempts; - - is(newPrompts, expectedSinceLastCall, "%s: wrong number of prompts: %s", testName, explanation); - promptAttempts = currentPrompts; - - return newPrompts; -} +uint32_t checkPrompts(uint32_t expectedSinceLastCall, char* explanation); #define checkPromptsTests 2 -#pragma clang diagnostic pop - #endif /* kc_helpers_h */ diff --git a/OSX/libsecurity_keychain/regressions/kc-identity-helpers.h b/OSX/libsecurity_keychain/regressions/kc-identity-helpers.h index 60c14cff..c1a17b3d 100644 --- a/OSX/libsecurity_keychain/regressions/kc-identity-helpers.h +++ b/OSX/libsecurity_keychain/regressions/kc-identity-helpers.h @@ -134,137 +134,6 @@ findIdentity(SecKeychainRef keychain, SecCertificateRef cert) } #define findIdentityTests 2 -unsigned char test_import_p12[] = { - 0x30, 0x82, 0x09, 0xbf, 0x02, 0x01, 0x03, 0x30, 0x82, 0x09, 0x86, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x07, 0x01, 0xa0, 0x82, 0x09, 0x77, 0x04, 0x82, 0x09, 0x73, 0x30, 0x82, 0x09, 0x6f, 0x30, 0x82, 0x03, 0xff, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x03, 0xec, 0x02, 0x01, 0x00, - 0x30, 0x82, 0x03, 0xe5, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xcb, 0xa2, 0x8c, 0x60, 0xc2, 0x36, 0x55, - 0x05, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03, 0xb8, 0x57, 0x1d, 0x4c, 0x1f, 0xc7, 0x4c, 0x00, 0x82, 0xa3, 0xc9, 0x6f, - 0x2e, 0x00, 0x03, 0x1b, 0x55, 0xaa, 0xe5, 0x89, 0x58, 0x18, 0x71, 0xb8, 0xff, 0x40, 0x13, 0xd5, 0xac, 0x7f, 0xf1, 0x48, - 0xb2, 0x7e, 0x6e, 0xeb, 0x6e, 0xde, 0xe8, 0x35, 0x22, 0xa5, 0x45, 0x5a, 0xa6, 0x2e, 0xed, 0x0d, 0xe0, 0x8f, 0x2f, 0x60, - 0x5c, 0xd8, 0x49, 0x89, 0x26, 0x42, 0xd6, 0xe0, 0x24, 0x1c, 0x59, 0x9c, 0xe0, 0xbf, 0x98, 0x0c, 0xc3, 0x81, 0x20, 0x47, - 0x03, 0x03, 0xe2, 0x73, 0x90, 0x13, 0x6e, 0x96, 0x31, 0x68, 0xb7, 0x8f, 0xaa, 0x25, 0x4b, 0x27, 0x95, 0x3f, 0xef, 0xa3, - 0x2b, 0x96, 0x10, 0x85, 0xf3, 0x49, 0x3c, 0x6f, 0x9a, 0x20, 0x02, 0x17, 0x42, 0xe9, 0x9c, 0x5e, 0x5d, 0x4b, 0x3c, 0x88, - 0x65, 0xf5, 0x67, 0x61, 0x3e, 0xa6, 0x1a, 0x0f, 0x5b, 0x1e, 0x35, 0x18, 0x4e, 0xf3, 0x98, 0x93, 0x7e, 0x76, 0x77, 0x31, - 0x3b, 0x00, 0x78, 0x8c, 0x50, 0x28, 0x76, 0xca, 0xc8, 0x39, 0xc5, 0xf5, 0x79, 0x23, 0x4a, 0xea, 0x9a, 0xf0, 0xb5, 0xb6, - 0x50, 0x8d, 0x16, 0xd9, 0x39, 0x74, 0x36, 0x1d, 0x26, 0xcb, 0xbf, 0xb7, 0x72, 0x5e, 0x77, 0xf5, 0xb8, 0x35, 0xfc, 0x66, - 0x4d, 0xdc, 0xd6, 0x20, 0x50, 0x70, 0xc6, 0xf7, 0x13, 0x55, 0xb1, 0x97, 0x7e, 0x1d, 0x6a, 0x7d, 0x73, 0xc2, 0x71, 0x49, - 0xd1, 0x15, 0xe7, 0x30, 0xa7, 0x52, 0x1f, 0x24, 0xe8, 0x7b, 0xd7, 0x81, 0x53, 0x27, 0x94, 0xd0, 0x31, 0xe5, 0x11, 0xe4, - 0x90, 0x8a, 0x02, 0x46, 0x70, 0x82, 0xe7, 0xc4, 0xfe, 0xb5, 0xed, 0xb0, 0x1b, 0xcb, 0xa2, 0x23, 0x5c, 0xd2, 0x95, 0xe6, - 0x2c, 0x5f, 0x2d, 0x07, 0xb1, 0xd8, 0xe8, 0xa0, 0x39, 0xe7, 0xdd, 0x2e, 0x36, 0xac, 0x38, 0xfc, 0x65, 0x99, 0x2c, 0xda, - 0x3d, 0x26, 0x5d, 0x1e, 0x2f, 0xbc, 0x31, 0x36, 0x3e, 0x87, 0x55, 0x5f, 0x40, 0xf1, 0x77, 0x7a, 0x15, 0xa2, 0xc3, 0xe4, - 0x21, 0xc0, 0xe1, 0x11, 0x15, 0x31, 0xf4, 0x7a, 0x51, 0xc3, 0x78, 0x70, 0xfc, 0x3b, 0xed, 0x04, 0x7f, 0x5c, 0xaf, 0x22, - 0x37, 0x1c, 0x80, 0xb6, 0x7b, 0xdf, 0x11, 0x90, 0x52, 0xc1, 0x0d, 0xfb, 0xaa, 0xd0, 0x43, 0x47, 0xe9, 0xdb, 0x31, 0xb7, - 0xfc, 0x35, 0xbf, 0xce, 0x00, 0x15, 0x0d, 0x51, 0xb1, 0x78, 0x99, 0x55, 0x91, 0x1f, 0xf1, 0x4c, 0x36, 0xfa, 0xc1, 0xa0, - 0xce, 0x86, 0xc9, 0x79, 0x60, 0x07, 0x58, 0xa7, 0xe5, 0x28, 0x28, 0x84, 0x92, 0x03, 0x2c, 0x43, 0xda, 0x69, 0xce, 0x75, - 0x25, 0x01, 0x51, 0x37, 0xd4, 0xfd, 0xa2, 0xc4, 0x09, 0xfb, 0xa0, 0xf5, 0x1f, 0x23, 0x7b, 0xd6, 0x63, 0xd1, 0xb5, 0x5b, - 0xc5, 0xd9, 0xbc, 0xe7, 0xd4, 0x5e, 0x8b, 0x62, 0xee, 0xdb, 0xb7, 0x1e, 0xd2, 0x8b, 0x6e, 0xe4, 0x8c, 0xfd, 0x11, 0x25, - 0xda, 0xac, 0x2a, 0x7a, 0x9a, 0xad, 0x6c, 0x29, 0xe1, 0x1c, 0x68, 0x4f, 0xb3, 0x99, 0x06, 0xb4, 0x72, 0x2a, 0x5a, 0x70, - 0xd6, 0xf6, 0x7c, 0x22, 0x0f, 0x85, 0xf1, 0xc4, 0x30, 0x9f, 0x32, 0x53, 0xa1, 0xb2, 0x1a, 0x41, 0x01, 0xa2, 0x92, 0x58, - 0xa2, 0x27, 0xe8, 0x09, 0xed, 0x75, 0x84, 0x41, 0xcd, 0x19, 0x46, 0x47, 0x86, 0x7d, 0xa0, 0x49, 0xc4, 0x72, 0x94, 0x9f, - 0x43, 0xf2, 0x09, 0x3a, 0x59, 0x56, 0x7c, 0x3b, 0x34, 0x79, 0x1b, 0x58, 0x82, 0xc7, 0x64, 0x19, 0x7c, 0x32, 0x7b, 0x42, - 0x66, 0x9f, 0x32, 0xef, 0x48, 0xb4, 0xf7, 0xd0, 0x74, 0x1f, 0x1c, 0xbe, 0xd4, 0x7a, 0x2a, 0x02, 0xb2, 0x3d, 0x47, 0x15, - 0x40, 0xa8, 0xd5, 0x57, 0xc8, 0xe7, 0x7d, 0x8d, 0xa6, 0xea, 0xe5, 0x21, 0x6a, 0xbe, 0x39, 0x8c, 0xfd, 0x78, 0x26, 0xaf, - 0x31, 0x93, 0x0f, 0x94, 0x07, 0x87, 0x6c, 0xa8, 0x56, 0xd8, 0xc6, 0x79, 0xcf, 0x1d, 0x36, 0xee, 0xab, 0x33, 0x5b, 0x63, - 0xe8, 0x34, 0x00, 0x0c, 0x95, 0x48, 0x34, 0xac, 0xe2, 0xda, 0x61, 0x7a, 0x97, 0x3e, 0x41, 0xe4, 0xb7, 0x30, 0xb0, 0xb3, - 0x96, 0xed, 0x91, 0xb8, 0x5b, 0x20, 0x30, 0xfa, 0xf0, 0xfa, 0xc7, 0xc2, 0x97, 0x14, 0x9b, 0x81, 0xa9, 0x70, 0x8a, 0x10, - 0xf1, 0x75, 0xe4, 0xec, 0x54, 0x3e, 0xd9, 0xa8, 0x94, 0xcd, 0x3a, 0x82, 0xf7, 0xe3, 0xb8, 0x75, 0xd7, 0x49, 0x6c, 0x80, - 0x97, 0xd8, 0xdf, 0x56, 0x66, 0x93, 0xe6, 0xef, 0xa3, 0xc3, 0xd6, 0x34, 0xb7, 0x6f, 0x9b, 0x51, 0xaa, 0x7c, 0x1e, 0x16, - 0x8f, 0x21, 0x8a, 0x0a, 0x9f, 0x0e, 0xbe, 0x6b, 0x96, 0x8b, 0x95, 0x95, 0x5d, 0x11, 0x39, 0x15, 0x8c, 0xca, 0x9d, 0xec, - 0x26, 0x39, 0x49, 0x1e, 0xf6, 0x16, 0x09, 0x36, 0x95, 0xae, 0xa0, 0x55, 0xbf, 0x94, 0xf2, 0x6f, 0x1b, 0x74, 0x93, 0x97, - 0x6d, 0xd8, 0x00, 0x0c, 0xf0, 0x9e, 0x24, 0xb9, 0xfe, 0x04, 0xfa, 0x30, 0x63, 0x90, 0x28, 0xcb, 0x0d, 0x8e, 0xe8, 0xf0, - 0x7f, 0x9a, 0x69, 0x54, 0xf2, 0xbc, 0x9f, 0x24, 0x0b, 0xd1, 0xda, 0x2f, 0x22, 0x81, 0x22, 0x31, 0x03, 0xc2, 0x60, 0x41, - 0x2e, 0xe0, 0xc6, 0x52, 0x7b, 0x5a, 0x35, 0xbc, 0x00, 0xfd, 0x71, 0x00, 0x19, 0xd3, 0xa4, 0xa8, 0x5b, 0xbc, 0xfc, 0xae, - 0x24, 0x10, 0xb4, 0x21, 0x8c, 0x3c, 0x15, 0xad, 0x2d, 0x1e, 0x33, 0x09, 0x58, 0x93, 0xb4, 0x29, 0x3a, 0xbc, 0x6f, 0x7d, - 0x51, 0x3b, 0x5b, 0x97, 0xfe, 0x67, 0xe1, 0x9e, 0xff, 0x6b, 0xdc, 0xf2, 0xb0, 0x6f, 0xa1, 0x4e, 0x4b, 0xf2, 0xdf, 0xd6, - 0xa4, 0xec, 0x8d, 0x19, 0x6d, 0x30, 0x67, 0xde, 0x04, 0x5e, 0xaf, 0xd7, 0xd4, 0x42, 0xf8, 0xbc, 0xca, 0xfc, 0x49, 0xc0, - 0xe7, 0xcd, 0xfc, 0xab, 0xca, 0x3f, 0x67, 0xff, 0xfb, 0x41, 0xc0, 0xe4, 0xe8, 0x0c, 0xe8, 0x2e, 0xca, 0x43, 0xfb, 0xec, - 0xe0, 0xeb, 0xea, 0x30, 0x14, 0xca, 0x30, 0x8d, 0x49, 0xaa, 0x99, 0x71, 0xcb, 0x85, 0xa4, 0x68, 0xda, 0xd1, 0xbe, 0xa9, - 0xc6, 0xee, 0x26, 0xdf, 0x3f, 0xde, 0x39, 0x29, 0x6c, 0x45, 0x9e, 0x41, 0x88, 0x63, 0xd8, 0x31, 0x47, 0x8e, 0xdc, 0xc8, - 0xe4, 0x28, 0x25, 0x75, 0x11, 0x99, 0xdd, 0x28, 0x25, 0xa7, 0x5e, 0xac, 0x7f, 0x0c, 0xb5, 0x2b, 0x62, 0x9d, 0xe0, 0xda, - 0xe3, 0xc2, 0xd8, 0x8d, 0xc6, 0x25, 0x5f, 0x08, 0x6e, 0xfc, 0xcd, 0xae, 0x4c, 0x99, 0x41, 0xc4, 0x75, 0x3e, 0x5e, 0x51, - 0xa1, 0x76, 0x47, 0x93, 0x4a, 0x83, 0x51, 0x91, 0xf3, 0x92, 0xd0, 0x29, 0xa6, 0x44, 0x3c, 0x2a, 0x91, 0x3f, 0x01, 0x75, - 0xeb, 0x6f, 0xf3, 0x3c, 0x04, 0xd3, 0x74, 0x7a, 0xfc, 0x7a, 0x39, 0x70, 0xc8, 0x3a, 0x89, 0x93, 0xbd, 0xfd, 0xd7, 0x41, - 0x2c, 0xb0, 0xd3, 0xef, 0xd0, 0xd5, 0x75, 0x24, 0xb1, 0x0e, 0x3d, 0x89, 0x8e, 0xde, 0xa7, 0x40, 0x80, 0xd2, 0x05, 0xe5, - 0x18, 0xa2, 0xf3, 0x30, 0x22, 0x56, 0x0b, 0xbc, 0x05, 0xb0, 0x48, 0x9a, 0x42, 0xb7, 0xe1, 0x32, 0xba, 0x52, 0x99, 0x22, - 0xf6, 0x30, 0x82, 0x05, 0x68, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0x59, - 0x04, 0x82, 0x05, 0x55, 0x30, 0x82, 0x05, 0x51, 0x30, 0x82, 0x05, 0x4d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, 0xea, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x8e, 0x7e, 0x90, 0x94, 0xaf, 0x09, 0xc5, 0xbc, 0x02, - 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0x0c, 0x7c, 0x7f, 0x58, 0x8b, 0x41, 0x9a, 0xb8, 0x70, 0xbf, 0x6c, 0x4c, 0xb8, - 0x7d, 0x72, 0xa5, 0x50, 0xe6, 0xc4, 0xaf, 0x74, 0x0e, 0x88, 0xbf, 0x83, 0x51, 0xbc, 0xe1, 0x66, 0x8a, 0x9f, 0x42, 0x11, - 0x2b, 0x3d, 0x8c, 0x10, 0xa3, 0xc2, 0xdf, 0xb9, 0x36, 0x74, 0xc1, 0x18, 0x23, 0x1e, 0x9a, 0xbf, 0x8d, 0x0a, 0x4b, 0x63, - 0xd5, 0x20, 0x1b, 0xae, 0xb0, 0x64, 0xfc, 0xe1, 0x5c, 0xe7, 0xde, 0xa3, 0x6f, 0x8e, 0xe3, 0xc9, 0x8d, 0x18, 0x63, 0x7f, - 0x26, 0x4a, 0x3d, 0x41, 0x76, 0xa6, 0xaa, 0x3f, 0x27, 0x75, 0xec, 0x2f, 0x78, 0xd2, 0x40, 0x28, 0xe7, 0xf5, 0xee, 0x61, - 0x6d, 0x49, 0xe0, 0x64, 0x33, 0xc9, 0x9e, 0xf6, 0xda, 0x86, 0x3a, 0xad, 0x47, 0x13, 0xe2, 0x8a, 0x0b, 0x98, 0xe7, 0x73, - 0xea, 0x08, 0x59, 0xfe, 0x74, 0x6f, 0x10, 0x7d, 0xbc, 0x0b, 0xb9, 0xcf, 0xe7, 0xe7, 0x28, 0xe8, 0xfe, 0x20, 0x8a, 0x98, - 0x40, 0x00, 0x52, 0xa0, 0x0c, 0x5c, 0xfa, 0x48, 0x5b, 0xf4, 0x3c, 0x76, 0x5d, 0xf4, 0x33, 0x53, 0xd4, 0x51, 0x43, 0x47, - 0x29, 0xda, 0xff, 0xbd, 0xfe, 0x71, 0x5b, 0x50, 0xa1, 0xa5, 0x25, 0xe9, 0xcc, 0x68, 0x74, 0x9f, 0x7f, 0x39, 0x65, 0x5e, - 0xb9, 0x71, 0x8f, 0x25, 0x68, 0xe6, 0x71, 0x06, 0x10, 0xa2, 0xfb, 0x08, 0x54, 0x21, 0xca, 0x28, 0xfc, 0xf1, 0x89, 0xb9, - 0x29, 0x11, 0x67, 0x00, 0x19, 0xdd, 0x00, 0xd8, 0x48, 0x89, 0x46, 0x0d, 0x39, 0x0c, 0x7e, 0x94, 0x02, 0x80, 0x37, 0xa0, - 0x01, 0x45, 0x25, 0xbd, 0x8b, 0x44, 0xcc, 0xdf, 0x43, 0xa1, 0x1d, 0xf5, 0x59, 0x4b, 0x07, 0xe6, 0xab, 0x15, 0x93, 0x3d, - 0xea, 0x7d, 0xd6, 0xaa, 0xb0, 0x97, 0xed, 0x1d, 0x5e, 0xc2, 0xf0, 0xea, 0x1b, 0xc2, 0xcc, 0x88, 0x47, 0x3e, 0xe4, 0x54, - 0xc3, 0x02, 0xac, 0x5e, 0x88, 0xb9, 0x2f, 0x82, 0xd4, 0xd0, 0x5d, 0xb2, 0x2a, 0xee, 0x94, 0x3d, 0xdb, 0x82, 0x93, 0xc6, - 0x69, 0x5f, 0x40, 0x83, 0xf0, 0x07, 0x8d, 0x9f, 0x7f, 0x29, 0x3f, 0x4d, 0x3b, 0x08, 0xd9, 0x29, 0xf5, 0x1c, 0x0f, 0x18, - 0x42, 0x4b, 0xd9, 0x01, 0xda, 0x71, 0x92, 0xa8, 0x32, 0xa7, 0x53, 0x6f, 0xd0, 0x74, 0x4a, 0xee, 0x39, 0x04, 0xf1, 0x2d, - 0xee, 0x50, 0xbe, 0x48, 0xb1, 0x90, 0x21, 0x24, 0x28, 0x40, 0xa9, 0x85, 0xe1, 0x81, 0x77, 0x37, 0xa8, 0x86, 0x15, 0x7d, - 0x16, 0xb2, 0xe7, 0xcc, 0xe0, 0xa2, 0x7e, 0x58, 0xb3, 0xdc, 0xf9, 0x41, 0xae, 0x36, 0xba, 0x55, 0x87, 0x64, 0x01, 0xfd, - 0xc9, 0x0e, 0xa1, 0xfe, 0x55, 0xc3, 0x2a, 0x66, 0xd5, 0x83, 0x39, 0x7e, 0x5a, 0xe8, 0x28, 0x76, 0x36, 0xbb, 0x39, 0xa9, - 0xb7, 0xc6, 0xcf, 0x99, 0x56, 0xe5, 0xbf, 0x4d, 0xb2, 0xa0, 0xac, 0x64, 0x00, 0xc9, 0x42, 0x79, 0x47, 0x46, 0xd7, 0x9c, - 0x4a, 0x33, 0x03, 0x55, 0x07, 0x7f, 0x05, 0x23, 0xe3, 0x51, 0x35, 0xa9, 0x32, 0xe9, 0xa6, 0xf2, 0xe2, 0x42, 0x4d, 0x00, - 0xbb, 0xdb, 0xc3, 0x85, 0x05, 0xcb, 0xe4, 0xb1, 0x0a, 0x03, 0xf4, 0xe5, 0x27, 0x28, 0x12, 0xec, 0x1e, 0xd4, 0xd7, 0x43, - 0xe3, 0x05, 0xc7, 0x92, 0xd2, 0x8e, 0xf7, 0xae, 0x55, 0x1a, 0x50, 0x88, 0x2f, 0x91, 0x05, 0x65, 0x4b, 0xe3, 0xba, 0xc0, - 0x42, 0x86, 0x19, 0x2b, 0x64, 0xfc, 0x46, 0x31, 0x9b, 0xd2, 0x88, 0x32, 0xf8, 0x4d, 0x91, 0xd4, 0xc6, 0x77, 0xcb, 0x29, - 0x00, 0x5e, 0xd2, 0x48, 0x99, 0x0e, 0x3f, 0x2d, 0x4f, 0xdb, 0x9b, 0x05, 0xea, 0xa1, 0x3d, 0x9f, 0x21, 0x83, 0x6f, 0xcf, - 0xe9, 0x1c, 0x65, 0x40, 0x3c, 0x8b, 0x2a, 0x38, 0x8f, 0x1b, 0x5a, 0x3c, 0x73, 0x7a, 0xfc, 0x81, 0x69, 0xb3, 0xff, 0xb6, - 0x25, 0x12, 0x3f, 0xda, 0x50, 0xe7, 0xde, 0xfe, 0xd3, 0x31, 0x2f, 0xb4, 0x99, 0x87, 0xae, 0x17, 0xaf, 0xe4, 0xb8, 0x35, - 0xf7, 0x3c, 0xc0, 0x99, 0x0e, 0x75, 0x72, 0xb6, 0x46, 0xa1, 0x55, 0xef, 0xff, 0x48, 0x3b, 0x5c, 0x85, 0xf7, 0xc3, 0x03, - 0x0a, 0x49, 0x0f, 0x11, 0x48, 0x13, 0x8b, 0x90, 0x73, 0x33, 0xb6, 0x22, 0x35, 0x45, 0x07, 0x80, 0x1a, 0xf9, 0x91, 0x80, - 0x9d, 0x8b, 0xc7, 0x8e, 0xcc, 0x3a, 0x52, 0x93, 0x8f, 0xf6, 0x59, 0x3c, 0x69, 0xf7, 0x52, 0x9a, 0x8d, 0x8e, 0xfe, 0x8a, - 0x41, 0xb0, 0x43, 0x74, 0x04, 0xe8, 0x0e, 0xf5, 0xc1, 0x4c, 0xa3, 0x8d, 0xe3, 0x98, 0x25, 0xf6, 0xd5, 0x0d, 0xa9, 0x2d, - 0xb7, 0x6f, 0x52, 0x22, 0x43, 0x59, 0x30, 0x6d, 0x54, 0xb6, 0xad, 0x73, 0xa1, 0xe8, 0xee, 0x10, 0xbd, 0x55, 0xa4, 0x7f, - 0xc3, 0x1d, 0xad, 0x8e, 0x72, 0xf1, 0x26, 0x6d, 0xa1, 0xaf, 0xda, 0x82, 0x37, 0xa1, 0x6d, 0xfe, 0x78, 0xd1, 0x88, 0x65, - 0x6a, 0xb2, 0x33, 0x23, 0xcd, 0xba, 0xbe, 0x09, 0x66, 0x61, 0x33, 0xdc, 0x69, 0xed, 0x4f, 0xe6, 0xfb, 0x2f, 0x7d, 0xd0, - 0xfd, 0x7a, 0x21, 0x69, 0x2d, 0x1f, 0xd4, 0xc4, 0x93, 0x7c, 0x34, 0x7d, 0x67, 0x2c, 0xe9, 0x2a, 0x9a, 0x53, 0xc2, 0xbf, - 0xf9, 0x06, 0x10, 0xa6, 0xa8, 0x60, 0xe3, 0x01, 0xcb, 0x2b, 0x03, 0xdb, 0xb7, 0x27, 0xe9, 0x86, 0xe8, 0x7d, 0x75, 0xce, - 0x80, 0xdb, 0xaf, 0xe9, 0x7e, 0x75, 0xad, 0xe3, 0xd4, 0xc4, 0xf3, 0x10, 0x89, 0x16, 0xcb, 0xc6, 0x23, 0x5a, 0x58, 0x66, - 0xb6, 0x2a, 0xd7, 0xc9, 0x69, 0xd3, 0x7f, 0xa2, 0x9a, 0x5c, 0x1c, 0xd4, 0xf8, 0xe3, 0xe0, 0x63, 0x01, 0x88, 0x14, 0xb3, - 0x20, 0xe3, 0x22, 0x45, 0x3d, 0xae, 0xaf, 0x0b, 0x55, 0xa1, 0x65, 0xec, 0x16, 0x0b, 0x35, 0x37, 0x6f, 0x12, 0x5f, 0x29, - 0x47, 0xee, 0xdd, 0xbb, 0xcf, 0x9f, 0x87, 0xaf, 0x7d, 0xaa, 0xf4, 0x01, 0x45, 0xea, 0x5f, 0x00, 0x87, 0x1e, 0xeb, 0x2f, - 0x77, 0x2b, 0x92, 0x42, 0x04, 0x45, 0x33, 0xf2, 0xfb, 0x6b, 0xac, 0xca, 0x98, 0x79, 0x56, 0x6f, 0xe7, 0x5b, 0xbd, 0x63, - 0xc7, 0x3a, 0x8c, 0xfd, 0x93, 0xb1, 0x13, 0x4e, 0xc2, 0x05, 0x7f, 0xde, 0x44, 0xa8, 0xb7, 0xc4, 0x9c, 0xba, 0x57, 0x58, - 0x3b, 0xba, 0xb5, 0x74, 0x73, 0x97, 0x20, 0x53, 0x70, 0x70, 0x65, 0xf1, 0x81, 0xea, 0x07, 0xc2, 0xbe, 0x57, 0x71, 0x62, - 0x3b, 0xc0, 0x3c, 0x07, 0x65, 0xf4, 0x22, 0xfb, 0xd3, 0xf9, 0x2d, 0xb3, 0x20, 0xdd, 0x66, 0x51, 0x89, 0x54, 0x57, 0xcd, - 0xd7, 0xc7, 0x1a, 0xd9, 0xfe, 0xe0, 0x13, 0x9d, 0x7d, 0xe7, 0xe3, 0x2f, 0x65, 0x3e, 0xf0, 0xb2, 0xd9, 0x0c, 0x1a, 0xa9, - 0xaa, 0xba, 0x3b, 0x79, 0x86, 0xed, 0x6c, 0xbf, 0x9e, 0x9b, 0xb5, 0x78, 0xd8, 0x9e, 0x2f, 0x95, 0xcc, 0x31, 0xb4, 0x5f, - 0xd3, 0x63, 0xff, 0xb9, 0x62, 0x34, 0xfd, 0x78, 0x1f, 0xac, 0xe7, 0xbd, 0x29, 0x09, 0x2a, 0x1c, 0x94, 0xc5, 0x28, 0x6c, - 0x04, 0x59, 0xeb, 0xd6, 0x7c, 0x0d, 0x45, 0x07, 0xd9, 0xde, 0x89, 0xa1, 0xd8, 0x38, 0x8a, 0x2b, 0x9f, 0xc3, 0xdb, 0x55, - 0x89, 0x90, 0xc6, 0x75, 0xd0, 0x2f, 0x85, 0x9b, 0x0a, 0x5e, 0x04, 0xa1, 0xf9, 0xf7, 0x16, 0x35, 0x9d, 0x97, 0xfe, 0x7c, - 0x4b, 0x27, 0x4c, 0xc3, 0x8a, 0x2a, 0x56, 0x6a, 0x41, 0xe5, 0xd3, 0x82, 0xeb, 0xd2, 0x62, 0x4e, 0x11, 0x1e, 0x4e, 0xae, - 0xa4, 0x79, 0x89, 0x20, 0x82, 0x6e, 0x39, 0x7d, 0x70, 0xf8, 0x17, 0xd6, 0xe3, 0x67, 0x9a, 0x14, 0xd7, 0xc8, 0x80, 0xbe, - 0x62, 0x52, 0xe7, 0x69, 0xab, 0x98, 0xa9, 0x14, 0x98, 0xbd, 0x30, 0xf4, 0xab, 0x2c, 0x22, 0x6b, 0x5f, 0xee, 0x58, 0xf3, - 0x6f, 0x15, 0xea, 0xce, 0xd3, 0x1b, 0x07, 0xfa, 0xe6, 0x4c, 0xeb, 0xeb, 0x30, 0xa6, 0xff, 0x03, 0xc9, 0x75, 0x94, 0xa5, - 0x5b, 0x68, 0xd3, 0x42, 0x85, 0x3f, 0xa4, 0x87, 0xee, 0x3f, 0x14, 0x63, 0x16, 0x52, 0x26, 0x3b, 0x1a, 0xee, 0x48, 0x77, - 0x6e, 0x4a, 0x56, 0x01, 0x53, 0x54, 0x1b, 0xa6, 0xd7, 0x72, 0x98, 0x89, 0xd5, 0xf7, 0x11, 0x3a, 0x86, 0xac, 0x64, 0xe6, - 0x59, 0xba, 0x07, 0xea, 0x23, 0x21, 0x05, 0xd6, 0x14, 0xed, 0x88, 0x2e, 0x96, 0xb3, 0x90, 0xc3, 0xb7, 0xc4, 0x5b, 0x8f, - 0x0e, 0xcd, 0x56, 0xba, 0xb8, 0x4b, 0x7b, 0xfd, 0xd4, 0x7d, 0x0c, 0xcb, 0xe1, 0xff, 0xaf, 0x3e, 0x2a, 0x7c, 0x1a, 0xe5, - 0x66, 0x65, 0x59, 0x42, 0xd7, 0x3b, 0xd2, 0x2e, 0x89, 0x1d, 0x64, 0xc0, 0xbd, 0xec, 0x8c, 0xaa, 0x06, 0xb8, 0x5a, 0x7c, - 0xb8, 0xd0, 0xa5, 0xef, 0x5a, 0xf3, 0x92, 0x4c, 0x2f, 0x60, 0x98, 0x34, 0x73, 0x49, 0x92, 0x7a, 0x5d, 0x7c, 0x2c, 0xcd, - 0x0b, 0xfb, 0x28, 0xd9, 0x3e, 0xfa, 0xbd, 0x76, 0x0f, 0xaa, 0x71, 0xfa, 0x98, 0x36, 0x94, 0x97, 0xaa, 0x97, 0x1f, 0x34, - 0x21, 0x72, 0xc6, 0x19, 0xb4, 0xe3, 0xaa, 0x05, 0x16, 0xda, 0xaa, 0x92, 0x04, 0x49, 0xc7, 0x97, 0x42, 0x58, 0xd0, 0x80, - 0xdc, 0x9e, 0xcf, 0xfa, 0x5f, 0x4b, 0xbc, 0x78, 0xff, 0x95, 0x39, 0x31, 0x4c, 0x30, 0x25, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31, 0x18, 0x1e, 0x16, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5f, - 0x00, 0x69, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x74, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xf6, 0x4d, 0x65, 0x40, 0x9d, 0xff, 0x26, 0x84, 0x3f, 0x6e, 0x6b, - 0x99, 0x75, 0xb0, 0xae, 0x60, 0x01, 0x8c, 0xf0, 0xf9, 0x30, 0x30, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x3d, 0xbb, 0x58, 0x44, 0x6c, 0xa3, 0x3c, 0x48, 0xaa, 0x52, 0x76, 0xd1, 0xef, 0x3a, - 0xe2, 0xa4, 0x23, 0xcc, 0x4d, 0x38, 0x04, 0x08, 0x11, 0xa4, 0xda, 0x79, 0x3e, 0xdd, 0xba, 0xfa, 0x02, 0x01, 0x01 -}; -unsigned int test_import_p12_len = 2499; - -// test_import_p12's password: "password" - #pragma clang diagnostic pop #endif /* kc_identity_helpers_h */ diff --git a/OSX/libsecurity_keychain/regressions/kc-keychain-file-helpers.c b/OSX/libsecurity_keychain/regressions/kc-keychain-file-helpers.c new file mode 100644 index 00000000..696b1905 --- /dev/null +++ b/OSX/libsecurity_keychain/regressions/kc-keychain-file-helpers.c @@ -0,0 +1,2527 @@ + +#include "kc-keychain-file-helpers.h" +#include "kc-helpers.h" + +char keychainFile[1000]; +char keychainDbFile[1000]; +char keychainTempFile[1000]; +char keychainName[1000]; +char testName[1000]; +uint32_t promptAttempts; + +const char * test_keychain_password = "password"; + +unsigned char test_keychain[] = { + 0x6b, 0x79, 0x63, 0x68, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb3, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x03, 0x64, 0x00, 0x00, 0x1b, 0x70, + 0x00, 0x00, 0x4d, 0xe8, 0x00, 0x00, 0x4e, 0x10, 0x00, 0x00, 0x57, 0xe0, 0x00, 0x00, 0x6c, 0x88, 0x00, 0x00, 0x8b, 0x44, + 0x00, 0x00, 0x91, 0x20, 0x00, 0x00, 0x96, 0x4c, 0x00, 0x00, 0x97, 0x0c, 0x00, 0x00, 0xb2, 0x28, 0x00, 0x00, 0x03, 0x2c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x03, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x01, 0x14, + 0x00, 0x00, 0x01, 0x5c, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x02, 0x04, + 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x02, 0xd8, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, + 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x43, 0x53, 0x53, 0x4d, + 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, + 0x55, 0x54, 0x45, 0x53, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x19, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, + 0x41, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, + 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x50, 0x41, 0x52, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x4f, + 0x44, 0x55, 0x4c, 0x45, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x44, 0x42, 0x42, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1c, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, + 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d, + 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x50, 0x52, + 0x49, 0x56, 0x41, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1f, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, + 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x53, 0x59, 0x4d, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, + 0x4b, 0x45, 0x59, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x22, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, + 0x44, 0x5f, 0x58, 0x35, 0x30, 0x39, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, + 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x01, 0x84, + 0x00, 0x00, 0x01, 0xc4, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x44, 0x00, 0x00, 0x02, 0x84, 0x00, 0x00, 0x02, 0xc4, + 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x03, 0x44, 0x00, 0x00, 0x03, 0x84, 0x00, 0x00, 0x03, 0xc4, 0x00, 0x00, 0x04, 0x04, + 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x04, 0x84, 0x00, 0x00, 0x04, 0xc4, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x05, 0x44, + 0x00, 0x00, 0x05, 0x84, 0x00, 0x00, 0x05, 0xc4, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x06, 0x44, 0x00, 0x00, 0x06, 0x84, + 0x00, 0x00, 0x06, 0xc4, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x84, 0x00, 0x00, 0x07, 0xc4, + 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x08, 0x44, 0x00, 0x00, 0x08, 0x84, 0x00, 0x00, 0x08, 0xc4, 0x00, 0x00, 0x09, 0x04, + 0x00, 0x00, 0x09, 0x44, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x09, 0xc4, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x44, + 0x00, 0x00, 0x0a, 0x84, 0x00, 0x00, 0x0a, 0xc4, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x0b, 0x44, 0x00, 0x00, 0x0b, 0x84, + 0x00, 0x00, 0x0b, 0xc4, 0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x0c, 0x44, 0x00, 0x00, 0x0c, 0x84, 0x00, 0x00, 0x0c, 0xc4, + 0x00, 0x00, 0x0d, 0x04, 0x00, 0x00, 0x0d, 0x44, 0x00, 0x00, 0x0d, 0x84, 0x00, 0x00, 0x0d, 0xc4, 0x00, 0x00, 0x0e, 0x04, + 0x00, 0x00, 0x0e, 0x44, 0x00, 0x00, 0x0e, 0x84, 0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x0f, 0x44, + 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0x0f, 0xc4, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x10, 0x84, + 0x00, 0x00, 0x10, 0xc4, 0x00, 0x00, 0x11, 0x04, 0x00, 0x00, 0x11, 0x44, 0x00, 0x00, 0x11, 0x84, 0x00, 0x00, 0x11, 0xc4, + 0x00, 0x00, 0x12, 0x04, 0x00, 0x00, 0x12, 0x44, 0x00, 0x00, 0x12, 0x84, 0x00, 0x00, 0x12, 0xc4, 0x00, 0x00, 0x13, 0x04, + 0x00, 0x00, 0x13, 0x44, 0x00, 0x00, 0x13, 0x84, 0x00, 0x00, 0x13, 0xc4, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x14, 0x44, + 0x00, 0x00, 0x14, 0x84, 0x00, 0x00, 0x14, 0xc4, 0x00, 0x00, 0x15, 0x04, 0x00, 0x00, 0x15, 0x44, 0x00, 0x00, 0x15, 0x84, + 0x00, 0x00, 0x15, 0xc4, 0x00, 0x00, 0x16, 0x04, 0x00, 0x00, 0x16, 0x44, 0x00, 0x00, 0x16, 0x84, 0x00, 0x00, 0x16, 0xc4, + 0x00, 0x00, 0x17, 0x04, 0x00, 0x00, 0x17, 0x44, 0x00, 0x00, 0x17, 0x84, 0x00, 0x00, 0x17, 0xc4, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x61, 0x63, 0x63, 0x74, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x73, 0x73, 0x69, 0x67, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, + 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x06, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x72, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x70, 0x74, 0x63, 0x6c, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, + 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0d, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1d, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x27, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2c, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x36, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3b, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4a, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4f, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x6e, 0x62, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x73, 0x75, 0x62, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x73, 0x6e, 0x62, 0x72, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x73, 0x6b, 0x69, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x59, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x78, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x02, 0xac, + 0x00, 0x00, 0x32, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x02, 0xac, 0x00, 0x00, 0x02, 0xfc, + 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x03, 0x9c, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x04, 0x98, + 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x05, 0x90, 0x00, 0x00, 0x05, 0xdc, 0x00, 0x00, 0x06, 0x2c, + 0x00, 0x00, 0x06, 0x7c, 0x00, 0x00, 0x06, 0xd4, 0x00, 0x00, 0x07, 0x24, 0x00, 0x00, 0x07, 0x74, 0x00, 0x00, 0x07, 0xc0, + 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x58, 0x00, 0x00, 0x08, 0xac, 0x00, 0x00, 0x08, 0xec, 0x00, 0x00, 0x09, 0x2c, + 0x00, 0x00, 0x09, 0x6c, 0x00, 0x00, 0x09, 0xac, 0x00, 0x00, 0x09, 0xec, 0x00, 0x00, 0x0a, 0x2c, 0x00, 0x00, 0x0a, 0x6c, + 0x00, 0x00, 0x0a, 0xbc, 0x00, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x0b, 0x48, 0x00, 0x00, 0x0b, 0x88, 0x00, 0x00, 0x0b, 0xc8, + 0x00, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x0c, 0x48, 0x00, 0x00, 0x0c, 0x88, 0x00, 0x00, 0x0c, 0xc8, 0x00, 0x00, 0x0d, 0x08, + 0x00, 0x00, 0x0d, 0x48, 0x00, 0x00, 0x0d, 0x88, 0x00, 0x00, 0x0d, 0xc8, 0x00, 0x00, 0x0e, 0x08, 0x00, 0x00, 0x0e, 0x48, + 0x00, 0x00, 0x0e, 0x88, 0x00, 0x00, 0x0e, 0xd8, 0x00, 0x00, 0x0f, 0x24, 0x00, 0x00, 0x0f, 0x64, 0x00, 0x00, 0x0f, 0xa4, + 0x00, 0x00, 0x0f, 0xe4, 0x00, 0x00, 0x10, 0x24, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00, 0x10, 0xa4, 0x00, 0x00, 0x10, 0xe4, + 0x00, 0x00, 0x11, 0x24, 0x00, 0x00, 0x11, 0x64, 0x00, 0x00, 0x11, 0xa4, 0x00, 0x00, 0x11, 0xe4, 0x00, 0x00, 0x12, 0x24, + 0x00, 0x00, 0x12, 0x64, 0x00, 0x00, 0x12, 0xa4, 0x00, 0x00, 0x12, 0xe4, 0x00, 0x00, 0x13, 0x24, 0x00, 0x00, 0x13, 0x64, + 0x00, 0x00, 0x13, 0xb4, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x14, 0xc0, + 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x40, 0x00, 0x00, 0x15, 0x80, 0x00, 0x00, 0x15, 0xc0, 0x00, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x16, 0x40, 0x00, 0x00, 0x16, 0x80, 0x00, 0x00, 0x16, 0xc0, 0x00, 0x00, 0x17, 0x0c, 0x00, 0x00, 0x17, 0x5c, + 0x00, 0x00, 0x17, 0xa8, 0x00, 0x00, 0x17, 0xf8, 0x00, 0x00, 0x18, 0x44, 0x00, 0x00, 0x18, 0x94, 0x00, 0x00, 0x18, 0xe0, + 0x00, 0x00, 0x19, 0x34, 0x00, 0x00, 0x19, 0x84, 0x00, 0x00, 0x19, 0xd0, 0x00, 0x00, 0x1a, 0x24, 0x00, 0x00, 0x1a, 0x78, + 0x00, 0x00, 0x1a, 0xc8, 0x00, 0x00, 0x1b, 0x14, 0x00, 0x00, 0x1b, 0x64, 0x00, 0x00, 0x1b, 0xb8, 0x00, 0x00, 0x1c, 0x08, + 0x00, 0x00, 0x1c, 0x5c, 0x00, 0x00, 0x1c, 0xa8, 0x00, 0x00, 0x1c, 0xf4, 0x00, 0x00, 0x1d, 0x40, 0x00, 0x00, 0x1d, 0x88, + 0x00, 0x00, 0x1d, 0xd4, 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1e, 0x78, 0x00, 0x00, 0x1e, 0xc0, 0x00, 0x00, 0x1f, 0x0c, + 0x00, 0x00, 0x1f, 0x58, 0x00, 0x00, 0x1f, 0xa8, 0x00, 0x00, 0x1f, 0xf4, 0x00, 0x00, 0x20, 0x44, 0x00, 0x00, 0x20, 0x90, + 0x00, 0x00, 0x20, 0xe0, 0x00, 0x00, 0x21, 0x2c, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x21, 0xd0, 0x00, 0x00, 0x22, 0x1c, + 0x00, 0x00, 0x22, 0x70, 0x00, 0x00, 0x22, 0xc4, 0x00, 0x00, 0x23, 0x14, 0x00, 0x00, 0x23, 0x60, 0x00, 0x00, 0x23, 0xb0, + 0x00, 0x00, 0x24, 0x04, 0x00, 0x00, 0x24, 0x54, 0x00, 0x00, 0x24, 0xa8, 0x00, 0x00, 0x24, 0xf4, 0x00, 0x00, 0x25, 0x40, + 0x00, 0x00, 0x25, 0x8c, 0x00, 0x00, 0x25, 0xd4, 0x00, 0x00, 0x26, 0x20, 0x00, 0x00, 0x26, 0x70, 0x00, 0x00, 0x26, 0xc4, + 0x00, 0x00, 0x27, 0x0c, 0x00, 0x00, 0x27, 0x58, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x27, 0xf4, 0x00, 0x00, 0x28, 0x40, + 0x00, 0x00, 0x28, 0x90, 0x00, 0x00, 0x28, 0xdc, 0x00, 0x00, 0x29, 0x2c, 0x00, 0x00, 0x29, 0x78, 0x00, 0x00, 0x29, 0xcc, + 0x00, 0x00, 0x2a, 0x1c, 0x00, 0x00, 0x2a, 0x68, 0x00, 0x00, 0x2a, 0xbc, 0x00, 0x00, 0x2b, 0x10, 0x00, 0x00, 0x2b, 0x60, + 0x00, 0x00, 0x2b, 0xac, 0x00, 0x00, 0x2b, 0xfc, 0x00, 0x00, 0x2c, 0x50, 0x00, 0x00, 0x2c, 0xa0, 0x00, 0x00, 0x2c, 0xf4, + 0x00, 0x00, 0x2d, 0x40, 0x00, 0x00, 0x2d, 0x8c, 0x00, 0x00, 0x2d, 0xd8, 0x00, 0x00, 0x2e, 0x20, 0x00, 0x00, 0x2e, 0x6c, + 0x00, 0x00, 0x2e, 0xbc, 0x00, 0x00, 0x2f, 0x10, 0x00, 0x00, 0x2f, 0x58, 0x00, 0x00, 0x2f, 0xa4, 0x00, 0x00, 0x2f, 0xf0, + 0x00, 0x00, 0x30, 0x40, 0x00, 0x00, 0x30, 0x90, 0x00, 0x00, 0x30, 0xdc, 0x00, 0x00, 0x31, 0x28, 0x00, 0x00, 0x31, 0x74, + 0x00, 0x00, 0x31, 0xc4, 0x00, 0x00, 0x32, 0x1c, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x44, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x46, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x44, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x44, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x4c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x41, 0x64, 0x64, 0x69, 0x6e, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x53, 0x53, 0x49, 0x44, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x53, 0x75, 0x62, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x64, 0x61, 0x74, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, + 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, + 0x73, 0x63, 0x72, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x1b, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, + 0x69, 0x6e, 0x76, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1d, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x00, 0x6e, 0x65, 0x67, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, + 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x00, 0x67, 0x65, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x63, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, + 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x27, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x02, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x63, 0x72, 0x70, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x69, 0x6e, 0x76, 0x69, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x6e, 0x65, 0x67, 0x61, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, + 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2f, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x02, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x72, 0x76, 0x72, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, + 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x34, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x02, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x63, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x6d, 0x64, 0x61, 0x74, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x01, 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x73, 0x63, 0x72, 0x70, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x69, 0x6e, 0x76, 0x69, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, + 0x6e, 0x65, 0x67, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x41, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x01, 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x73, 0x64, 0x6d, 0x6e, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, + 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x46, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x80, 0x00, 0x00, 0x01, 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x61, 0x74, 0x68, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x65, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, + 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x51, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x41, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, + 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, + 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, + 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x4b, 0x65, 0x79, 0x53, + 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, + 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, + 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, + 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, + 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, + 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x5f, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x53, 0x69, 0x67, 0x6e, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, + 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x65, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x65, 0x79, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x0a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, + 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, + 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x10, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x09, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x0f, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x06, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x53, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x06, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, + 0x4b, 0x65, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x81, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x82, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x0d, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, + 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, + 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x92, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x96, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x99, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x08, 0x43, 0x65, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x63, 0x65, 0x6e, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, + 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x6c, 0x61, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, + 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, + 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9f, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x80, 0x00, 0x10, 0x00, 0x73, 0x75, 0x62, 0x6a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x53, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, + 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x73, 0x6e, 0x62, 0x72, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x80, 0x00, 0x10, 0x00, 0x73, 0x6b, 0x69, 0x64, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0xa3, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, + 0x80, 0x00, 0x10, 0x00, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x03, 0x20, + 0x00, 0x00, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xb2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x51, + 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x5d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x79, + 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xbd, + 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, + 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed, + 0x00, 0x00, 0x02, 0xf1, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x74, 0x65, 0x78, 0x74, 0x20, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x82, 0x01, 0x0a, + 0x02, 0x82, 0x01, 0x01, 0x00, 0xb3, 0xaa, 0xa8, 0x77, 0xe7, 0x3e, 0x2d, 0x0c, 0xf4, 0x83, 0x55, 0xc2, 0x9e, 0x50, 0x10, + 0xc9, 0xef, 0xc8, 0x48, 0x38, 0xe4, 0x43, 0x96, 0xfa, 0x93, 0x32, 0xbf, 0x66, 0xad, 0x84, 0xa2, 0x8b, 0x6b, 0x07, 0x8c, + 0xc6, 0x93, 0x8c, 0x4d, 0x65, 0x0f, 0xad, 0x76, 0x73, 0x0c, 0x4d, 0x43, 0xee, 0x35, 0xd4, 0x68, 0x4a, 0x9a, 0x6d, 0x4d, + 0xa5, 0xae, 0x66, 0xcf, 0xfb, 0xbb, 0x93, 0xd3, 0x6a, 0xe3, 0xfc, 0x41, 0x97, 0xae, 0x90, 0xc3, 0xd8, 0x83, 0xfb, 0x8d, + 0x67, 0x84, 0xc1, 0xd5, 0x7d, 0x1d, 0x12, 0xca, 0x0c, 0xb5, 0xae, 0xf0, 0xe3, 0x36, 0x39, 0xf1, 0x68, 0x92, 0x6f, 0xda, + 0x2d, 0x48, 0x87, 0xf0, 0x4b, 0x15, 0x4e, 0x4f, 0x7a, 0x3a, 0x16, 0xb9, 0x02, 0x89, 0x95, 0x98, 0xab, 0xb2, 0x58, 0x5b, + 0x31, 0x7f, 0x49, 0x90, 0x48, 0xfd, 0x8d, 0x8a, 0x37, 0x3a, 0x4e, 0xd8, 0x00, 0x4a, 0xdc, 0xd4, 0x02, 0x9f, 0xcd, 0x4b, + 0xde, 0x75, 0x4a, 0xb2, 0x27, 0x8e, 0xe6, 0x2d, 0xea, 0x35, 0x89, 0x85, 0x8a, 0x37, 0x59, 0xd6, 0xd1, 0xf8, 0x36, 0x7c, + 0x93, 0x9e, 0xd6, 0xd1, 0xc3, 0xd9, 0x75, 0xa4, 0x4f, 0x40, 0x24, 0xe9, 0xc0, 0xde, 0xeb, 0xc0, 0x5e, 0xd6, 0x04, 0xe1, + 0xd0, 0x07, 0x29, 0xc1, 0x9d, 0x6f, 0x78, 0x2d, 0x5a, 0xef, 0xe6, 0xff, 0x25, 0x16, 0xcf, 0x60, 0x77, 0xa2, 0x10, 0x2b, + 0xa4, 0x2a, 0xff, 0x74, 0x3b, 0xe6, 0x4d, 0xc1, 0x13, 0xba, 0x8b, 0xe8, 0x15, 0x8e, 0xc7, 0xc3, 0xd4, 0x31, 0xb0, 0x99, + 0x51, 0x32, 0x30, 0x03, 0x0b, 0x1c, 0xa0, 0x0a, 0x17, 0x15, 0x34, 0x57, 0x38, 0xd3, 0x08, 0x13, 0xc4, 0xd6, 0x7c, 0x24, + 0x16, 0xd0, 0x2f, 0x00, 0x88, 0xd7, 0xd9, 0xca, 0x1e, 0x6b, 0x50, 0x3b, 0x5f, 0xb6, 0x08, 0xb1, 0x29, 0x42, 0x70, 0xf1, + 0x89, 0x02, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, + 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, + 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, + 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x51, + 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x5d, 0x00, 0x00, 0x02, 0x61, 0x00, 0x00, 0x02, 0x79, + 0x00, 0x00, 0x02, 0x7d, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5, + 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, + 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed, + 0x00, 0x00, 0x02, 0xf1, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0x00, 0x00, 0x02, 0xfd, 0xfa, 0xde, 0x07, 0x11, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x74, 0x65, 0x78, + 0x74, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x48, 0x39, 0x92, 0x01, 0x00, 0x00, 0x00, + 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb6, 0x07, 0xac, 0x5c, 0xc6, 0xcb, 0xf0, 0xb7, 0x97, 0x0d, 0x43, + 0x1a, 0xe9, 0x61, 0xe7, 0x34, 0x63, 0x6a, 0x26, 0x0d, 0x77, 0xba, 0x25, 0xaa, 0xc8, 0x46, 0xf8, 0xc9, 0xdd, 0x21, 0xb4, + 0x3e, 0x2e, 0x11, 0x8e, 0xb6, 0x72, 0xf2, 0x01, 0x16, 0x07, 0xcf, 0x88, 0x91, 0xc4, 0xc0, 0x48, 0x64, 0x41, 0x91, 0xf7, + 0x63, 0x72, 0xd5, 0x37, 0xef, 0x37, 0x62, 0xed, 0x33, 0xb3, 0xf9, 0x6e, 0x31, 0xd1, 0x68, 0xe7, 0xde, 0x62, 0x9f, 0x82, + 0xb8, 0x9e, 0x11, 0xe7, 0x66, 0x91, 0xc1, 0xbe, 0xe5, 0x5c, 0xd6, 0x71, 0x83, 0x91, 0xbc, 0x0f, 0xa8, 0x06, 0xc3, 0xe9, + 0xb6, 0x76, 0x16, 0xae, 0x69, 0x0a, 0x47, 0xe4, 0x65, 0xaa, 0x13, 0x71, 0x48, 0xb3, 0x5c, 0x25, 0xa5, 0x1a, 0xd0, 0x2a, + 0x57, 0x57, 0xf9, 0xb7, 0x13, 0xbd, 0xf4, 0x13, 0x5a, 0x11, 0x1b, 0xcc, 0xd8, 0x9a, 0x5f, 0x82, 0x3f, 0xa7, 0x6b, 0x64, + 0x47, 0x54, 0xb6, 0x81, 0xaf, 0xcb, 0x4b, 0x94, 0x39, 0x65, 0x15, 0xba, 0x6a, 0x02, 0x7c, 0x71, 0x30, 0x60, 0x21, 0x12, + 0x63, 0x28, 0xe0, 0x85, 0xca, 0xcc, 0x07, 0xb1, 0x13, 0x40, 0x19, 0x72, 0x02, 0x35, 0x0e, 0x2d, 0x4b, 0x8a, 0xcd, 0x1d, + 0x09, 0x65, 0xb0, 0x81, 0x49, 0xea, 0x70, 0x15, 0x92, 0x19, 0x7b, 0xfe, 0x15, 0xf7, 0x4a, 0x3f, 0x1e, 0x3c, 0x63, 0x7a, + 0x0f, 0x17, 0x32, 0x1a, 0xb7, 0x26, 0xa1, 0xa0, 0x9b, 0x3f, 0x4e, 0x7c, 0x38, 0xe6, 0x27, 0xbf, 0xa8, 0x1b, 0xf7, 0xbd, + 0x2d, 0xfd, 0x9b, 0x05, 0x0c, 0xaa, 0x81, 0xb8, 0x09, 0xd4, 0xe2, 0xe3, 0xbd, 0x6c, 0x70, 0xc0, 0x7e, 0x95, 0xd4, 0x0b, + 0x13, 0xab, 0xb8, 0xdd, 0x3d, 0x4c, 0x59, 0xf0, 0xc7, 0x8e, 0x47, 0xb5, 0xd8, 0x31, 0x78, 0x80, 0xd2, 0x5f, 0x0c, 0x0b, + 0xae, 0x22, 0xe7, 0x9e, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, + 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, + 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, + 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xb0, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x06, 0x54, 0x00, 0x00, 0x07, 0x78, 0x00, 0x00, 0x07, 0xd8, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x48, + 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0xb8, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00, 0x09, 0x28, 0x00, 0x00, 0x09, 0x60, + 0x00, 0x00, 0x09, 0x98, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x98, + 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, + 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, + 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, + 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, + 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, + 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, + 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x07, 0xa0, 0x00, 0x00, 0x07, 0xbc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, + 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, + 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x38, 0x00, 0x00, 0x08, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xa8, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x08, 0xe0, 0x00, 0x00, 0x08, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x18, + 0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x50, 0x00, 0x00, 0x09, 0x58, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x88, 0x00, 0x00, 0x09, 0x90, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0xc0, 0x00, 0x00, 0x09, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14, 0xa8, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x10, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x06, 0xc4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, + 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x06, 0x15, 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x06, 0x1d, 0x00, 0x00, 0x06, 0x21, + 0x00, 0x00, 0x06, 0x25, 0x00, 0x00, 0x06, 0x3d, 0x00, 0x00, 0x06, 0x41, 0x00, 0x00, 0x06, 0x6d, 0x00, 0x00, 0x06, 0x71, + 0x00, 0x00, 0x06, 0x75, 0x00, 0x00, 0x06, 0x79, 0x00, 0x00, 0x06, 0x85, 0x00, 0x00, 0x06, 0x91, 0x00, 0x00, 0x06, 0x95, + 0x00, 0x00, 0x06, 0x99, 0x00, 0x00, 0x06, 0x9d, 0x00, 0x00, 0x06, 0xa1, 0x00, 0x00, 0x06, 0xa5, 0x00, 0x00, 0x06, 0xa9, + 0x00, 0x00, 0x06, 0xad, 0x00, 0x00, 0x06, 0xb1, 0x00, 0x00, 0x06, 0xb5, 0x00, 0x00, 0x06, 0xb9, 0x00, 0x00, 0x06, 0xbd, + 0x00, 0x00, 0x06, 0xc1, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x05, 0x7c, + 0xce, 0x5e, 0x64, 0x56, 0xc9, 0x2c, 0x8c, 0xbb, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, + 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, + 0x39, 0xf9, 0x47, 0x1e, 0xec, 0x0d, 0xb8, 0x07, 0x55, 0xbc, 0xbf, 0x6e, 0xd7, 0xa7, 0xc4, 0x53, 0x73, 0x06, 0xa9, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0xc0, 0x79, 0x0d, 0x4e, 0xd3, 0x15, 0x14, 0x9a, 0x46, 0xeb, 0x6d, + 0x81, 0xe0, 0xa8, 0x43, 0x02, 0x74, 0x53, 0x4b, 0x3a, 0x23, 0xf7, 0x6d, 0x16, 0x6f, 0x5d, 0x5a, 0xa9, 0x97, 0x54, 0x37, + 0xd0, 0x44, 0xd1, 0x9c, 0x15, 0x33, 0x05, 0xdb, 0x6b, 0xcb, 0x5c, 0xcd, 0x23, 0xc9, 0x65, 0x07, 0x79, 0x1b, 0x60, 0x2d, + 0xd6, 0x17, 0x2b, 0x45, 0x20, 0x8f, 0xb6, 0x31, 0x91, 0xc0, 0x59, 0x53, 0x87, 0xa0, 0x3c, 0xd1, 0x77, 0x97, 0x91, 0xd8, + 0x9c, 0xfc, 0x51, 0x4f, 0xfd, 0x21, 0x6a, 0x71, 0x12, 0x5a, 0x6e, 0x10, 0xd1, 0x5c, 0xe9, 0x7e, 0x24, 0xb8, 0xf3, 0x5d, + 0xab, 0x51, 0x2f, 0x67, 0xa7, 0x65, 0x5c, 0x27, 0xb8, 0xe2, 0x06, 0x98, 0xd2, 0x57, 0xb8, 0xc7, 0x4e, 0xea, 0x28, 0x23, + 0x6e, 0x90, 0x25, 0x2e, 0xb6, 0xf3, 0x5c, 0x18, 0xe8, 0x94, 0xa5, 0x7c, 0x55, 0xbf, 0x22, 0x94, 0xfc, 0x0e, 0xe7, 0x15, + 0xde, 0xe3, 0x72, 0x80, 0xe7, 0xf1, 0xfd, 0xd4, 0x0e, 0x2a, 0xda, 0x53, 0x56, 0xcb, 0xdb, 0xe3, 0x71, 0xc7, 0xc5, 0xd7, + 0x35, 0x95, 0x39, 0xf8, 0xee, 0x16, 0x22, 0x3c, 0x19, 0x3e, 0xd4, 0x03, 0x49, 0xe7, 0xf6, 0xb9, 0x50, 0x9f, 0x18, 0xee, + 0xdf, 0x7b, 0x79, 0xc4, 0x3f, 0xd4, 0x41, 0x45, 0xf2, 0xea, 0xdd, 0x5f, 0xda, 0x17, 0xd3, 0xb0, 0x50, 0xfc, 0x2c, 0xe9, + 0x6a, 0xb6, 0x35, 0xf3, 0xd7, 0xfd, 0xe6, 0x62, 0x51, 0x16, 0x5c, 0x8d, 0x26, 0xc3, 0x18, 0x9c, 0xf0, 0xb9, 0xe5, 0xa9, + 0x46, 0xd9, 0xe3, 0x80, 0x6c, 0xe3, 0x66, 0x70, 0xed, 0x4e, 0xfd, 0xf9, 0x8b, 0xdb, 0x06, 0x56, 0x3f, 0x2d, 0xfe, 0x74, + 0xee, 0x66, 0x75, 0x2a, 0xad, 0x1e, 0x41, 0x6c, 0x1b, 0x6a, 0xe4, 0x90, 0x76, 0x48, 0x27, 0x73, 0x4b, 0x13, 0xda, 0x72, + 0xa6, 0x7f, 0xc2, 0x7c, 0xb5, 0xca, 0x4c, 0x15, 0x64, 0x27, 0x9e, 0xc4, 0x9e, 0x3a, 0xb4, 0x13, 0x9d, 0xb8, 0x02, 0x3f, + 0x92, 0x6c, 0xe5, 0x73, 0x3e, 0x61, 0xbb, 0x01, 0xec, 0x81, 0x9b, 0x64, 0x59, 0x11, 0x4e, 0x42, 0x8b, 0x31, 0x97, 0x16, + 0x18, 0x53, 0x98, 0x82, 0x6e, 0xa5, 0x44, 0x7f, 0xcf, 0x05, 0x9c, 0x2c, 0x9d, 0x8f, 0xe3, 0x45, 0x57, 0xb2, 0xb5, 0x7a, + 0x71, 0x62, 0x25, 0x41, 0x8b, 0xed, 0xe9, 0x08, 0x46, 0x44, 0xda, 0xe3, 0xa3, 0xdf, 0x4b, 0x66, 0x77, 0x19, 0xc2, 0x4f, + 0xbb, 0xa7, 0xde, 0x4b, 0xa0, 0xbd, 0x95, 0x0f, 0xe1, 0x10, 0x49, 0x13, 0xa3, 0xec, 0x80, 0x27, 0xbb, 0x8b, 0xc8, 0xed, + 0x7a, 0x3a, 0x70, 0x5d, 0xea, 0x93, 0x6c, 0x0c, 0xc7, 0x2f, 0x41, 0x15, 0x64, 0x3d, 0x3a, 0x65, 0x02, 0x72, 0x78, 0xc9, + 0x35, 0x61, 0xe8, 0xd9, 0x63, 0x3f, 0x45, 0x7f, 0x04, 0xaf, 0x0b, 0x37, 0x7a, 0x66, 0x4e, 0x49, 0x3d, 0x6c, 0x3d, 0x2a, + 0xda, 0x0b, 0x81, 0x6d, 0x9f, 0x51, 0xea, 0xf6, 0x23, 0x6d, 0x7f, 0xcb, 0x75, 0x02, 0x49, 0x5e, 0x69, 0x57, 0x5b, 0x14, + 0xcb, 0xc2, 0xc8, 0xd4, 0xe4, 0x68, 0xab, 0xec, 0x51, 0x19, 0x80, 0xe4, 0xc1, 0xc7, 0x9b, 0x99, 0x15, 0xe1, 0x25, 0xf9, + 0x58, 0x18, 0x45, 0x0c, 0xde, 0xa7, 0x14, 0xe6, 0x96, 0xd5, 0xb8, 0x36, 0x83, 0x35, 0xfe, 0x77, 0x51, 0x4a, 0x57, 0x2e, + 0xaa, 0x26, 0x13, 0x23, 0x5d, 0x7d, 0xcf, 0x93, 0xce, 0x4a, 0x9a, 0xff, 0x03, 0x48, 0xf7, 0x10, 0x09, 0xe2, 0x01, 0xbb, + 0x17, 0xb6, 0x9d, 0xc7, 0x27, 0xe2, 0xd1, 0x26, 0xf1, 0x7c, 0xd0, 0x53, 0xf6, 0x53, 0x76, 0xfd, 0x39, 0x58, 0xd2, 0xc8, + 0xa8, 0x90, 0xa9, 0x75, 0x16, 0xaf, 0xe2, 0x91, 0x40, 0x53, 0x2e, 0x08, 0xdd, 0xb9, 0xfb, 0x17, 0x51, 0x51, 0x1b, 0xb9, + 0x12, 0xf0, 0x31, 0xd8, 0x48, 0x8f, 0x7d, 0x08, 0x9d, 0x1d, 0x2a, 0xb5, 0xcd, 0x46, 0x23, 0x2c, 0xf3, 0xb5, 0x11, 0x91, + 0x7f, 0x3c, 0x7a, 0x5e, 0x75, 0x90, 0x0e, 0xc0, 0xc0, 0x4f, 0x5e, 0xcb, 0xbc, 0x33, 0x09, 0x88, 0x4e, 0x68, 0xac, 0xba, + 0x46, 0x31, 0x41, 0x98, 0xf5, 0x75, 0x87, 0xf6, 0x0c, 0x0c, 0xaa, 0x84, 0x75, 0xe4, 0xfa, 0xa3, 0x1e, 0xe1, 0xe2, 0x88, + 0x09, 0xf0, 0x57, 0x8b, 0xdc, 0x47, 0x7b, 0xff, 0x39, 0xac, 0x51, 0x8b, 0x00, 0x08, 0xc0, 0x9f, 0xd4, 0xa4, 0xbe, 0xe5, + 0x41, 0x8b, 0xc5, 0x66, 0xdb, 0xed, 0x08, 0x0b, 0xdf, 0xa4, 0x2b, 0x5a, 0x59, 0xde, 0x0e, 0x9c, 0x8b, 0x7f, 0xd1, 0x80, + 0x4d, 0xf9, 0x22, 0x60, 0x2c, 0xd4, 0xf9, 0x1c, 0xd7, 0xf5, 0xbd, 0x64, 0x7f, 0x4f, 0xeb, 0xf8, 0xa5, 0xb2, 0x34, 0x3d, + 0xfa, 0x07, 0xef, 0x44, 0x3c, 0x00, 0x2c, 0xec, 0x36, 0x36, 0xdd, 0xd5, 0x5c, 0xbd, 0x6b, 0x27, 0xba, 0x13, 0x91, 0x90, + 0x58, 0xe7, 0x75, 0x89, 0x00, 0x6b, 0x5a, 0x0c, 0x35, 0x9c, 0xe3, 0x8a, 0xd8, 0x46, 0xd2, 0x15, 0x14, 0x8b, 0x8b, 0xff, + 0x6a, 0x35, 0xf9, 0xd7, 0x65, 0x67, 0x56, 0x6d, 0xd5, 0x2d, 0x9c, 0xd6, 0xb1, 0xe2, 0x9a, 0xb0, 0xfa, 0x0e, 0xa2, 0xd5, + 0x5d, 0x30, 0x15, 0x8e, 0x48, 0x59, 0xd0, 0x13, 0xa7, 0x2b, 0x40, 0x97, 0x8c, 0xe4, 0x02, 0x38, 0x28, 0x54, 0x53, 0x6c, + 0x1c, 0xc7, 0x38, 0x06, 0xe9, 0xfc, 0x2d, 0xd5, 0x59, 0x74, 0x77, 0x62, 0x14, 0xf2, 0xa7, 0x7e, 0xfe, 0x59, 0xbf, 0xdf, + 0x8b, 0x6e, 0xd7, 0x66, 0xd1, 0x6a, 0xb9, 0xe6, 0x35, 0x98, 0xc6, 0x76, 0x44, 0x38, 0xb4, 0xe8, 0x3c, 0xf5, 0x3c, 0x27, + 0xb9, 0xa1, 0x21, 0x7d, 0x17, 0xf9, 0xb3, 0x1e, 0x30, 0xe7, 0xab, 0xd5, 0x2d, 0x8c, 0x02, 0xc3, 0xa4, 0x3c, 0xf4, 0x09, + 0x9f, 0x17, 0xc1, 0xce, 0xc9, 0xf5, 0xdf, 0xdb, 0x8b, 0xf5, 0x05, 0x14, 0x6d, 0x74, 0xdf, 0xa9, 0x0b, 0x87, 0x98, 0x17, + 0xf3, 0x68, 0x8d, 0xb3, 0xbc, 0x86, 0x3a, 0x47, 0x1d, 0x29, 0x80, 0x40, 0xba, 0xb0, 0x3d, 0x65, 0x0d, 0xd7, 0x95, 0x4a, + 0x79, 0x0d, 0x34, 0x20, 0x72, 0x25, 0xaa, 0x71, 0x43, 0x5c, 0x52, 0x0b, 0x69, 0xde, 0xf7, 0xc5, 0xfd, 0xdb, 0x41, 0x05, + 0xb1, 0xde, 0x94, 0xdb, 0xc4, 0xe4, 0x85, 0xf2, 0x6c, 0xc5, 0xd1, 0x04, 0xcd, 0xd7, 0x84, 0x0b, 0xd8, 0xa8, 0x2c, 0x68, + 0xfd, 0xe7, 0x30, 0xaf, 0x6e, 0xae, 0x02, 0x3f, 0xea, 0x13, 0x68, 0xb0, 0xd1, 0xef, 0x6d, 0x78, 0xf8, 0x77, 0x3e, 0xe8, + 0x03, 0x05, 0x6e, 0x00, 0x59, 0xf1, 0xde, 0x57, 0xbe, 0xfa, 0x6b, 0xde, 0x47, 0x86, 0x21, 0xa0, 0x8e, 0xcc, 0x0b, 0x15, + 0x7e, 0x7d, 0xd2, 0x59, 0x37, 0x7f, 0x74, 0xc5, 0x79, 0x8e, 0xf0, 0x37, 0x9b, 0xb3, 0x0e, 0x7f, 0x14, 0x91, 0x0e, 0xe5, + 0xe8, 0xdf, 0xf7, 0xdf, 0x6b, 0x59, 0x79, 0x37, 0x90, 0x99, 0xc8, 0xff, 0xb2, 0xe9, 0xe4, 0x35, 0x8c, 0x20, 0xde, 0x8c, + 0x6c, 0xb8, 0x87, 0x16, 0xdd, 0xc4, 0x4b, 0x5e, 0x93, 0x38, 0x06, 0x0f, 0x4a, 0xb0, 0xba, 0xe1, 0xc5, 0xb1, 0x5d, 0x5f, + 0x3a, 0x2e, 0x84, 0x56, 0x72, 0x13, 0xb2, 0xb4, 0xdf, 0xc0, 0x36, 0xe6, 0xf2, 0xee, 0x77, 0x93, 0xc1, 0xc7, 0xc5, 0xe5, + 0x58, 0x66, 0x3e, 0x8c, 0x5d, 0xe3, 0x5d, 0xbd, 0x43, 0xf6, 0x72, 0x51, 0xe7, 0x4c, 0xd4, 0x2f, 0x46, 0x12, 0x66, 0xc2, + 0x7a, 0xd4, 0xd9, 0x75, 0x25, 0xa5, 0x63, 0x60, 0x9c, 0xc4, 0xff, 0x0a, 0xec, 0x8d, 0x13, 0x22, 0x3e, 0x95, 0xe8, 0xd9, + 0xd4, 0xa4, 0x12, 0xba, 0x46, 0x93, 0x1f, 0x6b, 0x9f, 0xb2, 0xba, 0xca, 0x39, 0xda, 0x32, 0xe5, 0x5c, 0xb3, 0x86, 0xc9, + 0x86, 0xb9, 0x9c, 0x92, 0x72, 0xe4, 0xa7, 0x53, 0xe4, 0x39, 0x07, 0x96, 0xc6, 0x18, 0xbc, 0xfc, 0x2e, 0x5f, 0xd6, 0x15, + 0x2c, 0x73, 0x01, 0x05, 0x74, 0xd7, 0x9a, 0x34, 0x35, 0x56, 0x32, 0xb7, 0x50, 0x22, 0x76, 0x66, 0x4d, 0x6f, 0xd1, 0x19, + 0x6a, 0x79, 0xc1, 0x3f, 0x15, 0x21, 0x04, 0x14, 0x34, 0xc9, 0x9a, 0xdb, 0x25, 0x0d, 0xfb, 0xa9, 0x53, 0xc0, 0x5f, 0xac, + 0xb7, 0xec, 0x67, 0xac, 0x8e, 0x46, 0x4c, 0xd7, 0x1b, 0x9b, 0x25, 0x87, 0x97, 0x73, 0xd9, 0xc8, 0xb3, 0x65, 0x22, 0x3b, + 0x35, 0xc0, 0x2f, 0xf5, 0x7d, 0xa4, 0x9b, 0x79, 0x92, 0xfb, 0xb6, 0x0b, 0xc9, 0xf9, 0x88, 0xc5, 0x5b, 0x88, 0x21, 0x0d, + 0xcf, 0xd9, 0x83, 0x6d, 0xae, 0x58, 0x3f, 0xac, 0x88, 0x16, 0xae, 0x3f, 0xb5, 0xdb, 0x78, 0x1c, 0x03, 0x3a, 0x19, 0xf1, + 0xbe, 0xc6, 0x46, 0x12, 0x6b, 0x18, 0x0b, 0x70, 0x83, 0x2d, 0x2f, 0x16, 0xac, 0xa9, 0x31, 0x2d, 0xf3, 0xe5, 0xd7, 0xe1, + 0x0e, 0x0e, 0x23, 0xb3, 0x9e, 0xc5, 0x6e, 0x35, 0xb7, 0xc4, 0x7f, 0xac, 0x60, 0x92, 0xde, 0x73, 0x3b, 0x02, 0xb6, 0xf5, + 0x97, 0xe6, 0xe1, 0x55, 0x50, 0x72, 0xd2, 0xb4, 0xbd, 0xcd, 0x7e, 0x11, 0xe4, 0x7b, 0x4b, 0xa5, 0x6b, 0x7e, 0xbf, 0xb8, + 0x4a, 0x1f, 0xf6, 0x34, 0x29, 0xee, 0x28, 0xb0, 0x45, 0x7d, 0x48, 0xc2, 0x18, 0xb2, 0x15, 0x0c, 0xe5, 0x5a, 0x3e, 0xee, + 0xdd, 0x1f, 0x20, 0x7b, 0xe6, 0x79, 0x60, 0xee, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, + 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, + 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, + 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x08, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x49, 0x00, 0x00, 0x09, 0x4d, 0x00, 0x00, 0x09, 0x61, + 0x00, 0x00, 0x09, 0x65, 0x00, 0x00, 0x09, 0x69, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x00, 0x09, 0x71, 0x00, 0x00, 0x09, 0x89, + 0x00, 0x00, 0x09, 0x8d, 0x00, 0x00, 0x09, 0xb9, 0x00, 0x00, 0x09, 0xbd, 0x00, 0x00, 0x09, 0xc1, 0x00, 0x00, 0x09, 0xc5, + 0x00, 0x00, 0x09, 0xd1, 0x00, 0x00, 0x09, 0xdd, 0x00, 0x00, 0x09, 0xe1, 0x00, 0x00, 0x09, 0xe5, 0x00, 0x00, 0x09, 0xe9, + 0x00, 0x00, 0x09, 0xed, 0x00, 0x00, 0x09, 0xf1, 0x00, 0x00, 0x09, 0xf5, 0x00, 0x00, 0x09, 0xf9, 0x00, 0x00, 0x09, 0xfd, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x09, 0x00, 0x00, 0x0a, 0x0d, 0xfa, 0xde, 0x07, 0x11, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x08, 0xc4, 0x7a, 0x50, 0x55, 0x75, 0xed, 0x3d, 0xfc, 0x68, + 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0xb4, 0x4e, 0xa3, 0xa8, 0x86, 0x4f, 0x76, 0xe9, + 0x0f, 0x06, 0x2d, 0xca, 0x91, 0x26, 0x8e, 0x86, 0x1a, 0x1f, 0xb9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, + 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0xf7, 0xc4, 0x67, 0x03, 0x4c, 0xab, 0x35, 0xae, + 0x20, 0x64, 0x45, 0xf0, 0xe3, 0x48, 0xbc, 0xba, 0x5f, 0xac, 0x81, 0xda, 0x00, 0x00, 0x00, 0x74, 0x2f, 0x53, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x43, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x73, 0x73, + 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, + 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, + 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x14, 0xf7, 0xc4, 0x67, 0x03, 0x4c, 0xab, 0x35, 0xae, 0x20, 0x64, 0x45, 0xf0, 0xe3, 0x48, 0xbc, 0xba, + 0x5f, 0xac, 0x81, 0xda, 0x00, 0x00, 0x00, 0x74, 0x2f, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x4c, 0x69, 0x62, 0x72, + 0x61, 0x72, 0x79, 0x2f, 0x43, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2e, 0x61, + 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x10, 0x49, 0xe1, 0x42, + 0x39, 0xee, 0xe2, 0xbd, 0x76, 0x61, 0x00, 0x6f, 0xe5, 0xf4, 0xbe, 0xdb, 0xbc, 0x89, 0xbe, 0x56, 0x00, 0x00, 0x00, 0x44, + 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x4d, 0x61, 0x69, 0x6c, 0x2e, 0x61, + 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x61, + 0x69, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, + 0x55, 0x29, 0x46, 0xa2, 0xfb, 0x92, 0xda, 0xe4, 0xf8, 0x4c, 0x7d, 0xdd, 0xc3, 0x4e, 0x52, 0x62, 0xff, 0x0f, 0xd2, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x62, 0x69, 0x6e, 0x2f, 0x72, 0x61, 0x63, 0x6f, 0x6f, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x72, 0x61, + 0x63, 0x6f, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x5c, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1d, + 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, + 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x5f, 0xda, 0x57, 0x4e, 0xc0, 0xb5, 0x32, 0xdf, 0xc4, 0x87, 0x7f, 0x8c, 0x04, 0x1f, 0x65, 0xa2, 0x23, 0x20, 0x8c, + 0xab, 0x49, 0x2f, 0xff, 0x12, 0xfa, 0x57, 0x33, 0xf8, 0xcb, 0x7a, 0xcd, 0xc4, 0x7b, 0xc0, 0xf6, 0xf7, 0xe7, 0x2f, 0x7d, + 0x3f, 0xec, 0xf5, 0x8a, 0xee, 0x1e, 0x26, 0xe9, 0x12, 0x96, 0xdb, 0xa2, 0x2a, 0xf6, 0xb9, 0x3c, 0x68, 0x14, 0x49, 0x86, + 0x00, 0xc0, 0xaa, 0x29, 0xd3, 0xad, 0x4b, 0x48, 0xca, 0x48, 0x3f, 0xdb, 0x36, 0xdd, 0x3d, 0x3b, 0x18, 0x59, 0x26, 0x2a, + 0x9e, 0x5f, 0x86, 0xe9, 0x4b, 0xaa, 0x83, 0x60, 0x20, 0x36, 0x1e, 0x59, 0x17, 0x33, 0x5b, 0x20, 0x42, 0x7a, 0x59, 0xfd, + 0xb3, 0xa2, 0x5f, 0x2b, 0xdb, 0x63, 0x7e, 0x66, 0xee, 0x5e, 0xf5, 0x22, 0x0c, 0x10, 0x61, 0xd3, 0x9e, 0x3d, 0xce, 0x62, + 0x6b, 0xc3, 0x97, 0x86, 0x68, 0x61, 0x2a, 0x31, 0xaa, 0x7d, 0x5d, 0x18, 0x1f, 0xe9, 0xc3, 0x12, 0xb7, 0x0d, 0x14, 0x84, + 0x5c, 0xa0, 0x84, 0x0c, 0x07, 0xef, 0x01, 0xf4, 0xd3, 0xa1, 0x14, 0xa8, 0x5a, 0xb8, 0x15, 0xb7, 0x1b, 0x7a, 0x4a, 0x12, + 0x2f, 0x9d, 0x8f, 0x79, 0xb1, 0x74, 0x3e, 0x50, 0xd5, 0x99, 0x9c, 0x26, 0x7d, 0x37, 0xaf, 0xc7, 0x7b, 0x15, 0x8c, 0x07, + 0xae, 0x74, 0xef, 0xc3, 0xb1, 0x6a, 0xa2, 0x76, 0xf9, 0x6d, 0x6e, 0xc2, 0x6a, 0x01, 0x9a, 0x5f, 0x23, 0xf4, 0xd5, 0xe3, + 0x6a, 0x34, 0x86, 0x1e, 0x9d, 0xed, 0x5c, 0x09, 0xd3, 0xba, 0xff, 0x2d, 0xbe, 0x4b, 0xbb, 0x6c, 0x6a, 0x20, 0xc9, 0x8b, + 0x51, 0xcd, 0x4c, 0x91, 0x51, 0x6d, 0xf5, 0x80, 0x42, 0x31, 0xc1, 0x3a, 0x10, 0xdc, 0xb4, 0x92, 0x97, 0x18, 0xcc, 0x26, + 0xf1, 0xe6, 0x18, 0xe1, 0x97, 0x21, 0x94, 0x3d, 0xca, 0xa7, 0xb5, 0xcd, 0xce, 0x53, 0x7b, 0x16, 0x0b, 0x80, 0x8d, 0x4c, + 0xc8, 0x28, 0xc8, 0x55, 0xcf, 0xc7, 0xba, 0xd1, 0x05, 0x6a, 0x66, 0x72, 0x51, 0xb2, 0xd4, 0x3d, 0x81, 0x8d, 0xc5, 0xb3, + 0x86, 0xa6, 0x02, 0x53, 0x16, 0x2a, 0x2a, 0x40, 0xf1, 0x8d, 0xff, 0x42, 0x9a, 0x12, 0xd2, 0x46, 0x1d, 0x42, 0x98, 0x1f, + 0x1c, 0x52, 0x3f, 0x11, 0xa7, 0x12, 0xa7, 0xba, 0xb7, 0x84, 0xba, 0x80, 0xdf, 0x3e, 0x89, 0xcd, 0x81, 0x05, 0x98, 0x0a, + 0x92, 0x3e, 0x4b, 0x61, 0x44, 0x2f, 0xb8, 0xfe, 0x86, 0x56, 0x6b, 0xe1, 0xc0, 0xb4, 0x09, 0x52, 0x6c, 0xb2, 0xff, 0x1f, + 0xe7, 0x74, 0x98, 0xb6, 0x65, 0x47, 0x31, 0x5a, 0x33, 0x3a, 0x8c, 0x05, 0x18, 0xa5, 0x25, 0xc6, 0xb7, 0x18, 0x29, 0xf9, + 0x87, 0x7c, 0x3c, 0x3d, 0x70, 0x56, 0x60, 0xfe, 0x0c, 0xb9, 0x17, 0x89, 0xa0, 0x72, 0xe6, 0xa5, 0x2f, 0xa6, 0xa9, 0xc4, + 0x34, 0x5a, 0xbe, 0x0d, 0xa5, 0xf3, 0xac, 0xe8, 0x69, 0xa8, 0x2e, 0x50, 0xa2, 0xc1, 0x99, 0x7e, 0x7c, 0xd2, 0xd7, 0x60, + 0x1b, 0x41, 0xe4, 0x1f, 0x76, 0x5c, 0xeb, 0x1b, 0x28, 0x53, 0xd3, 0xab, 0x48, 0xd0, 0x7f, 0xb8, 0x9d, 0x70, 0x39, 0x8a, + 0xcd, 0x3c, 0x0f, 0x03, 0x5e, 0xe8, 0xa9, 0x95, 0x60, 0x54, 0x93, 0xfa, 0xd1, 0x9b, 0x49, 0xdb, 0x34, 0x32, 0x36, 0x38, + 0x56, 0xbb, 0xbf, 0xcf, 0x54, 0xe6, 0x5c, 0xa2, 0x8a, 0x9e, 0x73, 0x83, 0xa0, 0x53, 0x71, 0xfd, 0xef, 0x49, 0x1a, 0xa7, + 0x06, 0xca, 0x90, 0xd5, 0x2f, 0x31, 0xb4, 0x52, 0x0f, 0xaf, 0xfe, 0x6c, 0x19, 0x6d, 0xca, 0x11, 0xaa, 0xaf, 0x24, 0x21, + 0x47, 0x7f, 0x15, 0x47, 0x51, 0x96, 0x59, 0x3b, 0x27, 0x13, 0xc6, 0x50, 0x7b, 0x1c, 0x84, 0x0d, 0x61, 0x3d, 0x51, 0x58, + 0x9c, 0xe4, 0x65, 0x06, 0x1f, 0x7b, 0x91, 0x98, 0x7d, 0x35, 0x8c, 0x9f, 0xba, 0x38, 0x90, 0x89, 0xa2, 0xae, 0x68, 0x68, + 0x4b, 0x11, 0x2f, 0xea, 0x4d, 0xcb, 0x01, 0x59, 0x94, 0x26, 0x52, 0x37, 0x01, 0x6e, 0xfb, 0x01, 0x8b, 0x61, 0x59, 0x5b, + 0x49, 0xdf, 0xf2, 0x1c, 0x48, 0xbc, 0xed, 0x98, 0x8f, 0x09, 0x38, 0xa2, 0xf8, 0x27, 0xbb, 0x1a, 0x04, 0xcf, 0xd0, 0x4a, + 0x93, 0x32, 0xb8, 0x9d, 0x2f, 0x9c, 0xf3, 0xb2, 0xa8, 0x56, 0x47, 0xff, 0xa1, 0x28, 0x60, 0x6b, 0xc2, 0x3c, 0x1b, 0x48, + 0x5d, 0xc9, 0x05, 0x39, 0x98, 0xe5, 0x98, 0xfb, 0x17, 0x3f, 0x6d, 0x41, 0x8d, 0xc5, 0xa1, 0xee, 0x31, 0x19, 0x00, 0x2d, + 0xfb, 0x1e, 0x8f, 0x5f, 0x72, 0x6a, 0x92, 0x64, 0x01, 0xad, 0xcc, 0x90, 0x14, 0x48, 0x83, 0x88, 0x2e, 0xc1, 0x58, 0xe5, + 0x33, 0xa4, 0x19, 0xc3, 0x1d, 0xee, 0x06, 0xb6, 0x96, 0xb7, 0x57, 0x04, 0xa5, 0x4a, 0xa0, 0xa5, 0x1b, 0xa5, 0xda, 0x91, + 0xb7, 0x2c, 0xcd, 0x6d, 0x81, 0xff, 0x9f, 0xac, 0xc9, 0x05, 0x26, 0x8f, 0xb2, 0x37, 0x3c, 0xb8, 0x53, 0xab, 0x2b, 0xaf, + 0x9e, 0x22, 0xd2, 0xcd, 0xf4, 0x65, 0xf3, 0x84, 0x68, 0x83, 0xc2, 0xf8, 0xb7, 0x05, 0x25, 0xfe, 0x08, 0x2c, 0xb2, 0xb4, + 0xf3, 0x95, 0x63, 0x9a, 0xcc, 0x9d, 0xb1, 0xee, 0x5c, 0x53, 0x3b, 0x6b, 0xab, 0x0e, 0x95, 0x50, 0xcc, 0x8e, 0xc3, 0x97, + 0x43, 0x67, 0xe5, 0x49, 0xd0, 0x20, 0xbd, 0xda, 0x45, 0x6c, 0xef, 0x9a, 0xc7, 0x47, 0xdc, 0x7f, 0xda, 0xab, 0xf2, 0x8a, + 0xc5, 0x4f, 0xc5, 0xdb, 0xba, 0x87, 0x5f, 0xc1, 0xe0, 0x12, 0xc0, 0xb1, 0x3e, 0x1b, 0x72, 0x34, 0x00, 0x9f, 0x0a, 0xb4, + 0x99, 0xf8, 0x33, 0xe7, 0xb7, 0xc6, 0xc0, 0xed, 0xe6, 0x2c, 0x1b, 0x29, 0x9c, 0xfd, 0xeb, 0x6f, 0x9b, 0x0a, 0x55, 0xd2, + 0x09, 0xa2, 0x64, 0x49, 0x39, 0x30, 0x33, 0xb2, 0x77, 0x31, 0x32, 0x81, 0x25, 0x58, 0x66, 0x4d, 0xd2, 0xc2, 0xa6, 0x18, + 0xdc, 0xfc, 0x0a, 0x73, 0x5f, 0xbc, 0xcc, 0xef, 0xfe, 0xee, 0x1d, 0x3d, 0xb8, 0x21, 0xfb, 0x52, 0x25, 0x6f, 0xc3, 0x99, + 0x67, 0xa1, 0x69, 0x20, 0xb3, 0x01, 0xb4, 0x75, 0xbe, 0x08, 0x49, 0x2e, 0xe3, 0x6f, 0x1a, 0xd0, 0xe9, 0x7c, 0xec, 0xbf, + 0x98, 0x45, 0x82, 0xf8, 0xc4, 0x77, 0x74, 0x20, 0xc9, 0x5f, 0xa1, 0x8b, 0xf4, 0xa8, 0x4d, 0x12, 0xd5, 0x92, 0xd1, 0xe1, + 0x42, 0x4b, 0xa2, 0x45, 0x18, 0x60, 0xaf, 0x9a, 0xf2, 0xe4, 0xcf, 0x3e, 0x66, 0x87, 0x12, 0x0e, 0xa7, 0x55, 0x53, 0x96, + 0xcb, 0xcf, 0xd3, 0x34, 0xab, 0xdd, 0x20, 0x0f, 0x62, 0x9a, 0xb4, 0x86, 0x2f, 0x9f, 0x01, 0xda, 0xd6, 0xe6, 0x2b, 0xe2, + 0x5b, 0xb9, 0x74, 0xd8, 0x28, 0xad, 0x94, 0x89, 0x3e, 0x3a, 0x2a, 0x82, 0xa2, 0x0a, 0x7b, 0x4b, 0x4f, 0x3f, 0xed, 0x7f, + 0x2a, 0x3a, 0x06, 0xc8, 0xd4, 0x65, 0xcd, 0x60, 0x19, 0x79, 0x36, 0x31, 0x4c, 0xc1, 0x1e, 0x55, 0x22, 0x4f, 0x6e, 0xe0, + 0x1b, 0xab, 0x0b, 0x49, 0xa8, 0x9f, 0xf9, 0xc9, 0x6c, 0xd4, 0xd6, 0xfa, 0x07, 0xcd, 0xf5, 0xe7, 0x94, 0x51, 0x1b, 0x3d, + 0xc5, 0x00, 0x79, 0x38, 0xaf, 0xc0, 0x23, 0x60, 0x2b, 0x92, 0xda, 0x76, 0x69, 0xf7, 0xda, 0x23, 0xf9, 0xa6, 0x21, 0x34, + 0xc6, 0xf3, 0xc3, 0x69, 0xa6, 0x25, 0x87, 0x70, 0x5c, 0x0c, 0xc1, 0xfc, 0x9c, 0x30, 0xbc, 0xdf, 0x26, 0xbe, 0x4b, 0x49, + 0x44, 0xdd, 0x2f, 0x21, 0xc1, 0xa8, 0xcd, 0x54, 0x7a, 0xa4, 0x1b, 0xae, 0x82, 0xce, 0x05, 0x50, 0x9c, 0xb6, 0x85, 0x5d, + 0xf9, 0xbd, 0xdd, 0x4a, 0x56, 0x51, 0x32, 0x50, 0xdd, 0xaa, 0x55, 0xfe, 0x26, 0x3c, 0xee, 0x36, 0xa4, 0xa8, 0x53, 0x66, + 0x72, 0x89, 0xf6, 0xa3, 0x25, 0x7a, 0x23, 0x53, 0x29, 0x4d, 0x34, 0x29, 0x62, 0x94, 0x4f, 0x4f, 0x1b, 0x53, 0xcb, 0xc1, + 0x7c, 0xd1, 0x50, 0x8e, 0xa3, 0x19, 0x89, 0xfa, 0x90, 0x42, 0x69, 0x16, 0xd0, 0x6f, 0xf8, 0x7a, 0xc2, 0x9e, 0x67, 0xe8, + 0xe8, 0xff, 0xf1, 0x61, 0x7b, 0x31, 0x19, 0xcf, 0xf1, 0x27, 0xee, 0xab, 0x63, 0xe8, 0xdb, 0xf7, 0x4c, 0xbf, 0xcf, 0x2f, + 0xe7, 0x83, 0x92, 0xf8, 0x6d, 0x15, 0x9e, 0x1d, 0x77, 0xef, 0x40, 0x79, 0x58, 0xe4, 0xf9, 0xa7, 0x3d, 0xb6, 0x2d, 0xd0, + 0xfc, 0x01, 0x66, 0x20, 0x2c, 0xd1, 0x29, 0x86, 0x9b, 0x88, 0xcd, 0x98, 0xb4, 0x66, 0x61, 0x94, 0x58, 0x56, 0xf4, 0xff, + 0x60, 0x90, 0xf2, 0x8c, 0x07, 0x1c, 0x0b, 0x13, 0xfe, 0xb6, 0x58, 0x15, 0x6a, 0x8a, 0xd7, 0x98, 0xb2, 0x3e, 0xee, 0x49, + 0xdb, 0x3a, 0x0f, 0x98, 0x27, 0xc6, 0x88, 0xc5, 0x15, 0xe5, 0x67, 0x08, 0x09, 0xfc, 0x63, 0x6c, 0x8f, 0x30, 0xf4, 0x95, + 0xb7, 0x69, 0xd4, 0x47, 0x93, 0xe5, 0xa6, 0xf9, 0x73, 0xdd, 0x98, 0xb4, 0x66, 0x02, 0x1f, 0x3b, 0xe7, 0x53, 0x9f, 0x54, + 0x44, 0x0b, 0x9b, 0xdb, 0xe8, 0xaa, 0x77, 0xc3, 0x89, 0x65, 0x12, 0xb2, 0xc5, 0x2f, 0x5e, 0xaa, 0xff, 0xab, 0x72, 0x1f, + 0xf1, 0xd3, 0xdc, 0x8f, 0xaf, 0x13, 0x31, 0xaa, 0x5d, 0x48, 0x5a, 0x1b, 0x31, 0x61, 0x0b, 0x48, 0x9b, 0xe6, 0x75, 0x2e, + 0xd5, 0xdb, 0xd3, 0x22, 0xb5, 0x77, 0x9b, 0x45, 0xc2, 0x9d, 0x1b, 0xe2, 0x2b, 0x8c, 0x14, 0x99, 0x10, 0x7c, 0x24, 0x18, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, + 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, + 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, + 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, + 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x03, 0xb0, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x11, 0x2c, 0x00, 0x00, 0x12, 0x50, 0x00, 0x00, 0x12, 0xb0, + 0x00, 0x00, 0x12, 0xe8, 0x00, 0x00, 0x13, 0x20, 0x00, 0x00, 0x13, 0x58, 0x00, 0x00, 0x13, 0x90, 0x00, 0x00, 0x13, 0xc8, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x38, 0x00, 0x00, 0x14, 0x70, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x70, 0x00, 0x00, 0x11, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, + 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, + 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, + 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, + 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, + 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, + 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x12, 0x78, 0x00, 0x00, 0x12, 0x94, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, + 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, + 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x12, 0xd8, 0x00, 0x00, 0x12, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x13, 0x10, 0x00, 0x00, 0x13, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x48, + 0x00, 0x00, 0x13, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x80, 0x00, 0x00, 0x13, 0x88, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0xb8, 0x00, 0x00, 0x13, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0xf0, 0x00, 0x00, 0x13, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x14, 0x28, 0x00, 0x00, 0x14, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x60, + 0x00, 0x00, 0x14, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x98, 0x00, 0x00, 0x14, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1e, 0xbc, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x15, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x02, 0xf8, + 0x00, 0x00, 0x05, 0xe4, 0x00, 0x00, 0x08, 0xa4, 0x00, 0x00, 0x0e, 0xfc, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x11, 0xe4, + 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf5, 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x02, 0x15, + 0x00, 0x00, 0x02, 0x19, 0x00, 0x00, 0x02, 0x1d, 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, + 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x6d, 0x00, 0x00, 0x02, 0x71, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x81, + 0x00, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, + 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, + 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x70, 0xea, 0x6d, 0x4d, 0x2b, 0x42, 0xd6, 0x1d, 0xa7, 0x00, 0x00, 0x00, 0x02, + 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x59, 0x1b, 0x38, 0x6f, 0x83, 0xff, 0xcf, 0x13, 0x00, 0xc5, 0x58, 0x14, + 0x81, 0x60, 0xd5, 0xf2, 0x76, 0x2d, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, + 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xe5, 0x1f, 0x40, 0x4b, 0xde, 0x16, 0xe0, 0x41, + 0xc5, 0xdc, 0x68, 0x83, 0xfb, 0x0f, 0x7b, 0xad, 0x62, 0x9d, 0xa3, 0xee, 0xea, 0xa9, 0x6b, 0x27, 0x69, 0x1e, 0xea, 0xc7, + 0x1c, 0xf7, 0x06, 0xa5, 0x76, 0xcd, 0x9d, 0x65, 0x3c, 0xb1, 0x30, 0x6a, 0x30, 0xd1, 0x31, 0xbd, 0x8a, 0x19, 0x90, 0x89, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, + 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, + 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, + 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, + 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xec, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x25, 0x00, 0x00, 0x02, 0x3d, + 0x00, 0x00, 0x02, 0x41, 0x00, 0x00, 0x02, 0x45, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x65, + 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa1, + 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xc5, + 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, + 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0xfa, 0xde, 0x07, 0x11, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x6c, 0x00, 0x00, 0x01, 0x9c, 0x8b, 0x41, 0x4a, 0x57, 0xa6, 0xf2, 0x36, 0xc2, + 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x9a, 0xfe, 0xce, 0x76, 0xf7, 0x40, 0x3a, 0x9f, + 0xd2, 0xc5, 0x69, 0x65, 0x60, 0xea, 0x1a, 0x98, 0xc7, 0xed, 0x28, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x5a, 0x4c, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, + 0x83, 0x67, 0xc1, 0x00, 0xdf, 0x03, 0x66, 0xb0, 0xbb, 0x20, 0xb3, 0x39, 0x84, 0xf0, 0x07, 0xc3, 0x17, 0x75, 0x8a, 0x1b, + 0xce, 0x2a, 0xb7, 0xc3, 0x31, 0xd7, 0xea, 0xba, 0xa4, 0x38, 0xf5, 0x78, 0x94, 0xa5, 0xff, 0x08, 0x6d, 0x36, 0x41, 0xa5, + 0x8d, 0x6e, 0xf7, 0x55, 0x1f, 0x6f, 0xe9, 0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, + 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, + 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, + 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, + 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf5, + 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x02, 0x15, 0x00, 0x00, 0x02, 0x19, 0x00, 0x00, 0x02, 0x1d, + 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x6d, + 0x00, 0x00, 0x02, 0x71, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x02, 0x91, + 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, + 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, + 0x00, 0x00, 0x02, 0xbd, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x70, + 0x44, 0x1d, 0x55, 0x6f, 0xda, 0x1b, 0x4a, 0x43, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, + 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, + 0x23, 0x07, 0xb7, 0x3f, 0xb3, 0x23, 0xad, 0xb2, 0xa9, 0x7f, 0x10, 0x8b, 0x76, 0x89, 0x68, 0x1b, 0x42, 0xb4, 0x45, 0x98, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, + 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xc5, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x23, 0xe5, 0x14, 0x64, 0x77, 0x35, 0x5f, 0x79, 0x3e, 0x4c, 0x4d, 0x5e, 0xee, 0xa7, 0x26, 0x39, 0x7d, + 0x28, 0x18, 0xd5, 0xf5, 0x08, 0x07, 0x99, 0x37, 0xb1, 0xea, 0x83, 0x7c, 0xbc, 0xeb, 0x64, 0x47, 0xc6, 0xe1, 0x82, 0xfe, + 0x1f, 0x20, 0x67, 0x1e, 0x37, 0x92, 0x57, 0xaa, 0xbe, 0x4f, 0xac, 0x5f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, + 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, + 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5c, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5, + 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, 0x00, 0x00, 0x03, 0x05, + 0x00, 0x00, 0x03, 0x09, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, 0x03, 0x1d, 0x00, 0x00, 0x03, 0x29, + 0x00, 0x00, 0x03, 0x2d, 0x00, 0x00, 0x03, 0x31, 0x00, 0x00, 0x03, 0x35, 0x00, 0x00, 0x03, 0x39, 0x00, 0x00, 0x03, 0x3d, + 0x00, 0x00, 0x03, 0x41, 0x00, 0x00, 0x03, 0x45, 0x00, 0x00, 0x03, 0x49, 0x00, 0x00, 0x03, 0x4d, 0x00, 0x00, 0x03, 0x51, + 0x00, 0x00, 0x03, 0x55, 0x00, 0x00, 0x03, 0x59, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xdc, + 0x00, 0x00, 0x02, 0x0c, 0x52, 0x60, 0x55, 0x9c, 0x4a, 0x26, 0x30, 0x1b, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, + 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x06, 0x93, 0x56, 0x67, 0xd4, 0x00, 0x07, 0x17, 0xac, 0xc1, 0xbd, 0xea, 0x93, 0x3b, 0xd3, 0x28, 0xa0, + 0x57, 0xe5, 0x77, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, + 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x74, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x9d, 0x01, 0xd2, 0x67, 0xcc, 0xce, 0x6d, 0x38, 0xee, 0x87, 0xc1, 0xcc, + 0x32, 0xbb, 0xee, 0x47, 0xfa, 0x77, 0x9b, 0xdf, 0x00, 0x00, 0x00, 0x44, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x62, 0x69, 0x6e, + 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x63, 0x6f, 0x6d, 0x2e, + 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x69, 0x76, 0x65, 0xad, 0xa7, 0xd1, 0x01, 0x67, 0x9c, 0xc4, 0xea, 0xc3, 0xdf, 0x8e, 0xc4, 0x08, 0x5b, 0x35, 0x71, + 0x96, 0xc4, 0xb0, 0x57, 0x19, 0x46, 0xb5, 0x63, 0xce, 0xbb, 0x8e, 0xe7, 0x35, 0x53, 0x02, 0xe2, 0xb2, 0x8d, 0xfa, 0xf4, + 0x08, 0xdd, 0x5f, 0xda, 0x2e, 0x3e, 0xf4, 0x8c, 0x14, 0x02, 0xe2, 0x53, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, + 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, + 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfc, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0xa4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x29, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x51, + 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x79, 0x00, 0x00, 0x02, 0xa5, + 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc9, + 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, 0x00, 0x00, 0x02, 0xdd, + 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed, 0x00, 0x00, 0x02, 0xf1, + 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x7c, + 0x00, 0x00, 0x01, 0xa4, 0x3b, 0xaf, 0x30, 0xf6, 0xce, 0x08, 0x47, 0xad, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, + 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xcf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x06, 0xeb, 0x22, 0x2e, 0xd0, 0xa1, 0x2a, 0x8b, 0xd2, 0x11, 0xac, 0x9f, 0x5b, 0x27, 0x35, 0x5d, 0xd8, + 0x58, 0x6d, 0x84, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xa8, 0x12, 0x5f, 0x3d, 0x91, 0x36, 0x30, 0x1a, 0x76, 0x25, 0x8c, 0xbf, + 0x1f, 0x58, 0xcb, 0x76, 0xd6, 0xbb, 0xff, 0xb1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xa8, 0x12, 0x5f, 0x3d, 0x91, 0x36, 0x30, 0x1a, + 0x76, 0x25, 0x8c, 0xbf, 0x1f, 0x58, 0xcb, 0x76, 0xd6, 0xbb, 0xff, 0xb1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, 0xc2, 0xa8, 0x12, 0x5f, 0x3d, 0xc2, 0x91, 0x36, 0x30, 0x1a, 0x76, 0x25, 0xc2, 0x8c, 0xc2, 0xbf, + 0x1f, 0x58, 0xc3, 0x8b, 0x76, 0xc3, 0x96, 0xc2, 0xbb, 0xc3, 0xbf, 0xc2, 0xb1, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, + 0xbf, 0xc2, 0x98, 0xc2, 0xb9, 0xc2, 0x89, 0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x54, 0x55, 0x4d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, + 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xe6, 0x50, 0x17, 0x0a, 0x9f, 0xb9, 0xab, 0x61, 0x5d, 0x77, 0x39, 0x8b, + 0x76, 0x2d, 0x3f, 0x20, 0xb2, 0xec, 0x7c, 0xbc, 0xa1, 0x54, 0xac, 0x1b, 0x1c, 0x6d, 0x6b, 0x88, 0x3b, 0xd2, 0x7b, 0x6b, + 0x24, 0x84, 0x7c, 0xca, 0xc7, 0xe8, 0x66, 0x8e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x18, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, + 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, + 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x02, 0xe8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x00, 0x02, 0x31, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x41, + 0x00, 0x00, 0x02, 0x45, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x61, 0x00, 0x00, 0x02, 0x65, + 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa9, + 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xc5, + 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, + 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0xa8, 0xf4, 0x8e, 0xca, 0x78, 0x14, 0xb8, 0x41, 0x73, 0x00, 0x00, 0x00, 0x02, + 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x72, 0x3a, 0x27, 0x07, 0x00, 0xae, 0x19, 0xfc, 0x71, 0x1c, 0x6f, 0x2f, + 0xe2, 0x2b, 0x78, 0x9a, 0xdc, 0x88, 0xc1, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc9, 0x22, 0xdf, 0x1e, 0x94, 0x1b, 0x4d, 0x42, + 0x21, 0x42, 0x85, 0xcd, 0x32, 0xec, 0xe5, 0xd7, 0xf9, 0x61, 0x38, 0xe1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc9, 0x22, 0xdf, 0x1e, + 0x94, 0x1b, 0x4d, 0x42, 0x21, 0x42, 0x85, 0xcd, 0x32, 0xec, 0xe5, 0xd7, 0xf9, 0x61, 0x38, 0xe1, 0xff, 0xff, 0xff, 0xff, + 0x98, 0xb9, 0x89, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc3, 0x89, 0x22, 0xc3, 0x9f, 0x1e, 0xc2, 0x94, + 0x1b, 0x4d, 0x42, 0x21, 0x42, 0xc2, 0x85, 0xc3, 0x8d, 0x32, 0xc3, 0xac, 0xc3, 0xa5, 0xc3, 0x97, 0xc3, 0xb9, 0x61, 0x38, + 0xc3, 0xa1, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc2, 0x98, 0xc2, 0xb9, 0xc2, 0x89, 0x06, 0x01, 0x00, 0x4d, + 0x00, 0x54, 0x55, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0x7b, 0x74, 0x34, 0xf2, + 0x79, 0x55, 0x24, 0x13, 0xc5, 0x6c, 0xdd, 0xe2, 0xe7, 0xd5, 0xbf, 0x4e, 0xaa, 0xc8, 0x50, 0xa3, 0xc6, 0x46, 0x67, 0x62, + 0x08, 0x04, 0x0d, 0xe7, 0x54, 0xe1, 0xb5, 0x0a, 0x53, 0x0d, 0x90, 0xbc, 0xd7, 0x2e, 0x5f, 0x6d, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x08, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, + 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, + 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x02, 0x85, 0x00, 0x00, 0x02, 0x9d, + 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xc5, + 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0x00, 0x00, 0x02, 0xfd, 0x00, 0x00, 0x03, 0x01, + 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x03, 0x19, 0x00, 0x00, 0x03, 0x1d, 0x00, 0x00, 0x03, 0x21, 0x00, 0x00, 0x03, 0x25, + 0x00, 0x00, 0x03, 0x29, 0x00, 0x00, 0x03, 0x2d, 0x00, 0x00, 0x03, 0x31, 0x00, 0x00, 0x03, 0x35, 0x00, 0x00, 0x03, 0x39, + 0x00, 0x00, 0x03, 0x3d, 0x00, 0x00, 0x03, 0x41, 0x00, 0x00, 0x03, 0x45, 0x00, 0x00, 0x03, 0x49, 0xfa, 0xde, 0x07, 0x11, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x01, 0xfc, 0x1a, 0xe7, 0x86, 0xc7, 0x8e, 0x0c, 0x7b, 0xed, + 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0xbb, 0x34, 0xae, 0xf4, 0x96, 0x00, 0x3a, 0xa9, + 0x6c, 0x3b, 0x6c, 0xa6, 0x1b, 0xa0, 0xfd, 0x0d, 0x0b, 0x7b, 0xc1, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x6e, 0x6f, 0x62, 0x6f, + 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x50, 0x81, 0xee, 0xbe, 0x1f, 0x36, 0xff, 0x64, + 0xa1, 0x66, 0x43, 0xd7, 0xdc, 0x0e, 0x61, 0xf0, 0x17, 0xaf, 0x60, 0x35, 0x00, 0x00, 0x00, 0x60, 0x2f, 0x41, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2f, + 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x00, + 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xb8, 0x58, 0xf2, 0xef, + 0xb1, 0x4e, 0x1e, 0x2e, 0x15, 0xe0, 0x0f, 0xb5, 0xea, 0xd4, 0xf5, 0x1e, 0x45, 0x79, 0x80, 0x58, 0xe2, 0xb2, 0x93, 0xf6, + 0x1c, 0xbf, 0x8c, 0x2b, 0x1d, 0xdb, 0xed, 0x58, 0xd3, 0x90, 0x91, 0xfd, 0x86, 0xbe, 0x01, 0xdd, 0x76, 0x36, 0x01, 0xf0, + 0x1a, 0x4f, 0xd8, 0x7d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, + 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, + 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, + 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, + 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x8c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x15, 0x64, + 0x00, 0x00, 0x18, 0xe0, 0x00, 0x00, 0x19, 0xf4, 0x00, 0x00, 0x1a, 0x7c, 0x00, 0x00, 0x1b, 0x04, 0x00, 0x00, 0x1b, 0x8c, + 0x00, 0x00, 0x1c, 0x14, 0x00, 0x00, 0x1c, 0x9c, 0x00, 0x00, 0x1d, 0x24, 0x00, 0x00, 0x1d, 0xac, 0x00, 0x00, 0x1e, 0x34, + 0x00, 0x00, 0x03, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x15, 0xd0, 0x00, 0x00, 0x16, 0x44, + 0x00, 0x00, 0x16, 0xb4, 0x00, 0x00, 0x17, 0x24, 0x00, 0x00, 0x17, 0x94, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x18, 0x74, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x17, 0x72, 0x65, 0x73, 0x74, + 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, + 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, + 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, + 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, + 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, + 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, + 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, + 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, + 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, + 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, + 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, + 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, + 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, + 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, + 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, + 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, + 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, + 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, + 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, + 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x19, 0x30, + 0x00, 0x00, 0x19, 0x50, 0x00, 0x00, 0x19, 0x6c, 0x00, 0x00, 0x19, 0x88, 0x00, 0x00, 0x19, 0xa4, 0x00, 0x00, 0x19, 0xc0, + 0x00, 0x00, 0x19, 0xdc, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x17, + 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, + 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9, + 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, + 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, + 0xdf, 0x25, 0xe4, 0x2d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1a, 0x44, 0x00, 0x00, 0x1a, 0x4c, + 0x00, 0x00, 0x1a, 0x54, 0x00, 0x00, 0x1a, 0x5c, 0x00, 0x00, 0x1a, 0x64, 0x00, 0x00, 0x1a, 0x6c, 0x00, 0x00, 0x1a, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1a, 0xcc, 0x00, 0x00, 0x1a, 0xd4, 0x00, 0x00, 0x1a, 0xdc, + 0x00, 0x00, 0x1a, 0xe4, 0x00, 0x00, 0x1a, 0xec, 0x00, 0x00, 0x1a, 0xf4, 0x00, 0x00, 0x1a, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1b, 0x54, 0x00, 0x00, 0x1b, 0x5c, 0x00, 0x00, 0x1b, 0x64, 0x00, 0x00, 0x1b, 0x6c, + 0x00, 0x00, 0x1b, 0x74, 0x00, 0x00, 0x1b, 0x7c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x1b, 0xdc, 0x00, 0x00, 0x1b, 0xe4, 0x00, 0x00, 0x1b, 0xec, 0x00, 0x00, 0x1b, 0xf4, 0x00, 0x00, 0x1b, 0xfc, + 0x00, 0x00, 0x1c, 0x04, 0x00, 0x00, 0x1c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1c, 0x64, + 0x00, 0x00, 0x1c, 0x6c, 0x00, 0x00, 0x1c, 0x74, 0x00, 0x00, 0x1c, 0x7c, 0x00, 0x00, 0x1c, 0x84, 0x00, 0x00, 0x1c, 0x8c, + 0x00, 0x00, 0x1c, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1c, 0xec, 0x00, 0x00, 0x1c, 0xf4, + 0x00, 0x00, 0x1c, 0xfc, 0x00, 0x00, 0x1d, 0x04, 0x00, 0x00, 0x1d, 0x0c, 0x00, 0x00, 0x1d, 0x14, 0x00, 0x00, 0x1d, 0x1c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1d, 0x74, 0x00, 0x00, 0x1d, 0x7c, 0x00, 0x00, 0x1d, 0x84, + 0x00, 0x00, 0x1d, 0x8c, 0x00, 0x00, 0x1d, 0x94, 0x00, 0x00, 0x1d, 0x9c, 0x00, 0x00, 0x1d, 0xa4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1d, 0xfc, 0x00, 0x00, 0x1e, 0x04, 0x00, 0x00, 0x1e, 0x0c, 0x00, 0x00, 0x1e, 0x14, + 0x00, 0x00, 0x1e, 0x1c, 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1e, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x1e, 0x84, 0x00, 0x00, 0x1e, 0x8c, 0x00, 0x00, 0x1e, 0x94, 0x00, 0x00, 0x1e, 0x9c, 0x00, 0x00, 0x1e, 0xa4, + 0x00, 0x00, 0x1e, 0xac, 0x00, 0x00, 0x1e, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xdc, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x02, 0x38, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, + 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xf5, + 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d, + 0x4a, 0x16, 0x48, 0x81, 0x4a, 0xfb, 0x22, 0x80, 0x56, 0xd0, 0x65, 0x2b, 0x3e, 0x11, 0x11, 0xe2, 0x12, 0x2b, 0xc6, 0x87, + 0xa1, 0xd0, 0x14, 0x1e, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, 0x30, 0x36, 0x5a, 0x00, + 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, 0x30, 0x36, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x16, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, + 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x01, 0x15, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, + 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0xfd, 0xc0, 0xab, 0x3b, 0xfc, 0x61, 0xe6, 0xd5, 0xdd, 0xcf, 0x26, 0x91, + 0xe5, 0xe9, 0xfb, 0x2c, 0xc0, 0x8d, 0xfe, 0x4c, 0x96, 0xf5, 0x08, 0x64, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, + 0x31, 0x38, 0x35, 0x31, 0x31, 0x37, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, + 0x31, 0x37, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, + 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, + 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0xd9, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9, + 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0xdc, 0xaf, 0x18, 0xfa, 0xad, 0xad, 0x06, 0xf6, 0x32, 0x30, 0x31, 0x36, + 0x30, 0x34, 0x31, 0x31, 0x32, 0x31, 0x35, 0x31, 0x31, 0x35, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x31, 0x31, + 0x32, 0x31, 0x35, 0x31, 0x31, 0x35, 0x5a, 0x00, 0x61, 0x61, 0x70, 0x6c, 0x69, 0x70, 0x72, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x11, + 0x73, 0x73, 0x75, 0x69, 0x00, 0x00, 0x00, 0x20, 0x87, 0x19, 0x1c, 0xa3, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, + 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x64, 0x62, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x21, 0x7e, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x4b, 0x65, + 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x61, 0x73, 0x64, 0x66, 0x2d, 0x64, 0x62, + 0x00, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, + 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, + 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb4, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x05, 0x5c, 0x00, 0x00, 0x00, 0xb4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x61, 0x63, 0x63, 0x74, 0x73, 0x76, 0x63, 0x65, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x70, 0x00, 0x00, 0x04, 0x94, 0x00, 0x00, 0x04, 0xc8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x6c, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x05, 0x34, 0x00, 0x00, 0x05, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, + 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x05, 0x8c, 0x00, 0x00, 0x05, 0xa4, 0x00, 0x00, 0x05, 0xb8, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, + 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, + 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x05, 0x2c, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x01, 0x58, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, + 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x21, + 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x01, 0x2d, 0x00, 0x00, 0x01, 0x31, 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, + 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0xce, 0x58, 0x3c, 0x63, 0xf0, 0xe1, 0x4b, 0xfc, + 0xee, 0x88, 0x20, 0xa4, 0xc4, 0x20, 0xc4, 0x8c, 0xaf, 0x9d, 0xe6, 0x89, 0x39, 0xe3, 0xcc, 0x27, 0x32, 0x30, 0x31, 0x36, + 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x33, 0x34, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, + 0x31, 0x38, 0x34, 0x39, 0x33, 0x34, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x61, 0x20, 0x75, 0x73, + 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x68, 0x74, 0x70, 0x73, + 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xed, + 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x05, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x01, 0x11, + 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, + 0x60, 0x88, 0xd4, 0xf3, 0x53, 0x7d, 0x89, 0x6e, 0xc1, 0x4f, 0xfd, 0x7b, 0x4b, 0x9d, 0x0d, 0xe0, 0xe9, 0xd6, 0x84, 0xdf, + 0x0f, 0x23, 0x90, 0x0b, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x34, 0x33, 0x5a, 0x00, + 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x34, 0x33, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x61, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0c, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04, + 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x02, 0x94, 0x00, 0x00, 0x03, 0x5c, 0x00, 0x00, 0x03, 0xac, 0x00, 0x00, 0x03, 0xe4, 0x00, 0x00, 0x04, 0x44, + 0x00, 0x00, 0x04, 0x7c, 0x00, 0x00, 0x04, 0xbc, 0x00, 0x00, 0x04, 0xf4, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x61, 0x63, 0x63, 0x74, 0x73, 0x64, 0x6d, 0x6e, 0x73, 0x72, 0x76, 0x72, + 0x70, 0x74, 0x63, 0x6c, 0x61, 0x74, 0x79, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x02, 0xd4, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x68, 0x74, 0x70, 0x73, + 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, + 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04, + 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x84, + 0x00, 0x00, 0x03, 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xd4, + 0x00, 0x00, 0x03, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x6c, 0x00, 0x00, 0x04, 0x74, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, 0x74, 0x70, 0x73, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x74, 0x79, 0x70, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0xa4, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x70, 0x61, 0x74, 0x68, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x1c, 0x00, 0x00, 0x05, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1d, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x61, 0x63, 0x63, 0x74, 0x76, 0x6c, 0x6d, 0x65, + 0x61, 0x64, 0x64, 0x72, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x64, 0x64, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0b, 0xd8, 0x00, 0x00, 0x05, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x45, 0x00, 0x00, 0x04, 0x49, + 0x00, 0x00, 0x04, 0x4d, 0x00, 0x00, 0x04, 0x5d, 0x00, 0x00, 0x04, 0x71, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x05, 0xb9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xc1, 0x30, 0x82, 0x04, 0x01, 0x30, 0x82, 0x02, 0xe9, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, + 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, + 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, + 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x35, 0x33, 0x32, 0x5a, 0x17, + 0x0d, 0x32, 0x36, 0x30, 0x34, 0x30, 0x36, 0x31, 0x38, 0x35, 0x35, 0x33, 0x32, 0x5a, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, + 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, + 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, + 0x62, 0x6f, 0x64, 0x79, 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, 0xb3, 0xaa, 0xa8, 0x77, 0xe7, 0x3e, 0x2d, 0x0c, 0xf4, 0x83, 0x55, 0xc2, 0x9e, + 0x50, 0x10, 0xc9, 0xef, 0xc8, 0x48, 0x38, 0xe4, 0x43, 0x96, 0xfa, 0x93, 0x32, 0xbf, 0x66, 0xad, 0x84, 0xa2, 0x8b, 0x6b, + 0x07, 0x8c, 0xc6, 0x93, 0x8c, 0x4d, 0x65, 0x0f, 0xad, 0x76, 0x73, 0x0c, 0x4d, 0x43, 0xee, 0x35, 0xd4, 0x68, 0x4a, 0x9a, + 0x6d, 0x4d, 0xa5, 0xae, 0x66, 0xcf, 0xfb, 0xbb, 0x93, 0xd3, 0x6a, 0xe3, 0xfc, 0x41, 0x97, 0xae, 0x90, 0xc3, 0xd8, 0x83, + 0xfb, 0x8d, 0x67, 0x84, 0xc1, 0xd5, 0x7d, 0x1d, 0x12, 0xca, 0x0c, 0xb5, 0xae, 0xf0, 0xe3, 0x36, 0x39, 0xf1, 0x68, 0x92, + 0x6f, 0xda, 0x2d, 0x48, 0x87, 0xf0, 0x4b, 0x15, 0x4e, 0x4f, 0x7a, 0x3a, 0x16, 0xb9, 0x02, 0x89, 0x95, 0x98, 0xab, 0xb2, + 0x58, 0x5b, 0x31, 0x7f, 0x49, 0x90, 0x48, 0xfd, 0x8d, 0x8a, 0x37, 0x3a, 0x4e, 0xd8, 0x00, 0x4a, 0xdc, 0xd4, 0x02, 0x9f, + 0xcd, 0x4b, 0xde, 0x75, 0x4a, 0xb2, 0x27, 0x8e, 0xe6, 0x2d, 0xea, 0x35, 0x89, 0x85, 0x8a, 0x37, 0x59, 0xd6, 0xd1, 0xf8, + 0x36, 0x7c, 0x93, 0x9e, 0xd6, 0xd1, 0xc3, 0xd9, 0x75, 0xa4, 0x4f, 0x40, 0x24, 0xe9, 0xc0, 0xde, 0xeb, 0xc0, 0x5e, 0xd6, + 0x04, 0xe1, 0xd0, 0x07, 0x29, 0xc1, 0x9d, 0x6f, 0x78, 0x2d, 0x5a, 0xef, 0xe6, 0xff, 0x25, 0x16, 0xcf, 0x60, 0x77, 0xa2, + 0x10, 0x2b, 0xa4, 0x2a, 0xff, 0x74, 0x3b, 0xe6, 0x4d, 0xc1, 0x13, 0xba, 0x8b, 0xe8, 0x15, 0x8e, 0xc7, 0xc3, 0xd4, 0x31, + 0xb0, 0x99, 0x51, 0x32, 0x30, 0x03, 0x0b, 0x1c, 0xa0, 0x0a, 0x17, 0x15, 0x34, 0x57, 0x38, 0xd3, 0x08, 0x13, 0xc4, 0xd6, + 0x7c, 0x24, 0x16, 0xd0, 0x2f, 0x00, 0x88, 0xd7, 0xd9, 0xca, 0x1e, 0x6b, 0x50, 0x3b, 0x5f, 0xb6, 0x08, 0xb1, 0x29, 0x42, + 0x70, 0xf1, 0x89, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x47, 0x30, 0x45, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, + 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, + 0x14, 0x30, 0x12, 0x81, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x00, 0xa3, 0x3e, 0x5c, 0x33, 0x06, 0x0b, 0x74, 0xf7, 0x59, 0x56, 0x2e, 0x26, 0x18, 0xe0, 0x59, 0xc9, 0x20, 0x9d, + 0xaa, 0xf2, 0xfb, 0xa0, 0xf8, 0x11, 0x00, 0x71, 0x53, 0x3d, 0xfa, 0xdc, 0xe9, 0x12, 0x4c, 0x8a, 0xa1, 0x1c, 0x7c, 0xb3, + 0x4b, 0xa5, 0xa0, 0xfa, 0x03, 0xc5, 0x82, 0x1c, 0xab, 0x44, 0xf6, 0xcb, 0x59, 0x4b, 0x80, 0xeb, 0xc0, 0xa8, 0x0e, 0xc6, + 0x93, 0xea, 0xbf, 0x67, 0x41, 0xa9, 0x64, 0xcb, 0xb4, 0x3e, 0xf7, 0x64, 0xcf, 0x4c, 0xef, 0x24, 0x62, 0x73, 0x2d, 0xed, + 0xb4, 0xec, 0x30, 0x97, 0x91, 0x9f, 0x18, 0xe9, 0x12, 0x93, 0x18, 0x83, 0x70, 0xb0, 0xc4, 0x35, 0x33, 0x67, 0x17, 0xb0, + 0x8b, 0xbe, 0x45, 0xde, 0x98, 0x23, 0xf2, 0x02, 0x77, 0x79, 0x55, 0x53, 0xc4, 0xd7, 0x67, 0x81, 0xde, 0xa1, 0x3f, 0x63, + 0xb5, 0x87, 0xb6, 0x20, 0x8d, 0x4f, 0x5e, 0x7e, 0x27, 0x30, 0x99, 0xe0, 0xff, 0x91, 0x8b, 0x00, 0x8d, 0x7d, 0xe5, 0x57, + 0x57, 0xd8, 0xd9, 0x7d, 0x6f, 0xc6, 0xb8, 0x6f, 0x84, 0xed, 0x84, 0x9d, 0xd9, 0xac, 0x13, 0xd8, 0x4a, 0x96, 0x55, 0x2d, + 0x8e, 0x21, 0x11, 0xc9, 0xa4, 0x81, 0x10, 0x7a, 0x0a, 0x15, 0xce, 0x99, 0x98, 0x09, 0xdd, 0xec, 0x8d, 0x1b, 0xfb, 0x17, + 0x55, 0x03, 0xa6, 0x44, 0xb5, 0xc9, 0xa9, 0x1f, 0x52, 0xd7, 0x35, 0x06, 0x8d, 0x0a, 0x5a, 0x01, 0x2a, 0xb0, 0xd2, 0x0c, + 0xfa, 0xd9, 0x66, 0xfa, 0x35, 0x6e, 0xa0, 0xbc, 0x21, 0xe4, 0xe1, 0xe0, 0x3c, 0x3b, 0x7a, 0xef, 0x7d, 0xe1, 0x34, 0x2e, + 0xe3, 0x9c, 0xc0, 0xa9, 0x4c, 0x16, 0xab, 0x00, 0x60, 0xe0, 0x44, 0xeb, 0x62, 0xcc, 0x1d, 0x27, 0x84, 0x0f, 0x33, 0x37, + 0x9d, 0xc5, 0xc4, 0xa1, 0xd3, 0xe8, 0x38, 0xff, 0xf2, 0xdf, 0xcd, 0x7c, 0xbb, 0xc3, 0xa1, 0xae, 0x4d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, + 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, + 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, + 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, + 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, + 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, + 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, + 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, + 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x05, 0xd8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x31, 0x00, 0x00, 0x04, 0x35, 0x00, 0x00, 0x04, 0x39, + 0x00, 0x00, 0x04, 0x4d, 0x00, 0x00, 0x04, 0x61, 0x00, 0x00, 0x05, 0x0d, 0x00, 0x00, 0x05, 0xb9, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xc1, 0x30, 0x82, 0x03, 0xee, 0x30, 0x82, 0x02, 0xd6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x06, + 0xe0, 0x2a, 0x1d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, + 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, + 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, + 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x36, 0x34, 0x36, 0x5a, + 0x17, 0x0d, 0x32, 0x36, 0x30, 0x34, 0x30, 0x36, 0x31, 0x38, 0x35, 0x36, 0x34, 0x36, 0x5a, 0x30, 0x81, 0xa2, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, + 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, + 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, + 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, + 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 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, 0xb6, 0x07, 0xac, 0x5c, 0xc6, 0xcb, 0xf0, + 0xb7, 0x97, 0x0d, 0x43, 0x1a, 0xe9, 0x61, 0xe7, 0x34, 0x63, 0x6a, 0x26, 0x0d, 0x77, 0xba, 0x25, 0xaa, 0xc8, 0x46, 0xf8, + 0xc9, 0xdd, 0x21, 0xb4, 0x3e, 0x2e, 0x11, 0x8e, 0xb6, 0x72, 0xf2, 0x01, 0x16, 0x07, 0xcf, 0x88, 0x91, 0xc4, 0xc0, 0x48, + 0x64, 0x41, 0x91, 0xf7, 0x63, 0x72, 0xd5, 0x37, 0xef, 0x37, 0x62, 0xed, 0x33, 0xb3, 0xf9, 0x6e, 0x31, 0xd1, 0x68, 0xe7, + 0xde, 0x62, 0x9f, 0x82, 0xb8, 0x9e, 0x11, 0xe7, 0x66, 0x91, 0xc1, 0xbe, 0xe5, 0x5c, 0xd6, 0x71, 0x83, 0x91, 0xbc, 0x0f, + 0xa8, 0x06, 0xc3, 0xe9, 0xb6, 0x76, 0x16, 0xae, 0x69, 0x0a, 0x47, 0xe4, 0x65, 0xaa, 0x13, 0x71, 0x48, 0xb3, 0x5c, 0x25, + 0xa5, 0x1a, 0xd0, 0x2a, 0x57, 0x57, 0xf9, 0xb7, 0x13, 0xbd, 0xf4, 0x13, 0x5a, 0x11, 0x1b, 0xcc, 0xd8, 0x9a, 0x5f, 0x82, + 0x3f, 0xa7, 0x6b, 0x64, 0x47, 0x54, 0xb6, 0x81, 0xaf, 0xcb, 0x4b, 0x94, 0x39, 0x65, 0x15, 0xba, 0x6a, 0x02, 0x7c, 0x71, + 0x30, 0x60, 0x21, 0x12, 0x63, 0x28, 0xe0, 0x85, 0xca, 0xcc, 0x07, 0xb1, 0x13, 0x40, 0x19, 0x72, 0x02, 0x35, 0x0e, 0x2d, + 0x4b, 0x8a, 0xcd, 0x1d, 0x09, 0x65, 0xb0, 0x81, 0x49, 0xea, 0x70, 0x15, 0x92, 0x19, 0x7b, 0xfe, 0x15, 0xf7, 0x4a, 0x3f, + 0x1e, 0x3c, 0x63, 0x7a, 0x0f, 0x17, 0x32, 0x1a, 0xb7, 0x26, 0xa1, 0xa0, 0x9b, 0x3f, 0x4e, 0x7c, 0x38, 0xe6, 0x27, 0xbf, + 0xa8, 0x1b, 0xf7, 0xbd, 0x2d, 0xfd, 0x9b, 0x05, 0x0c, 0xaa, 0x81, 0xb8, 0x09, 0xd4, 0xe2, 0xe3, 0xbd, 0x6c, 0x70, 0xc0, + 0x7e, 0x95, 0xd4, 0x0b, 0x13, 0xab, 0xb8, 0xdd, 0x3d, 0x4c, 0x59, 0xf0, 0xc7, 0x8e, 0x47, 0xb5, 0xd8, 0x31, 0x78, 0x80, + 0xd2, 0x5f, 0x0c, 0x0b, 0xae, 0x22, 0xe7, 0x9e, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x2a, 0x30, 0x28, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, + 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xaf, 0xe3, + 0x41, 0xaa, 0x63, 0xdc, 0x3e, 0xd1, 0x46, 0x1e, 0x7a, 0x09, 0x04, 0x4a, 0xfd, 0x54, 0xc7, 0xd9, 0x25, 0x2f, 0xce, 0x8e, + 0x5d, 0x34, 0x96, 0x04, 0x67, 0xbc, 0x6f, 0xb6, 0x99, 0x35, 0xc2, 0x16, 0x1c, 0x2a, 0xc3, 0x5f, 0xdf, 0x6e, 0xe2, 0xe4, + 0x2e, 0xbb, 0x64, 0x1c, 0x0a, 0xff, 0x62, 0x79, 0x70, 0x7c, 0xc6, 0x8e, 0xd9, 0x95, 0xb6, 0x8a, 0x3d, 0xf6, 0xdd, 0x79, + 0x1c, 0xeb, 0x73, 0x05, 0x2f, 0x7e, 0x38, 0xb8, 0x9c, 0xfc, 0x06, 0x8f, 0x5f, 0xd7, 0xec, 0xd3, 0x23, 0xae, 0x75, 0x0f, + 0x8e, 0x70, 0xb2, 0xd8, 0x88, 0xa0, 0x4f, 0x53, 0x0a, 0xcc, 0xee, 0x18, 0xf2, 0x5b, 0xf8, 0xe1, 0x22, 0x6b, 0xeb, 0x4d, + 0x9d, 0x2a, 0xa1, 0x46, 0xf4, 0xc7, 0x99, 0x26, 0x5b, 0xaf, 0x92, 0x54, 0x72, 0xe7, 0xea, 0x49, 0x34, 0x98, 0x8d, 0x93, + 0x18, 0xc5, 0x6e, 0x79, 0x79, 0xb3, 0x63, 0x76, 0xf7, 0x84, 0x49, 0x06, 0x58, 0x14, 0x1a, 0x86, 0xbd, 0xe5, 0x5a, 0xf8, + 0x81, 0x06, 0x15, 0x0c, 0xf7, 0x57, 0x4e, 0xeb, 0xbe, 0xc9, 0xe6, 0x09, 0xa3, 0x1d, 0xcc, 0xc6, 0x08, 0xbc, 0x71, 0x4b, + 0x62, 0x1a, 0xec, 0xdd, 0xad, 0xe3, 0x00, 0xd9, 0xf3, 0x98, 0x94, 0x75, 0xb5, 0xc2, 0x64, 0xec, 0xec, 0xe1, 0x88, 0x5b, + 0x24, 0xd6, 0xa2, 0x27, 0x86, 0x10, 0xc4, 0xfc, 0xf7, 0x8d, 0x79, 0x95, 0x20, 0x3e, 0xc5, 0x7a, 0xdc, 0x57, 0xc8, 0x2e, + 0x78, 0x63, 0xd5, 0x09, 0xc3, 0xa9, 0xa4, 0xd9, 0x83, 0x99, 0xbe, 0x17, 0xdc, 0x22, 0x85, 0x98, 0x0b, 0xe1, 0xf6, 0x67, + 0x47, 0xf7, 0x1d, 0xed, 0x40, 0xe4, 0x5c, 0x5e, 0x58, 0xf1, 0x27, 0x5b, 0xe2, 0x7b, 0xb0, 0xf5, 0xbf, 0x37, 0xc3, 0xe2, + 0x73, 0xa8, 0xd6, 0xf1, 0x42, 0xb2, 0x56, 0x90, 0x00, 0xa4, 0x35, 0x4a, 0x5a, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, + 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, + 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, + 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, + 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, + 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, + 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, + 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, 0x00, 0x00, 0x00, 0x14, + 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, + 0x00, 0x00, 0x06, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x00, 0x00, 0x04, 0x85, 0x00, 0x00, 0x04, 0x89, 0x00, 0x00, 0x04, 0xa5, + 0x00, 0x00, 0x04, 0xc5, 0x00, 0x00, 0x05, 0x81, 0x00, 0x00, 0x06, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x45, + 0x30, 0x82, 0x04, 0x3d, 0x30, 0x82, 0x03, 0x25, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, + 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x31, 0x31, 0x32, 0x32, 0x34, 0x30, 0x32, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, + 0x34, 0x30, 0x39, 0x32, 0x32, 0x34, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, + 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, + 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, + 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 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, 0xc3, 0xe8, 0xe0, 0x34, 0xff, 0x63, 0x08, 0xce, 0x36, 0x82, 0x02, 0xe7, 0x91, + 0x0b, 0x73, 0x84, 0xb9, 0xad, 0xd8, 0x79, 0x92, 0x34, 0x20, 0x96, 0xd1, 0x3a, 0xc7, 0x7f, 0x19, 0xd7, 0xcf, 0x9f, 0xab, + 0x2b, 0xc0, 0x0c, 0xe1, 0xf6, 0x0e, 0x9e, 0x9f, 0x73, 0x42, 0x95, 0xf1, 0x2c, 0x63, 0xff, 0x3f, 0x31, 0xb1, 0xe3, 0x24, + 0x1a, 0x75, 0x7d, 0x50, 0x2c, 0x23, 0x59, 0x53, 0x2c, 0xab, 0xaf, 0xd7, 0x5c, 0xf1, 0x27, 0xd2, 0xe9, 0xf5, 0x8f, 0x76, + 0xc4, 0x96, 0x74, 0x3c, 0xda, 0x65, 0xd4, 0x9e, 0xde, 0x33, 0x25, 0x5d, 0xed, 0x04, 0x94, 0x2c, 0xb5, 0x18, 0xeb, 0x64, + 0x8e, 0xf4, 0xd4, 0xe0, 0xb6, 0xfc, 0xcc, 0xd7, 0xfb, 0x90, 0x9c, 0xc1, 0xe6, 0x09, 0xb9, 0x8c, 0xc9, 0xba, 0x91, 0x4d, + 0x63, 0x5f, 0xa1, 0x75, 0x13, 0x11, 0x7d, 0x13, 0xa9, 0x2c, 0x07, 0xbd, 0xcb, 0x5d, 0xc5, 0xb0, 0x4f, 0xed, 0x95, 0xc6, + 0x8c, 0xe9, 0x78, 0xa2, 0xa5, 0x42, 0x15, 0x5a, 0xd0, 0x9c, 0x9c, 0x85, 0x85, 0x6e, 0x50, 0xae, 0x19, 0xd5, 0x91, 0x13, + 0x62, 0x96, 0xd9, 0x4a, 0x47, 0xe3, 0xfe, 0x8f, 0x7d, 0x47, 0xbd, 0xbe, 0xaa, 0x37, 0x64, 0xe3, 0xf0, 0xa3, 0xa4, 0xd0, + 0xef, 0xef, 0x2a, 0xa7, 0x45, 0xbf, 0x21, 0x79, 0xb8, 0x5c, 0x04, 0x8a, 0x2f, 0x7b, 0xe0, 0xe2, 0x32, 0x58, 0x75, 0xec, + 0xec, 0x2f, 0x78, 0xa5, 0x9a, 0x7b, 0xa3, 0x3c, 0xf6, 0x67, 0x00, 0x83, 0xe5, 0x77, 0x1d, 0x2b, 0xdd, 0x74, 0xd0, 0x45, + 0xcf, 0xa4, 0x0c, 0xf2, 0xe2, 0x60, 0xa8, 0x70, 0x87, 0x05, 0x0b, 0x7c, 0xef, 0x88, 0x09, 0x23, 0x15, 0xdf, 0xdb, 0x9f, + 0xc2, 0x80, 0x1f, 0x0a, 0x12, 0xcb, 0x00, 0xa4, 0x8a, 0x77, 0xa7, 0x54, 0x8f, 0xcb, 0x91, 0xbb, 0x55, 0x52, 0x51, 0x8f, + 0xca, 0xf6, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, + 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, + 0x20, 0x30, 0x1e, 0x81, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8c, 0x44, 0x70, 0xda, 0xd9, 0x65, 0x52, + 0xfd, 0x46, 0x0e, 0xab, 0xbb, 0xb5, 0x1c, 0x46, 0x0a, 0xcb, 0x3d, 0xc3, 0x71, 0x79, 0xa8, 0x5f, 0x3b, 0x45, 0x49, 0x29, + 0x0c, 0xf5, 0x69, 0xb4, 0x27, 0x4d, 0x79, 0xad, 0xa9, 0x93, 0x11, 0x7b, 0xad, 0x45, 0xc6, 0x49, 0x54, 0x8b, 0x5d, 0x5f, + 0xcc, 0x9d, 0xd9, 0xe4, 0x8f, 0xff, 0x21, 0x0f, 0x7a, 0x40, 0xf2, 0xd6, 0xce, 0xe1, 0x97, 0x5f, 0x7d, 0x9c, 0x76, 0x22, + 0x73, 0x30, 0x3b, 0xb4, 0x5b, 0xa0, 0x07, 0x70, 0x96, 0x97, 0x84, 0xe1, 0x47, 0x5b, 0x3e, 0xd2, 0xed, 0x3f, 0xca, 0x97, + 0x3a, 0x33, 0x52, 0xb8, 0x22, 0x89, 0xe2, 0x2e, 0x61, 0x5e, 0x20, 0x1a, 0xf9, 0x4f, 0x9a, 0x18, 0xde, 0xf3, 0x8e, 0x11, + 0x3b, 0x19, 0x09, 0xce, 0x8e, 0xb9, 0x28, 0x5f, 0x64, 0x54, 0xc1, 0x33, 0x19, 0x68, 0x96, 0x54, 0x53, 0x84, 0xb6, 0xf2, + 0xdb, 0xb3, 0x6b, 0xca, 0x36, 0x08, 0xb1, 0xa3, 0x0d, 0x19, 0x4e, 0xac, 0x17, 0x25, 0x96, 0x0d, 0x4c, 0x9e, 0xc5, 0xa0, + 0xcc, 0xe4, 0x52, 0x98, 0x1c, 0xcf, 0x0a, 0x77, 0x91, 0xf2, 0xc8, 0xae, 0x8c, 0x1c, 0x1d, 0xae, 0x79, 0xf6, 0x0c, 0x65, + 0xf0, 0xb4, 0xdd, 0x0c, 0x6f, 0x35, 0x12, 0x93, 0xb7, 0x20, 0xd1, 0x29, 0xa3, 0x40, 0xb5, 0x66, 0x67, 0x69, 0xdd, 0x97, + 0xcf, 0x48, 0x9f, 0xe9, 0x00, 0x33, 0x0e, 0x8e, 0xae, 0xc6, 0x40, 0xe3, 0x40, 0xdb, 0xab, 0x8b, 0x1e, 0x34, 0xbb, 0x0b, + 0xb7, 0x42, 0xd4, 0x0d, 0x9e, 0x86, 0x99, 0x3c, 0xbd, 0x34, 0xc5, 0xba, 0xac, 0x03, 0x8b, 0xcd, 0xa3, 0xee, 0x36, 0x52, + 0x28, 0x59, 0x7a, 0x29, 0xd7, 0x1f, 0xa1, 0x18, 0xc5, 0xba, 0x7a, 0xc4, 0xf0, 0x67, 0x4a, 0x61, 0x5c, 0x83, 0xad, 0x6c, + 0x89, 0x0b, 0xdd, 0x40, 0xf8, 0xfd, 0x8c, 0xce, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, + 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, + 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, + 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, + 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, + 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, + 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x14, 0xd7, 0x58, 0x0b, 0xdf, 0xe7, 0x97, 0x49, 0x7e, 0xd7, 0x44, 0x80, 0x01, + 0xf5, 0xf3, 0x7f, 0xf6, 0x1d, 0x5c, 0x24, 0x16, 0x00, 0x00, 0x08, 0xe8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x12, 0x5c, + 0x00, 0x00, 0x14, 0xd0, 0x00, 0x00, 0x15, 0x18, 0x00, 0x00, 0x15, 0x9c, 0x00, 0x00, 0x17, 0xe4, 0x00, 0x00, 0x1a, 0x2c, + 0x00, 0x00, 0x1a, 0x80, 0x00, 0x00, 0x1a, 0x98, 0x00, 0x00, 0x02, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x03, 0x63, 0x74, 0x79, 0x70, 0x69, 0x73, 0x73, 0x75, 0x73, 0x6e, 0x62, 0x72, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x12, 0x94, 0x00, 0x00, 0x13, 0x48, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, + 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, + 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, + 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, + 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, + 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, + 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, + 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, + 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, + 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x00, 0x15, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x15, 0x48, 0x00, 0x00, 0x15, 0x60, + 0x00, 0x00, 0x15, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x75, 0x62, 0x6a, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x15, 0xcc, 0x00, 0x00, 0x16, 0x74, 0x00, 0x00, 0x17, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, + 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xac, + 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, + 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, + 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, + 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0xb8, + 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, + 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, + 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, + 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, + 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x18, 0x14, 0x00, 0x00, 0x18, 0xbc, 0x00, 0x00, 0x19, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa0, + 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, + 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, + 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, + 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, + 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, + 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, + 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, + 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, + 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, + 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, + 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x73, 0x6e, 0x62, 0x72, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1a, 0x5c, 0x00, 0x00, 0x1a, 0x68, + 0x00, 0x00, 0x1a, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x6b, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x1a, 0xc8, 0x00, 0x00, 0x1a, 0xe4, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, + 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, + 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xd7, 0x58, 0x0b, 0xdf, 0xe7, 0x97, 0x49, 0x7e, 0xd7, 0x44, 0x80, 0x01, + 0xf5, 0xf3, 0x7f, 0xf6, 0x1d, 0x5c, 0x24, 0x16, 0x00, 0x00, 0x00, 0xe8, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xa8, + 0x52, 0xba, 0xd6, 0xe8, 0x80, 0xd9, 0x0e, 0xbb, 0x2e, 0x64, 0x65, 0xce, 0xcd, 0xe6, 0xa9, 0x71, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0xff, 0x00, 0x7f, 0x00, 0x00, 0x58, 0xcc, 0x46, 0xd5, 0x94, 0x46, 0x74, 0xb1, 0x30, 0x40, 0x9b, 0x78, + 0xb0, 0x30, 0x4b, 0x1a, 0xa1, 0x93, 0x58, 0x1f, 0x48, 0xd4, 0x81, 0x1e, 0x1e, 0x1e, 0xe2, 0xaf, 0xda, 0x6a, 0x3e, 0x6e, + 0x08, 0x90, 0x5e, 0xd5, 0xf1, 0xce, 0x8b, 0x78, 0x8a, 0x5e, 0xe2, 0x36, 0x45, 0x92, 0xee, 0xeb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xe6, 0xb4, 0xf8, 0xd6, 0xa3, 0x68, 0x66, 0xde, 0x70, 0xd4, 0xe0, 0xd6, 0x9a, 0x46, 0x5d, 0xbd, + 0x60, 0x41, 0x2b, 0x19, 0x2b, 0x4b, 0x55, 0x64, 0x60, 0xe4, 0x91, 0x17, 0x5e, 0xa2, 0x08, 0xe0, 0x1c, 0x6e, 0xbd, 0xf1, + 0x08, 0xfd, 0x2d, 0x7b, 0x42, 0x6a, 0x7c, 0xa3, 0x73, 0x6d, 0xb0, 0xfd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x48 +}; +unsigned int test_keychain_len = 45864; + + +SecKeychainRef CF_RETURNS_RETAINED getPopulatedTestKeychain() { + deleteKeychainFiles(keychainFile); + + writeFile(keychainFile, test_keychain, test_keychain_len); + + SecKeychainRef kc = NULL; + ok_status(SecKeychainOpen(keychainFile, &kc), "%s: getPopulatedTestKeychain: SecKeychainOpen", testName); + ok_status(SecKeychainUnlock(kc, (UInt32) strlen(test_keychain_password), test_keychain_password, true), "%s: getPopulatedTestKeychain: SecKeychainUnlock", testName); + return kc; +} +#define getPopulatedTestKeychainTests 2 + +SecKeychainRef CF_RETURNS_RETAINED getEmptyTestKeychain() { + deleteKeychainFiles(keychainFile); + + SecKeychainRef kc = NULL; + ok_status(SecKeychainCreate(keychainFile, (UInt32) strlen(test_keychain_password), test_keychain_password, false, NULL, &kc), "%s: getPopulatedTestKeychain: SecKeychainCreate", testName); + return kc; +} +#define getEmptyTestKeychainTests 1 + + +void startTest(const char* thisTestName) { + strlcpy(testName, thisTestName, sizeof(testName)); +} + +void initializeKeychainTests(const char* thisTestName) { + const char *home_dir = getenv("HOME"); + snprintf(keychainName, sizeof(keychainName), "test-%s.asdf", thisTestName); + snprintf(keychainFile, sizeof(keychainFile), "%s/Library/Keychains/%s", home_dir, keychainName); + snprintf(keychainDbFile, sizeof(keychainDbFile), "%s/Library/Keychains/%s-db", home_dir, keychainName); + snprintf(keychainTempFile, sizeof(keychainTempFile), "%s/Library/Keychains/test_temp", home_dir); + + deleteKeychainFiles(keychainFile); + + startTest(thisTestName); + + SecKeychainGetUserPromptAttempts(&promptAttempts); + SecKeychainSetUserInteractionAllowed(FALSE); +} + +// Use this at the bottom of every test to make sure everything is gone +void deleteTestFiles() { + deleteKeychainFiles(keychainFile); +} + +void addToSearchList(SecKeychainRef keychain) { + CFArrayRef searchList = NULL; + SecKeychainCopySearchList(&searchList); + CFMutableArrayRef mutableSearchList = CFArrayCreateMutableCopy(NULL, CFArrayGetCount(searchList) + 1, searchList); + CFArrayAppendValue(mutableSearchList, keychain); + SecKeychainSetSearchList(mutableSearchList); + CFRelease(searchList); + CFRelease(mutableSearchList); +} + + +/* Checks to be sure there are N elements in this search, and returns the first + * if it exists. */ +SecKeychainItemRef checkNCopyFirst(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n) { + CFArrayRef results = NULL; + if(n > 0) { + ok_status(SecItemCopyMatching(query, (CFTypeRef*) &results), "%s: SecItemCopyMatching", testName); + } else { + is(SecItemCopyMatching(query, (CFTypeRef*) &results), errSecItemNotFound, "%s: SecItemCopyMatching (for no items)", testName); + } + + SecKeychainItemRef item = NULL; + if(results) { + is(CFArrayGetCount(results), n, "%s: Wrong number of results", testName); + if(n >= 1) { + ok(item = (SecKeychainItemRef) CFArrayGetValueAtIndex(results, 0), "%s: Couldn't get item", testName); + } else { + pass("make test numbers match"); + } + } else if((!results) && n == 0) { + pass("%s: no results found (and none expected)", testName); + pass("make test numbers match"); + } else { + fail("%s: no results found (and %d expected)", testName, n); + fflush(stdout); CFShow(query); fflush(stdout); + pass("make test numbers match"); + } + + CFRetainSafe(item); + CFReleaseNull(results); + + CFRelease(query); + return item; +} + +void checkN(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n) { + SecKeychainItemRef item = checkNCopyFirst(testName, query, n); + CFReleaseSafe(item); +} + +#define checkNTests 3 + + +void readPasswordContentsWithResult(SecKeychainItemRef item, OSStatus expectedResult, CFStringRef expectedContents) { + if(!item) { + fail("no item passed to readPasswordContentsWithResult"); + fail("Match test numbers"); + fail("Match test numbers"); + return; + } + + CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne); + CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue); + + CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks); + CFArrayAppendValue((CFMutableArrayRef)itemList, item); + CFDictionarySetValue(query, kSecUseItemList, itemList); + + CFTypeRef results = NULL; + if(expectedContents) { + is(SecItemCopyMatching(query, (CFTypeRef*) &results), expectedResult, "%s: readPasswordContents: SecItemCopyMatching", testName); + CFReleaseNull(query); + + if(results) { + ok(CFGetTypeID(results) == CFDataGetTypeID(), "%s: result is not a data", testName); + + CFDataRef data = (CFDataRef) results; + CFStringRef str = CFStringCreateWithBytes(NULL, CFDataGetBytePtr(data), CFDataGetLength(data), kCFStringEncodingUTF8, false); + eq_cf(str, expectedContents, "%s: contents do not match", testName); + CFReleaseNull(str); + CFReleaseNull(results); + } else { + fail("Didn't get any results"); + fail("Match test numbers"); + } + } else { + is(SecItemCopyMatching(query, (CFTypeRef*) &results), expectedResult, "%s: readPasswordContents: expecting error %d", testName, (int) expectedResult); + pass("Match test numbers"); + pass("Match test numbers"); + } +} +#define readPasswordContentsWithResultTests 3 + +void readPasswordContents(SecKeychainItemRef item, CFStringRef expectedContents) { + return readPasswordContentsWithResult(item, errSecSuccess, expectedContents); +} +#define readPasswordContentsTests readPasswordContentsWithResultTests + +void changePasswordContents(SecKeychainItemRef item, CFStringRef newPassword) { + if(!item) { + fail("no item passed to changePasswordContents"); + return; + } + + CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne); + + CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks); + CFArrayAppendValue((CFMutableArrayRef)itemList, item); + CFDictionarySetValue(query, kSecUseItemList, itemList); + + CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDataRef data = CFDataCreate(NULL, (const UInt8*) CFStringGetCStringPtr(newPassword, kCFStringEncodingUTF8), CFStringGetLength(newPassword)); + CFDictionarySetValue(attrs, kSecValueData, data); + CFReleaseNull(data); + + ok_status(SecItemUpdate(query, attrs), "%s: SecItemUpdate", testName); +} +#define changePasswordContentsTests 1 + +void deleteItem(SecKeychainItemRef item) { + CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks); + CFArrayAppendValue((CFMutableArrayRef)itemList, item); + CFDictionarySetValue(query, kSecUseItemList, itemList); + + ok_status(SecItemDelete(query), "%s: SecItemDelete single item", testName); + CFReleaseNull(query); +} +#define deleteItemTests 1 + +void deleteItems(CFArrayRef items) { + if(!items) { + fail("no items passed to deleteItems"); + return; + } + + CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(query, kSecUseItemList, items); + + size_t count = (size_t) CFArrayGetCount(items); + if(count > 0) { + ok_status(SecItemDelete(query), "%s: SecItemDelete %ld items", testName, count); + } else { + is(SecItemDelete(query), errSecItemNotFound, "%s: SecItemDelete no items", testName); + } + CFReleaseNull(query); +} +#define deleteItemsTests 1 + +/* Checks in with securityd to see how many prompts were generated since the last call to this function, and tests against the number expected. + Returns the number generated since the last call. */ +uint32_t checkPrompts(uint32_t expectedSinceLastCall, char* explanation) { + uint32_t currentPrompts = UINT_MAX; + uint32_t newPrompts = UINT_MAX; + ok_status(SecKeychainGetUserPromptAttempts(¤tPrompts), "%s: SecKeychainGetUserPromptAttempts", testName); + + newPrompts = currentPrompts - promptAttempts; + + is(newPrompts, expectedSinceLastCall, "%s: wrong number of prompts: %s", testName, explanation); + promptAttempts = currentPrompts; + + return newPrompts; +} +#define checkPromptsTests 2 diff --git a/OSX/libsecurity_keychain/regressions/kc-keychain-file-helpers.h b/OSX/libsecurity_keychain/regressions/kc-keychain-file-helpers.h index b5baede4..271159fe 100644 --- a/OSX/libsecurity_keychain/regressions/kc-keychain-file-helpers.h +++ b/OSX/libsecurity_keychain/regressions/kc-keychain-file-helpers.h @@ -24,8 +24,12 @@ #ifndef kc_file_helpers_h #define kc_file_helpers_h +#include #include #include +#include +#include +#include "keychain_regressions.h" #pragma clang diagnostic push @@ -67,6 +71,12 @@ static void writeFile(const char* path, uint8_t* buf, size_t len) { sync(); } +SecKeychainRef CF_RETURNS_RETAINED getPopulatedTestKeychain(void); +#define getPopulatedTestKeychainTests 2 + +SecKeychainRef CF_RETURNS_RETAINED getEmptyTestKeychain(void); +#define getEmptyTestKeychainTests 1 + // The following keychain includes: // // security add-internet-password -s test_service_restrictive_acl -a test_account -j "a useful comment" -r "htps" -t dflt -w test_password test.keychain @@ -78,2305 +88,11 @@ static void writeFile(const char* path, uint8_t* buf, size_t len) { // Code Signing identity // S/MIME identity -const char * test_keychain_password = "password"; +extern const char * test_keychain_password; + +extern unsigned char test_keychain[]; -unsigned char test_keychain[] = { - 0x6b, 0x79, 0x63, 0x68, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xb3, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x03, 0x64, 0x00, 0x00, 0x1b, 0x70, - 0x00, 0x00, 0x4d, 0xe8, 0x00, 0x00, 0x4e, 0x10, 0x00, 0x00, 0x57, 0xe0, 0x00, 0x00, 0x6c, 0x88, 0x00, 0x00, 0x8b, 0x44, - 0x00, 0x00, 0x91, 0x20, 0x00, 0x00, 0x96, 0x4c, 0x00, 0x00, 0x97, 0x0c, 0x00, 0x00, 0xb2, 0x28, 0x00, 0x00, 0x03, 0x2c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x03, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x01, 0x14, - 0x00, 0x00, 0x01, 0x5c, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x02, 0x04, - 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x02, 0xd8, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, - 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x43, 0x53, 0x53, 0x4d, - 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, - 0x55, 0x54, 0x45, 0x53, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x19, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, - 0x41, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, - 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x50, 0x41, 0x52, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x4f, - 0x44, 0x55, 0x4c, 0x45, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x44, 0x42, 0x42, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1c, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, - 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, - 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d, - 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x50, 0x52, - 0x49, 0x56, 0x41, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x0a, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1f, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, - 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x53, 0x59, 0x4d, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, - 0x4b, 0x45, 0x59, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x22, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, - 0x44, 0x5f, 0x58, 0x35, 0x30, 0x39, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, - 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x01, 0x84, - 0x00, 0x00, 0x01, 0xc4, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x44, 0x00, 0x00, 0x02, 0x84, 0x00, 0x00, 0x02, 0xc4, - 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x03, 0x44, 0x00, 0x00, 0x03, 0x84, 0x00, 0x00, 0x03, 0xc4, 0x00, 0x00, 0x04, 0x04, - 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x04, 0x84, 0x00, 0x00, 0x04, 0xc4, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x05, 0x44, - 0x00, 0x00, 0x05, 0x84, 0x00, 0x00, 0x05, 0xc4, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x06, 0x44, 0x00, 0x00, 0x06, 0x84, - 0x00, 0x00, 0x06, 0xc4, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x84, 0x00, 0x00, 0x07, 0xc4, - 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x08, 0x44, 0x00, 0x00, 0x08, 0x84, 0x00, 0x00, 0x08, 0xc4, 0x00, 0x00, 0x09, 0x04, - 0x00, 0x00, 0x09, 0x44, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x09, 0xc4, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x44, - 0x00, 0x00, 0x0a, 0x84, 0x00, 0x00, 0x0a, 0xc4, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x0b, 0x44, 0x00, 0x00, 0x0b, 0x84, - 0x00, 0x00, 0x0b, 0xc4, 0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x0c, 0x44, 0x00, 0x00, 0x0c, 0x84, 0x00, 0x00, 0x0c, 0xc4, - 0x00, 0x00, 0x0d, 0x04, 0x00, 0x00, 0x0d, 0x44, 0x00, 0x00, 0x0d, 0x84, 0x00, 0x00, 0x0d, 0xc4, 0x00, 0x00, 0x0e, 0x04, - 0x00, 0x00, 0x0e, 0x44, 0x00, 0x00, 0x0e, 0x84, 0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x0f, 0x44, - 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0x0f, 0xc4, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x10, 0x84, - 0x00, 0x00, 0x10, 0xc4, 0x00, 0x00, 0x11, 0x04, 0x00, 0x00, 0x11, 0x44, 0x00, 0x00, 0x11, 0x84, 0x00, 0x00, 0x11, 0xc4, - 0x00, 0x00, 0x12, 0x04, 0x00, 0x00, 0x12, 0x44, 0x00, 0x00, 0x12, 0x84, 0x00, 0x00, 0x12, 0xc4, 0x00, 0x00, 0x13, 0x04, - 0x00, 0x00, 0x13, 0x44, 0x00, 0x00, 0x13, 0x84, 0x00, 0x00, 0x13, 0xc4, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x14, 0x44, - 0x00, 0x00, 0x14, 0x84, 0x00, 0x00, 0x14, 0xc4, 0x00, 0x00, 0x15, 0x04, 0x00, 0x00, 0x15, 0x44, 0x00, 0x00, 0x15, 0x84, - 0x00, 0x00, 0x15, 0xc4, 0x00, 0x00, 0x16, 0x04, 0x00, 0x00, 0x16, 0x44, 0x00, 0x00, 0x16, 0x84, 0x00, 0x00, 0x16, 0xc4, - 0x00, 0x00, 0x17, 0x04, 0x00, 0x00, 0x17, 0x44, 0x00, 0x00, 0x17, 0x84, 0x00, 0x00, 0x17, 0xc4, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x61, 0x63, 0x63, 0x74, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x73, 0x73, 0x69, 0x67, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, - 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x06, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0e, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x72, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x13, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x70, 0x74, 0x63, 0x6c, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, - 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x0d, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1d, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x27, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, - 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2c, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x36, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3b, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4a, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4f, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x6e, 0x62, 0x72, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x54, - 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x73, 0x75, 0x62, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x73, 0x6e, 0x62, 0x72, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x73, 0x6b, 0x69, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x59, - 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x78, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x02, 0xac, - 0x00, 0x00, 0x32, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x02, 0xac, 0x00, 0x00, 0x02, 0xfc, - 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x03, 0x9c, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x04, 0x98, - 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x05, 0x90, 0x00, 0x00, 0x05, 0xdc, 0x00, 0x00, 0x06, 0x2c, - 0x00, 0x00, 0x06, 0x7c, 0x00, 0x00, 0x06, 0xd4, 0x00, 0x00, 0x07, 0x24, 0x00, 0x00, 0x07, 0x74, 0x00, 0x00, 0x07, 0xc0, - 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x58, 0x00, 0x00, 0x08, 0xac, 0x00, 0x00, 0x08, 0xec, 0x00, 0x00, 0x09, 0x2c, - 0x00, 0x00, 0x09, 0x6c, 0x00, 0x00, 0x09, 0xac, 0x00, 0x00, 0x09, 0xec, 0x00, 0x00, 0x0a, 0x2c, 0x00, 0x00, 0x0a, 0x6c, - 0x00, 0x00, 0x0a, 0xbc, 0x00, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x0b, 0x48, 0x00, 0x00, 0x0b, 0x88, 0x00, 0x00, 0x0b, 0xc8, - 0x00, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x0c, 0x48, 0x00, 0x00, 0x0c, 0x88, 0x00, 0x00, 0x0c, 0xc8, 0x00, 0x00, 0x0d, 0x08, - 0x00, 0x00, 0x0d, 0x48, 0x00, 0x00, 0x0d, 0x88, 0x00, 0x00, 0x0d, 0xc8, 0x00, 0x00, 0x0e, 0x08, 0x00, 0x00, 0x0e, 0x48, - 0x00, 0x00, 0x0e, 0x88, 0x00, 0x00, 0x0e, 0xd8, 0x00, 0x00, 0x0f, 0x24, 0x00, 0x00, 0x0f, 0x64, 0x00, 0x00, 0x0f, 0xa4, - 0x00, 0x00, 0x0f, 0xe4, 0x00, 0x00, 0x10, 0x24, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00, 0x10, 0xa4, 0x00, 0x00, 0x10, 0xe4, - 0x00, 0x00, 0x11, 0x24, 0x00, 0x00, 0x11, 0x64, 0x00, 0x00, 0x11, 0xa4, 0x00, 0x00, 0x11, 0xe4, 0x00, 0x00, 0x12, 0x24, - 0x00, 0x00, 0x12, 0x64, 0x00, 0x00, 0x12, 0xa4, 0x00, 0x00, 0x12, 0xe4, 0x00, 0x00, 0x13, 0x24, 0x00, 0x00, 0x13, 0x64, - 0x00, 0x00, 0x13, 0xb4, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x14, 0xc0, - 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x40, 0x00, 0x00, 0x15, 0x80, 0x00, 0x00, 0x15, 0xc0, 0x00, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x16, 0x40, 0x00, 0x00, 0x16, 0x80, 0x00, 0x00, 0x16, 0xc0, 0x00, 0x00, 0x17, 0x0c, 0x00, 0x00, 0x17, 0x5c, - 0x00, 0x00, 0x17, 0xa8, 0x00, 0x00, 0x17, 0xf8, 0x00, 0x00, 0x18, 0x44, 0x00, 0x00, 0x18, 0x94, 0x00, 0x00, 0x18, 0xe0, - 0x00, 0x00, 0x19, 0x34, 0x00, 0x00, 0x19, 0x84, 0x00, 0x00, 0x19, 0xd0, 0x00, 0x00, 0x1a, 0x24, 0x00, 0x00, 0x1a, 0x78, - 0x00, 0x00, 0x1a, 0xc8, 0x00, 0x00, 0x1b, 0x14, 0x00, 0x00, 0x1b, 0x64, 0x00, 0x00, 0x1b, 0xb8, 0x00, 0x00, 0x1c, 0x08, - 0x00, 0x00, 0x1c, 0x5c, 0x00, 0x00, 0x1c, 0xa8, 0x00, 0x00, 0x1c, 0xf4, 0x00, 0x00, 0x1d, 0x40, 0x00, 0x00, 0x1d, 0x88, - 0x00, 0x00, 0x1d, 0xd4, 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1e, 0x78, 0x00, 0x00, 0x1e, 0xc0, 0x00, 0x00, 0x1f, 0x0c, - 0x00, 0x00, 0x1f, 0x58, 0x00, 0x00, 0x1f, 0xa8, 0x00, 0x00, 0x1f, 0xf4, 0x00, 0x00, 0x20, 0x44, 0x00, 0x00, 0x20, 0x90, - 0x00, 0x00, 0x20, 0xe0, 0x00, 0x00, 0x21, 0x2c, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x21, 0xd0, 0x00, 0x00, 0x22, 0x1c, - 0x00, 0x00, 0x22, 0x70, 0x00, 0x00, 0x22, 0xc4, 0x00, 0x00, 0x23, 0x14, 0x00, 0x00, 0x23, 0x60, 0x00, 0x00, 0x23, 0xb0, - 0x00, 0x00, 0x24, 0x04, 0x00, 0x00, 0x24, 0x54, 0x00, 0x00, 0x24, 0xa8, 0x00, 0x00, 0x24, 0xf4, 0x00, 0x00, 0x25, 0x40, - 0x00, 0x00, 0x25, 0x8c, 0x00, 0x00, 0x25, 0xd4, 0x00, 0x00, 0x26, 0x20, 0x00, 0x00, 0x26, 0x70, 0x00, 0x00, 0x26, 0xc4, - 0x00, 0x00, 0x27, 0x0c, 0x00, 0x00, 0x27, 0x58, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x27, 0xf4, 0x00, 0x00, 0x28, 0x40, - 0x00, 0x00, 0x28, 0x90, 0x00, 0x00, 0x28, 0xdc, 0x00, 0x00, 0x29, 0x2c, 0x00, 0x00, 0x29, 0x78, 0x00, 0x00, 0x29, 0xcc, - 0x00, 0x00, 0x2a, 0x1c, 0x00, 0x00, 0x2a, 0x68, 0x00, 0x00, 0x2a, 0xbc, 0x00, 0x00, 0x2b, 0x10, 0x00, 0x00, 0x2b, 0x60, - 0x00, 0x00, 0x2b, 0xac, 0x00, 0x00, 0x2b, 0xfc, 0x00, 0x00, 0x2c, 0x50, 0x00, 0x00, 0x2c, 0xa0, 0x00, 0x00, 0x2c, 0xf4, - 0x00, 0x00, 0x2d, 0x40, 0x00, 0x00, 0x2d, 0x8c, 0x00, 0x00, 0x2d, 0xd8, 0x00, 0x00, 0x2e, 0x20, 0x00, 0x00, 0x2e, 0x6c, - 0x00, 0x00, 0x2e, 0xbc, 0x00, 0x00, 0x2f, 0x10, 0x00, 0x00, 0x2f, 0x58, 0x00, 0x00, 0x2f, 0xa4, 0x00, 0x00, 0x2f, 0xf0, - 0x00, 0x00, 0x30, 0x40, 0x00, 0x00, 0x30, 0x90, 0x00, 0x00, 0x30, 0xdc, 0x00, 0x00, 0x31, 0x28, 0x00, 0x00, 0x31, 0x74, - 0x00, 0x00, 0x31, 0xc4, 0x00, 0x00, 0x32, 0x1c, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x44, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x44, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x44, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x4c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0d, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0e, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4d, 0x6f, 0x64, 0x75, - 0x6c, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x41, 0x64, 0x64, 0x69, 0x6e, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x53, 0x53, 0x49, 0x44, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0e, 0x53, 0x75, 0x62, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x64, 0x61, 0x74, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, - 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x15, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, - 0x73, 0x63, 0x72, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x1a, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, - 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x1b, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, - 0x69, 0x6e, 0x76, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1d, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x00, 0x6e, 0x65, 0x67, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, - 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x00, 0x67, 0x65, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x63, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x64, 0x65, 0x73, 0x63, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, - 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x27, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x02, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x63, 0x72, 0x70, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x69, 0x6e, 0x76, 0x69, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x6e, 0x65, 0x67, 0x61, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, - 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2f, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x02, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x72, 0x76, 0x72, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, - 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x34, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x02, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x63, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x6d, 0x64, 0x61, 0x74, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x01, 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x73, 0x63, 0x72, 0x70, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x69, 0x6e, 0x76, 0x69, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, - 0x6e, 0x65, 0x67, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x41, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x01, 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x73, 0x64, 0x6d, 0x6e, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, - 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, - 0x80, 0x00, 0x00, 0x01, 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x61, 0x74, 0x68, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x65, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, - 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, - 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x51, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, - 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x41, 0x70, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, - 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, - 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, - 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, - 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x54, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, - 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x4b, 0x65, 0x79, 0x53, - 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, - 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, - 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, - 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, - 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, - 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, - 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x12, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, - 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, - 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x5f, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, - 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x53, 0x69, 0x67, 0x6e, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x19, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, - 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x65, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x65, 0x79, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x0a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, - 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, - 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, - 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, - 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x10, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x09, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x0f, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x06, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, - 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, - 0x53, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x06, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, - 0x4b, 0x65, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x81, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, - 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x82, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, - 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x0d, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0b, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, - 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, - 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0e, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, - 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, - 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x92, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x96, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, - 0x66, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x99, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1a, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x08, 0x43, 0x65, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, - 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x63, 0x65, 0x6e, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, - 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, - 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x6c, 0x61, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, - 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, - 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9f, - 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x80, 0x00, 0x10, 0x00, 0x73, 0x75, 0x62, 0x6a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x53, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, - 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x73, 0x6e, 0x62, 0x72, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x80, 0x00, 0x10, 0x00, 0x73, 0x6b, 0x69, 0x64, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0xa3, - 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, - 0x80, 0x00, 0x10, 0x00, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, - 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x03, 0x20, - 0x00, 0x00, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xb2, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x51, - 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x5d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x79, - 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xbd, - 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, - 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed, - 0x00, 0x00, 0x02, 0xf1, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x74, 0x65, 0x78, 0x74, 0x20, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x82, 0x01, 0x0a, - 0x02, 0x82, 0x01, 0x01, 0x00, 0xb3, 0xaa, 0xa8, 0x77, 0xe7, 0x3e, 0x2d, 0x0c, 0xf4, 0x83, 0x55, 0xc2, 0x9e, 0x50, 0x10, - 0xc9, 0xef, 0xc8, 0x48, 0x38, 0xe4, 0x43, 0x96, 0xfa, 0x93, 0x32, 0xbf, 0x66, 0xad, 0x84, 0xa2, 0x8b, 0x6b, 0x07, 0x8c, - 0xc6, 0x93, 0x8c, 0x4d, 0x65, 0x0f, 0xad, 0x76, 0x73, 0x0c, 0x4d, 0x43, 0xee, 0x35, 0xd4, 0x68, 0x4a, 0x9a, 0x6d, 0x4d, - 0xa5, 0xae, 0x66, 0xcf, 0xfb, 0xbb, 0x93, 0xd3, 0x6a, 0xe3, 0xfc, 0x41, 0x97, 0xae, 0x90, 0xc3, 0xd8, 0x83, 0xfb, 0x8d, - 0x67, 0x84, 0xc1, 0xd5, 0x7d, 0x1d, 0x12, 0xca, 0x0c, 0xb5, 0xae, 0xf0, 0xe3, 0x36, 0x39, 0xf1, 0x68, 0x92, 0x6f, 0xda, - 0x2d, 0x48, 0x87, 0xf0, 0x4b, 0x15, 0x4e, 0x4f, 0x7a, 0x3a, 0x16, 0xb9, 0x02, 0x89, 0x95, 0x98, 0xab, 0xb2, 0x58, 0x5b, - 0x31, 0x7f, 0x49, 0x90, 0x48, 0xfd, 0x8d, 0x8a, 0x37, 0x3a, 0x4e, 0xd8, 0x00, 0x4a, 0xdc, 0xd4, 0x02, 0x9f, 0xcd, 0x4b, - 0xde, 0x75, 0x4a, 0xb2, 0x27, 0x8e, 0xe6, 0x2d, 0xea, 0x35, 0x89, 0x85, 0x8a, 0x37, 0x59, 0xd6, 0xd1, 0xf8, 0x36, 0x7c, - 0x93, 0x9e, 0xd6, 0xd1, 0xc3, 0xd9, 0x75, 0xa4, 0x4f, 0x40, 0x24, 0xe9, 0xc0, 0xde, 0xeb, 0xc0, 0x5e, 0xd6, 0x04, 0xe1, - 0xd0, 0x07, 0x29, 0xc1, 0x9d, 0x6f, 0x78, 0x2d, 0x5a, 0xef, 0xe6, 0xff, 0x25, 0x16, 0xcf, 0x60, 0x77, 0xa2, 0x10, 0x2b, - 0xa4, 0x2a, 0xff, 0x74, 0x3b, 0xe6, 0x4d, 0xc1, 0x13, 0xba, 0x8b, 0xe8, 0x15, 0x8e, 0xc7, 0xc3, 0xd4, 0x31, 0xb0, 0x99, - 0x51, 0x32, 0x30, 0x03, 0x0b, 0x1c, 0xa0, 0x0a, 0x17, 0x15, 0x34, 0x57, 0x38, 0xd3, 0x08, 0x13, 0xc4, 0xd6, 0x7c, 0x24, - 0x16, 0xd0, 0x2f, 0x00, 0x88, 0xd7, 0xd9, 0xca, 0x1e, 0x6b, 0x50, 0x3b, 0x5f, 0xb6, 0x08, 0xb1, 0x29, 0x42, 0x70, 0xf1, - 0x89, 0x02, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, - 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, - 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, - 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x51, - 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x5d, 0x00, 0x00, 0x02, 0x61, 0x00, 0x00, 0x02, 0x79, - 0x00, 0x00, 0x02, 0x7d, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5, - 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, - 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed, - 0x00, 0x00, 0x02, 0xf1, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0x00, 0x00, 0x02, 0xfd, 0xfa, 0xde, 0x07, 0x11, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x74, 0x65, 0x78, - 0x74, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x48, 0x39, 0x92, 0x01, 0x00, 0x00, 0x00, - 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb6, 0x07, 0xac, 0x5c, 0xc6, 0xcb, 0xf0, 0xb7, 0x97, 0x0d, 0x43, - 0x1a, 0xe9, 0x61, 0xe7, 0x34, 0x63, 0x6a, 0x26, 0x0d, 0x77, 0xba, 0x25, 0xaa, 0xc8, 0x46, 0xf8, 0xc9, 0xdd, 0x21, 0xb4, - 0x3e, 0x2e, 0x11, 0x8e, 0xb6, 0x72, 0xf2, 0x01, 0x16, 0x07, 0xcf, 0x88, 0x91, 0xc4, 0xc0, 0x48, 0x64, 0x41, 0x91, 0xf7, - 0x63, 0x72, 0xd5, 0x37, 0xef, 0x37, 0x62, 0xed, 0x33, 0xb3, 0xf9, 0x6e, 0x31, 0xd1, 0x68, 0xe7, 0xde, 0x62, 0x9f, 0x82, - 0xb8, 0x9e, 0x11, 0xe7, 0x66, 0x91, 0xc1, 0xbe, 0xe5, 0x5c, 0xd6, 0x71, 0x83, 0x91, 0xbc, 0x0f, 0xa8, 0x06, 0xc3, 0xe9, - 0xb6, 0x76, 0x16, 0xae, 0x69, 0x0a, 0x47, 0xe4, 0x65, 0xaa, 0x13, 0x71, 0x48, 0xb3, 0x5c, 0x25, 0xa5, 0x1a, 0xd0, 0x2a, - 0x57, 0x57, 0xf9, 0xb7, 0x13, 0xbd, 0xf4, 0x13, 0x5a, 0x11, 0x1b, 0xcc, 0xd8, 0x9a, 0x5f, 0x82, 0x3f, 0xa7, 0x6b, 0x64, - 0x47, 0x54, 0xb6, 0x81, 0xaf, 0xcb, 0x4b, 0x94, 0x39, 0x65, 0x15, 0xba, 0x6a, 0x02, 0x7c, 0x71, 0x30, 0x60, 0x21, 0x12, - 0x63, 0x28, 0xe0, 0x85, 0xca, 0xcc, 0x07, 0xb1, 0x13, 0x40, 0x19, 0x72, 0x02, 0x35, 0x0e, 0x2d, 0x4b, 0x8a, 0xcd, 0x1d, - 0x09, 0x65, 0xb0, 0x81, 0x49, 0xea, 0x70, 0x15, 0x92, 0x19, 0x7b, 0xfe, 0x15, 0xf7, 0x4a, 0x3f, 0x1e, 0x3c, 0x63, 0x7a, - 0x0f, 0x17, 0x32, 0x1a, 0xb7, 0x26, 0xa1, 0xa0, 0x9b, 0x3f, 0x4e, 0x7c, 0x38, 0xe6, 0x27, 0xbf, 0xa8, 0x1b, 0xf7, 0xbd, - 0x2d, 0xfd, 0x9b, 0x05, 0x0c, 0xaa, 0x81, 0xb8, 0x09, 0xd4, 0xe2, 0xe3, 0xbd, 0x6c, 0x70, 0xc0, 0x7e, 0x95, 0xd4, 0x0b, - 0x13, 0xab, 0xb8, 0xdd, 0x3d, 0x4c, 0x59, 0xf0, 0xc7, 0x8e, 0x47, 0xb5, 0xd8, 0x31, 0x78, 0x80, 0xd2, 0x5f, 0x0c, 0x0b, - 0xae, 0x22, 0xe7, 0x9e, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, - 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, - 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, - 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xb0, 0x00, 0x00, 0x00, 0x0b, - 0x00, 0x00, 0x06, 0x54, 0x00, 0x00, 0x07, 0x78, 0x00, 0x00, 0x07, 0xd8, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x48, - 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0xb8, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00, 0x09, 0x28, 0x00, 0x00, 0x09, 0x60, - 0x00, 0x00, 0x09, 0x98, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, - 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x98, - 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, - 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, - 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, - 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, - 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, - 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, - 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x07, 0xa0, 0x00, 0x00, 0x07, 0xbc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, - 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, - 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x38, 0x00, 0x00, 0x08, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xa8, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x08, 0xe0, 0x00, 0x00, 0x08, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x18, - 0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x50, 0x00, 0x00, 0x09, 0x58, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x88, 0x00, 0x00, 0x09, 0x90, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0xc0, 0x00, 0x00, 0x09, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14, 0xa8, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x10, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x06, 0xc4, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, - 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x06, 0x15, 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x06, 0x1d, 0x00, 0x00, 0x06, 0x21, - 0x00, 0x00, 0x06, 0x25, 0x00, 0x00, 0x06, 0x3d, 0x00, 0x00, 0x06, 0x41, 0x00, 0x00, 0x06, 0x6d, 0x00, 0x00, 0x06, 0x71, - 0x00, 0x00, 0x06, 0x75, 0x00, 0x00, 0x06, 0x79, 0x00, 0x00, 0x06, 0x85, 0x00, 0x00, 0x06, 0x91, 0x00, 0x00, 0x06, 0x95, - 0x00, 0x00, 0x06, 0x99, 0x00, 0x00, 0x06, 0x9d, 0x00, 0x00, 0x06, 0xa1, 0x00, 0x00, 0x06, 0xa5, 0x00, 0x00, 0x06, 0xa9, - 0x00, 0x00, 0x06, 0xad, 0x00, 0x00, 0x06, 0xb1, 0x00, 0x00, 0x06, 0xb5, 0x00, 0x00, 0x06, 0xb9, 0x00, 0x00, 0x06, 0xbd, - 0x00, 0x00, 0x06, 0xc1, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x05, 0x7c, - 0xce, 0x5e, 0x64, 0x56, 0xc9, 0x2c, 0x8c, 0xbb, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, - 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, - 0x39, 0xf9, 0x47, 0x1e, 0xec, 0x0d, 0xb8, 0x07, 0x55, 0xbc, 0xbf, 0x6e, 0xd7, 0xa7, 0xc4, 0x53, 0x73, 0x06, 0xa9, 0x05, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0xc0, 0x79, 0x0d, 0x4e, 0xd3, 0x15, 0x14, 0x9a, 0x46, 0xeb, 0x6d, - 0x81, 0xe0, 0xa8, 0x43, 0x02, 0x74, 0x53, 0x4b, 0x3a, 0x23, 0xf7, 0x6d, 0x16, 0x6f, 0x5d, 0x5a, 0xa9, 0x97, 0x54, 0x37, - 0xd0, 0x44, 0xd1, 0x9c, 0x15, 0x33, 0x05, 0xdb, 0x6b, 0xcb, 0x5c, 0xcd, 0x23, 0xc9, 0x65, 0x07, 0x79, 0x1b, 0x60, 0x2d, - 0xd6, 0x17, 0x2b, 0x45, 0x20, 0x8f, 0xb6, 0x31, 0x91, 0xc0, 0x59, 0x53, 0x87, 0xa0, 0x3c, 0xd1, 0x77, 0x97, 0x91, 0xd8, - 0x9c, 0xfc, 0x51, 0x4f, 0xfd, 0x21, 0x6a, 0x71, 0x12, 0x5a, 0x6e, 0x10, 0xd1, 0x5c, 0xe9, 0x7e, 0x24, 0xb8, 0xf3, 0x5d, - 0xab, 0x51, 0x2f, 0x67, 0xa7, 0x65, 0x5c, 0x27, 0xb8, 0xe2, 0x06, 0x98, 0xd2, 0x57, 0xb8, 0xc7, 0x4e, 0xea, 0x28, 0x23, - 0x6e, 0x90, 0x25, 0x2e, 0xb6, 0xf3, 0x5c, 0x18, 0xe8, 0x94, 0xa5, 0x7c, 0x55, 0xbf, 0x22, 0x94, 0xfc, 0x0e, 0xe7, 0x15, - 0xde, 0xe3, 0x72, 0x80, 0xe7, 0xf1, 0xfd, 0xd4, 0x0e, 0x2a, 0xda, 0x53, 0x56, 0xcb, 0xdb, 0xe3, 0x71, 0xc7, 0xc5, 0xd7, - 0x35, 0x95, 0x39, 0xf8, 0xee, 0x16, 0x22, 0x3c, 0x19, 0x3e, 0xd4, 0x03, 0x49, 0xe7, 0xf6, 0xb9, 0x50, 0x9f, 0x18, 0xee, - 0xdf, 0x7b, 0x79, 0xc4, 0x3f, 0xd4, 0x41, 0x45, 0xf2, 0xea, 0xdd, 0x5f, 0xda, 0x17, 0xd3, 0xb0, 0x50, 0xfc, 0x2c, 0xe9, - 0x6a, 0xb6, 0x35, 0xf3, 0xd7, 0xfd, 0xe6, 0x62, 0x51, 0x16, 0x5c, 0x8d, 0x26, 0xc3, 0x18, 0x9c, 0xf0, 0xb9, 0xe5, 0xa9, - 0x46, 0xd9, 0xe3, 0x80, 0x6c, 0xe3, 0x66, 0x70, 0xed, 0x4e, 0xfd, 0xf9, 0x8b, 0xdb, 0x06, 0x56, 0x3f, 0x2d, 0xfe, 0x74, - 0xee, 0x66, 0x75, 0x2a, 0xad, 0x1e, 0x41, 0x6c, 0x1b, 0x6a, 0xe4, 0x90, 0x76, 0x48, 0x27, 0x73, 0x4b, 0x13, 0xda, 0x72, - 0xa6, 0x7f, 0xc2, 0x7c, 0xb5, 0xca, 0x4c, 0x15, 0x64, 0x27, 0x9e, 0xc4, 0x9e, 0x3a, 0xb4, 0x13, 0x9d, 0xb8, 0x02, 0x3f, - 0x92, 0x6c, 0xe5, 0x73, 0x3e, 0x61, 0xbb, 0x01, 0xec, 0x81, 0x9b, 0x64, 0x59, 0x11, 0x4e, 0x42, 0x8b, 0x31, 0x97, 0x16, - 0x18, 0x53, 0x98, 0x82, 0x6e, 0xa5, 0x44, 0x7f, 0xcf, 0x05, 0x9c, 0x2c, 0x9d, 0x8f, 0xe3, 0x45, 0x57, 0xb2, 0xb5, 0x7a, - 0x71, 0x62, 0x25, 0x41, 0x8b, 0xed, 0xe9, 0x08, 0x46, 0x44, 0xda, 0xe3, 0xa3, 0xdf, 0x4b, 0x66, 0x77, 0x19, 0xc2, 0x4f, - 0xbb, 0xa7, 0xde, 0x4b, 0xa0, 0xbd, 0x95, 0x0f, 0xe1, 0x10, 0x49, 0x13, 0xa3, 0xec, 0x80, 0x27, 0xbb, 0x8b, 0xc8, 0xed, - 0x7a, 0x3a, 0x70, 0x5d, 0xea, 0x93, 0x6c, 0x0c, 0xc7, 0x2f, 0x41, 0x15, 0x64, 0x3d, 0x3a, 0x65, 0x02, 0x72, 0x78, 0xc9, - 0x35, 0x61, 0xe8, 0xd9, 0x63, 0x3f, 0x45, 0x7f, 0x04, 0xaf, 0x0b, 0x37, 0x7a, 0x66, 0x4e, 0x49, 0x3d, 0x6c, 0x3d, 0x2a, - 0xda, 0x0b, 0x81, 0x6d, 0x9f, 0x51, 0xea, 0xf6, 0x23, 0x6d, 0x7f, 0xcb, 0x75, 0x02, 0x49, 0x5e, 0x69, 0x57, 0x5b, 0x14, - 0xcb, 0xc2, 0xc8, 0xd4, 0xe4, 0x68, 0xab, 0xec, 0x51, 0x19, 0x80, 0xe4, 0xc1, 0xc7, 0x9b, 0x99, 0x15, 0xe1, 0x25, 0xf9, - 0x58, 0x18, 0x45, 0x0c, 0xde, 0xa7, 0x14, 0xe6, 0x96, 0xd5, 0xb8, 0x36, 0x83, 0x35, 0xfe, 0x77, 0x51, 0x4a, 0x57, 0x2e, - 0xaa, 0x26, 0x13, 0x23, 0x5d, 0x7d, 0xcf, 0x93, 0xce, 0x4a, 0x9a, 0xff, 0x03, 0x48, 0xf7, 0x10, 0x09, 0xe2, 0x01, 0xbb, - 0x17, 0xb6, 0x9d, 0xc7, 0x27, 0xe2, 0xd1, 0x26, 0xf1, 0x7c, 0xd0, 0x53, 0xf6, 0x53, 0x76, 0xfd, 0x39, 0x58, 0xd2, 0xc8, - 0xa8, 0x90, 0xa9, 0x75, 0x16, 0xaf, 0xe2, 0x91, 0x40, 0x53, 0x2e, 0x08, 0xdd, 0xb9, 0xfb, 0x17, 0x51, 0x51, 0x1b, 0xb9, - 0x12, 0xf0, 0x31, 0xd8, 0x48, 0x8f, 0x7d, 0x08, 0x9d, 0x1d, 0x2a, 0xb5, 0xcd, 0x46, 0x23, 0x2c, 0xf3, 0xb5, 0x11, 0x91, - 0x7f, 0x3c, 0x7a, 0x5e, 0x75, 0x90, 0x0e, 0xc0, 0xc0, 0x4f, 0x5e, 0xcb, 0xbc, 0x33, 0x09, 0x88, 0x4e, 0x68, 0xac, 0xba, - 0x46, 0x31, 0x41, 0x98, 0xf5, 0x75, 0x87, 0xf6, 0x0c, 0x0c, 0xaa, 0x84, 0x75, 0xe4, 0xfa, 0xa3, 0x1e, 0xe1, 0xe2, 0x88, - 0x09, 0xf0, 0x57, 0x8b, 0xdc, 0x47, 0x7b, 0xff, 0x39, 0xac, 0x51, 0x8b, 0x00, 0x08, 0xc0, 0x9f, 0xd4, 0xa4, 0xbe, 0xe5, - 0x41, 0x8b, 0xc5, 0x66, 0xdb, 0xed, 0x08, 0x0b, 0xdf, 0xa4, 0x2b, 0x5a, 0x59, 0xde, 0x0e, 0x9c, 0x8b, 0x7f, 0xd1, 0x80, - 0x4d, 0xf9, 0x22, 0x60, 0x2c, 0xd4, 0xf9, 0x1c, 0xd7, 0xf5, 0xbd, 0x64, 0x7f, 0x4f, 0xeb, 0xf8, 0xa5, 0xb2, 0x34, 0x3d, - 0xfa, 0x07, 0xef, 0x44, 0x3c, 0x00, 0x2c, 0xec, 0x36, 0x36, 0xdd, 0xd5, 0x5c, 0xbd, 0x6b, 0x27, 0xba, 0x13, 0x91, 0x90, - 0x58, 0xe7, 0x75, 0x89, 0x00, 0x6b, 0x5a, 0x0c, 0x35, 0x9c, 0xe3, 0x8a, 0xd8, 0x46, 0xd2, 0x15, 0x14, 0x8b, 0x8b, 0xff, - 0x6a, 0x35, 0xf9, 0xd7, 0x65, 0x67, 0x56, 0x6d, 0xd5, 0x2d, 0x9c, 0xd6, 0xb1, 0xe2, 0x9a, 0xb0, 0xfa, 0x0e, 0xa2, 0xd5, - 0x5d, 0x30, 0x15, 0x8e, 0x48, 0x59, 0xd0, 0x13, 0xa7, 0x2b, 0x40, 0x97, 0x8c, 0xe4, 0x02, 0x38, 0x28, 0x54, 0x53, 0x6c, - 0x1c, 0xc7, 0x38, 0x06, 0xe9, 0xfc, 0x2d, 0xd5, 0x59, 0x74, 0x77, 0x62, 0x14, 0xf2, 0xa7, 0x7e, 0xfe, 0x59, 0xbf, 0xdf, - 0x8b, 0x6e, 0xd7, 0x66, 0xd1, 0x6a, 0xb9, 0xe6, 0x35, 0x98, 0xc6, 0x76, 0x44, 0x38, 0xb4, 0xe8, 0x3c, 0xf5, 0x3c, 0x27, - 0xb9, 0xa1, 0x21, 0x7d, 0x17, 0xf9, 0xb3, 0x1e, 0x30, 0xe7, 0xab, 0xd5, 0x2d, 0x8c, 0x02, 0xc3, 0xa4, 0x3c, 0xf4, 0x09, - 0x9f, 0x17, 0xc1, 0xce, 0xc9, 0xf5, 0xdf, 0xdb, 0x8b, 0xf5, 0x05, 0x14, 0x6d, 0x74, 0xdf, 0xa9, 0x0b, 0x87, 0x98, 0x17, - 0xf3, 0x68, 0x8d, 0xb3, 0xbc, 0x86, 0x3a, 0x47, 0x1d, 0x29, 0x80, 0x40, 0xba, 0xb0, 0x3d, 0x65, 0x0d, 0xd7, 0x95, 0x4a, - 0x79, 0x0d, 0x34, 0x20, 0x72, 0x25, 0xaa, 0x71, 0x43, 0x5c, 0x52, 0x0b, 0x69, 0xde, 0xf7, 0xc5, 0xfd, 0xdb, 0x41, 0x05, - 0xb1, 0xde, 0x94, 0xdb, 0xc4, 0xe4, 0x85, 0xf2, 0x6c, 0xc5, 0xd1, 0x04, 0xcd, 0xd7, 0x84, 0x0b, 0xd8, 0xa8, 0x2c, 0x68, - 0xfd, 0xe7, 0x30, 0xaf, 0x6e, 0xae, 0x02, 0x3f, 0xea, 0x13, 0x68, 0xb0, 0xd1, 0xef, 0x6d, 0x78, 0xf8, 0x77, 0x3e, 0xe8, - 0x03, 0x05, 0x6e, 0x00, 0x59, 0xf1, 0xde, 0x57, 0xbe, 0xfa, 0x6b, 0xde, 0x47, 0x86, 0x21, 0xa0, 0x8e, 0xcc, 0x0b, 0x15, - 0x7e, 0x7d, 0xd2, 0x59, 0x37, 0x7f, 0x74, 0xc5, 0x79, 0x8e, 0xf0, 0x37, 0x9b, 0xb3, 0x0e, 0x7f, 0x14, 0x91, 0x0e, 0xe5, - 0xe8, 0xdf, 0xf7, 0xdf, 0x6b, 0x59, 0x79, 0x37, 0x90, 0x99, 0xc8, 0xff, 0xb2, 0xe9, 0xe4, 0x35, 0x8c, 0x20, 0xde, 0x8c, - 0x6c, 0xb8, 0x87, 0x16, 0xdd, 0xc4, 0x4b, 0x5e, 0x93, 0x38, 0x06, 0x0f, 0x4a, 0xb0, 0xba, 0xe1, 0xc5, 0xb1, 0x5d, 0x5f, - 0x3a, 0x2e, 0x84, 0x56, 0x72, 0x13, 0xb2, 0xb4, 0xdf, 0xc0, 0x36, 0xe6, 0xf2, 0xee, 0x77, 0x93, 0xc1, 0xc7, 0xc5, 0xe5, - 0x58, 0x66, 0x3e, 0x8c, 0x5d, 0xe3, 0x5d, 0xbd, 0x43, 0xf6, 0x72, 0x51, 0xe7, 0x4c, 0xd4, 0x2f, 0x46, 0x12, 0x66, 0xc2, - 0x7a, 0xd4, 0xd9, 0x75, 0x25, 0xa5, 0x63, 0x60, 0x9c, 0xc4, 0xff, 0x0a, 0xec, 0x8d, 0x13, 0x22, 0x3e, 0x95, 0xe8, 0xd9, - 0xd4, 0xa4, 0x12, 0xba, 0x46, 0x93, 0x1f, 0x6b, 0x9f, 0xb2, 0xba, 0xca, 0x39, 0xda, 0x32, 0xe5, 0x5c, 0xb3, 0x86, 0xc9, - 0x86, 0xb9, 0x9c, 0x92, 0x72, 0xe4, 0xa7, 0x53, 0xe4, 0x39, 0x07, 0x96, 0xc6, 0x18, 0xbc, 0xfc, 0x2e, 0x5f, 0xd6, 0x15, - 0x2c, 0x73, 0x01, 0x05, 0x74, 0xd7, 0x9a, 0x34, 0x35, 0x56, 0x32, 0xb7, 0x50, 0x22, 0x76, 0x66, 0x4d, 0x6f, 0xd1, 0x19, - 0x6a, 0x79, 0xc1, 0x3f, 0x15, 0x21, 0x04, 0x14, 0x34, 0xc9, 0x9a, 0xdb, 0x25, 0x0d, 0xfb, 0xa9, 0x53, 0xc0, 0x5f, 0xac, - 0xb7, 0xec, 0x67, 0xac, 0x8e, 0x46, 0x4c, 0xd7, 0x1b, 0x9b, 0x25, 0x87, 0x97, 0x73, 0xd9, 0xc8, 0xb3, 0x65, 0x22, 0x3b, - 0x35, 0xc0, 0x2f, 0xf5, 0x7d, 0xa4, 0x9b, 0x79, 0x92, 0xfb, 0xb6, 0x0b, 0xc9, 0xf9, 0x88, 0xc5, 0x5b, 0x88, 0x21, 0x0d, - 0xcf, 0xd9, 0x83, 0x6d, 0xae, 0x58, 0x3f, 0xac, 0x88, 0x16, 0xae, 0x3f, 0xb5, 0xdb, 0x78, 0x1c, 0x03, 0x3a, 0x19, 0xf1, - 0xbe, 0xc6, 0x46, 0x12, 0x6b, 0x18, 0x0b, 0x70, 0x83, 0x2d, 0x2f, 0x16, 0xac, 0xa9, 0x31, 0x2d, 0xf3, 0xe5, 0xd7, 0xe1, - 0x0e, 0x0e, 0x23, 0xb3, 0x9e, 0xc5, 0x6e, 0x35, 0xb7, 0xc4, 0x7f, 0xac, 0x60, 0x92, 0xde, 0x73, 0x3b, 0x02, 0xb6, 0xf5, - 0x97, 0xe6, 0xe1, 0x55, 0x50, 0x72, 0xd2, 0xb4, 0xbd, 0xcd, 0x7e, 0x11, 0xe4, 0x7b, 0x4b, 0xa5, 0x6b, 0x7e, 0xbf, 0xb8, - 0x4a, 0x1f, 0xf6, 0x34, 0x29, 0xee, 0x28, 0xb0, 0x45, 0x7d, 0x48, 0xc2, 0x18, 0xb2, 0x15, 0x0c, 0xe5, 0x5a, 0x3e, 0xee, - 0xdd, 0x1f, 0x20, 0x7b, 0xe6, 0x79, 0x60, 0xee, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, - 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, - 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, - 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x08, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x49, 0x00, 0x00, 0x09, 0x4d, 0x00, 0x00, 0x09, 0x61, - 0x00, 0x00, 0x09, 0x65, 0x00, 0x00, 0x09, 0x69, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x00, 0x09, 0x71, 0x00, 0x00, 0x09, 0x89, - 0x00, 0x00, 0x09, 0x8d, 0x00, 0x00, 0x09, 0xb9, 0x00, 0x00, 0x09, 0xbd, 0x00, 0x00, 0x09, 0xc1, 0x00, 0x00, 0x09, 0xc5, - 0x00, 0x00, 0x09, 0xd1, 0x00, 0x00, 0x09, 0xdd, 0x00, 0x00, 0x09, 0xe1, 0x00, 0x00, 0x09, 0xe5, 0x00, 0x00, 0x09, 0xe9, - 0x00, 0x00, 0x09, 0xed, 0x00, 0x00, 0x09, 0xf1, 0x00, 0x00, 0x09, 0xf5, 0x00, 0x00, 0x09, 0xf9, 0x00, 0x00, 0x09, 0xfd, - 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x09, 0x00, 0x00, 0x0a, 0x0d, 0xfa, 0xde, 0x07, 0x11, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x08, 0xc4, 0x7a, 0x50, 0x55, 0x75, 0xed, 0x3d, 0xfc, 0x68, - 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0xb4, 0x4e, 0xa3, 0xa8, 0x86, 0x4f, 0x76, 0xe9, - 0x0f, 0x06, 0x2d, 0xca, 0x91, 0x26, 0x8e, 0x86, 0x1a, 0x1f, 0xb9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, - 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0xf7, 0xc4, 0x67, 0x03, 0x4c, 0xab, 0x35, 0xae, - 0x20, 0x64, 0x45, 0xf0, 0xe3, 0x48, 0xbc, 0xba, 0x5f, 0xac, 0x81, 0xda, 0x00, 0x00, 0x00, 0x74, 0x2f, 0x53, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x43, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x73, 0x73, - 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, - 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, - 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x14, 0xf7, 0xc4, 0x67, 0x03, 0x4c, 0xab, 0x35, 0xae, 0x20, 0x64, 0x45, 0xf0, 0xe3, 0x48, 0xbc, 0xba, - 0x5f, 0xac, 0x81, 0xda, 0x00, 0x00, 0x00, 0x74, 0x2f, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x4c, 0x69, 0x62, 0x72, - 0x61, 0x72, 0x79, 0x2f, 0x43, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2e, 0x61, - 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x10, 0x49, 0xe1, 0x42, - 0x39, 0xee, 0xe2, 0xbd, 0x76, 0x61, 0x00, 0x6f, 0xe5, 0xf4, 0xbe, 0xdb, 0xbc, 0x89, 0xbe, 0x56, 0x00, 0x00, 0x00, 0x44, - 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x4d, 0x61, 0x69, 0x6c, 0x2e, 0x61, - 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x61, - 0x69, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, - 0x55, 0x29, 0x46, 0xa2, 0xfb, 0x92, 0xda, 0xe4, 0xf8, 0x4c, 0x7d, 0xdd, 0xc3, 0x4e, 0x52, 0x62, 0xff, 0x0f, 0xd2, 0x04, - 0x00, 0x00, 0x00, 0x40, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x62, 0x69, 0x6e, 0x2f, 0x72, 0x61, 0x63, 0x6f, 0x6f, 0x6e, - 0x00, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x72, 0x61, - 0x63, 0x6f, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x5c, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1d, - 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, - 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x84, 0x5f, 0xda, 0x57, 0x4e, 0xc0, 0xb5, 0x32, 0xdf, 0xc4, 0x87, 0x7f, 0x8c, 0x04, 0x1f, 0x65, 0xa2, 0x23, 0x20, 0x8c, - 0xab, 0x49, 0x2f, 0xff, 0x12, 0xfa, 0x57, 0x33, 0xf8, 0xcb, 0x7a, 0xcd, 0xc4, 0x7b, 0xc0, 0xf6, 0xf7, 0xe7, 0x2f, 0x7d, - 0x3f, 0xec, 0xf5, 0x8a, 0xee, 0x1e, 0x26, 0xe9, 0x12, 0x96, 0xdb, 0xa2, 0x2a, 0xf6, 0xb9, 0x3c, 0x68, 0x14, 0x49, 0x86, - 0x00, 0xc0, 0xaa, 0x29, 0xd3, 0xad, 0x4b, 0x48, 0xca, 0x48, 0x3f, 0xdb, 0x36, 0xdd, 0x3d, 0x3b, 0x18, 0x59, 0x26, 0x2a, - 0x9e, 0x5f, 0x86, 0xe9, 0x4b, 0xaa, 0x83, 0x60, 0x20, 0x36, 0x1e, 0x59, 0x17, 0x33, 0x5b, 0x20, 0x42, 0x7a, 0x59, 0xfd, - 0xb3, 0xa2, 0x5f, 0x2b, 0xdb, 0x63, 0x7e, 0x66, 0xee, 0x5e, 0xf5, 0x22, 0x0c, 0x10, 0x61, 0xd3, 0x9e, 0x3d, 0xce, 0x62, - 0x6b, 0xc3, 0x97, 0x86, 0x68, 0x61, 0x2a, 0x31, 0xaa, 0x7d, 0x5d, 0x18, 0x1f, 0xe9, 0xc3, 0x12, 0xb7, 0x0d, 0x14, 0x84, - 0x5c, 0xa0, 0x84, 0x0c, 0x07, 0xef, 0x01, 0xf4, 0xd3, 0xa1, 0x14, 0xa8, 0x5a, 0xb8, 0x15, 0xb7, 0x1b, 0x7a, 0x4a, 0x12, - 0x2f, 0x9d, 0x8f, 0x79, 0xb1, 0x74, 0x3e, 0x50, 0xd5, 0x99, 0x9c, 0x26, 0x7d, 0x37, 0xaf, 0xc7, 0x7b, 0x15, 0x8c, 0x07, - 0xae, 0x74, 0xef, 0xc3, 0xb1, 0x6a, 0xa2, 0x76, 0xf9, 0x6d, 0x6e, 0xc2, 0x6a, 0x01, 0x9a, 0x5f, 0x23, 0xf4, 0xd5, 0xe3, - 0x6a, 0x34, 0x86, 0x1e, 0x9d, 0xed, 0x5c, 0x09, 0xd3, 0xba, 0xff, 0x2d, 0xbe, 0x4b, 0xbb, 0x6c, 0x6a, 0x20, 0xc9, 0x8b, - 0x51, 0xcd, 0x4c, 0x91, 0x51, 0x6d, 0xf5, 0x80, 0x42, 0x31, 0xc1, 0x3a, 0x10, 0xdc, 0xb4, 0x92, 0x97, 0x18, 0xcc, 0x26, - 0xf1, 0xe6, 0x18, 0xe1, 0x97, 0x21, 0x94, 0x3d, 0xca, 0xa7, 0xb5, 0xcd, 0xce, 0x53, 0x7b, 0x16, 0x0b, 0x80, 0x8d, 0x4c, - 0xc8, 0x28, 0xc8, 0x55, 0xcf, 0xc7, 0xba, 0xd1, 0x05, 0x6a, 0x66, 0x72, 0x51, 0xb2, 0xd4, 0x3d, 0x81, 0x8d, 0xc5, 0xb3, - 0x86, 0xa6, 0x02, 0x53, 0x16, 0x2a, 0x2a, 0x40, 0xf1, 0x8d, 0xff, 0x42, 0x9a, 0x12, 0xd2, 0x46, 0x1d, 0x42, 0x98, 0x1f, - 0x1c, 0x52, 0x3f, 0x11, 0xa7, 0x12, 0xa7, 0xba, 0xb7, 0x84, 0xba, 0x80, 0xdf, 0x3e, 0x89, 0xcd, 0x81, 0x05, 0x98, 0x0a, - 0x92, 0x3e, 0x4b, 0x61, 0x44, 0x2f, 0xb8, 0xfe, 0x86, 0x56, 0x6b, 0xe1, 0xc0, 0xb4, 0x09, 0x52, 0x6c, 0xb2, 0xff, 0x1f, - 0xe7, 0x74, 0x98, 0xb6, 0x65, 0x47, 0x31, 0x5a, 0x33, 0x3a, 0x8c, 0x05, 0x18, 0xa5, 0x25, 0xc6, 0xb7, 0x18, 0x29, 0xf9, - 0x87, 0x7c, 0x3c, 0x3d, 0x70, 0x56, 0x60, 0xfe, 0x0c, 0xb9, 0x17, 0x89, 0xa0, 0x72, 0xe6, 0xa5, 0x2f, 0xa6, 0xa9, 0xc4, - 0x34, 0x5a, 0xbe, 0x0d, 0xa5, 0xf3, 0xac, 0xe8, 0x69, 0xa8, 0x2e, 0x50, 0xa2, 0xc1, 0x99, 0x7e, 0x7c, 0xd2, 0xd7, 0x60, - 0x1b, 0x41, 0xe4, 0x1f, 0x76, 0x5c, 0xeb, 0x1b, 0x28, 0x53, 0xd3, 0xab, 0x48, 0xd0, 0x7f, 0xb8, 0x9d, 0x70, 0x39, 0x8a, - 0xcd, 0x3c, 0x0f, 0x03, 0x5e, 0xe8, 0xa9, 0x95, 0x60, 0x54, 0x93, 0xfa, 0xd1, 0x9b, 0x49, 0xdb, 0x34, 0x32, 0x36, 0x38, - 0x56, 0xbb, 0xbf, 0xcf, 0x54, 0xe6, 0x5c, 0xa2, 0x8a, 0x9e, 0x73, 0x83, 0xa0, 0x53, 0x71, 0xfd, 0xef, 0x49, 0x1a, 0xa7, - 0x06, 0xca, 0x90, 0xd5, 0x2f, 0x31, 0xb4, 0x52, 0x0f, 0xaf, 0xfe, 0x6c, 0x19, 0x6d, 0xca, 0x11, 0xaa, 0xaf, 0x24, 0x21, - 0x47, 0x7f, 0x15, 0x47, 0x51, 0x96, 0x59, 0x3b, 0x27, 0x13, 0xc6, 0x50, 0x7b, 0x1c, 0x84, 0x0d, 0x61, 0x3d, 0x51, 0x58, - 0x9c, 0xe4, 0x65, 0x06, 0x1f, 0x7b, 0x91, 0x98, 0x7d, 0x35, 0x8c, 0x9f, 0xba, 0x38, 0x90, 0x89, 0xa2, 0xae, 0x68, 0x68, - 0x4b, 0x11, 0x2f, 0xea, 0x4d, 0xcb, 0x01, 0x59, 0x94, 0x26, 0x52, 0x37, 0x01, 0x6e, 0xfb, 0x01, 0x8b, 0x61, 0x59, 0x5b, - 0x49, 0xdf, 0xf2, 0x1c, 0x48, 0xbc, 0xed, 0x98, 0x8f, 0x09, 0x38, 0xa2, 0xf8, 0x27, 0xbb, 0x1a, 0x04, 0xcf, 0xd0, 0x4a, - 0x93, 0x32, 0xb8, 0x9d, 0x2f, 0x9c, 0xf3, 0xb2, 0xa8, 0x56, 0x47, 0xff, 0xa1, 0x28, 0x60, 0x6b, 0xc2, 0x3c, 0x1b, 0x48, - 0x5d, 0xc9, 0x05, 0x39, 0x98, 0xe5, 0x98, 0xfb, 0x17, 0x3f, 0x6d, 0x41, 0x8d, 0xc5, 0xa1, 0xee, 0x31, 0x19, 0x00, 0x2d, - 0xfb, 0x1e, 0x8f, 0x5f, 0x72, 0x6a, 0x92, 0x64, 0x01, 0xad, 0xcc, 0x90, 0x14, 0x48, 0x83, 0x88, 0x2e, 0xc1, 0x58, 0xe5, - 0x33, 0xa4, 0x19, 0xc3, 0x1d, 0xee, 0x06, 0xb6, 0x96, 0xb7, 0x57, 0x04, 0xa5, 0x4a, 0xa0, 0xa5, 0x1b, 0xa5, 0xda, 0x91, - 0xb7, 0x2c, 0xcd, 0x6d, 0x81, 0xff, 0x9f, 0xac, 0xc9, 0x05, 0x26, 0x8f, 0xb2, 0x37, 0x3c, 0xb8, 0x53, 0xab, 0x2b, 0xaf, - 0x9e, 0x22, 0xd2, 0xcd, 0xf4, 0x65, 0xf3, 0x84, 0x68, 0x83, 0xc2, 0xf8, 0xb7, 0x05, 0x25, 0xfe, 0x08, 0x2c, 0xb2, 0xb4, - 0xf3, 0x95, 0x63, 0x9a, 0xcc, 0x9d, 0xb1, 0xee, 0x5c, 0x53, 0x3b, 0x6b, 0xab, 0x0e, 0x95, 0x50, 0xcc, 0x8e, 0xc3, 0x97, - 0x43, 0x67, 0xe5, 0x49, 0xd0, 0x20, 0xbd, 0xda, 0x45, 0x6c, 0xef, 0x9a, 0xc7, 0x47, 0xdc, 0x7f, 0xda, 0xab, 0xf2, 0x8a, - 0xc5, 0x4f, 0xc5, 0xdb, 0xba, 0x87, 0x5f, 0xc1, 0xe0, 0x12, 0xc0, 0xb1, 0x3e, 0x1b, 0x72, 0x34, 0x00, 0x9f, 0x0a, 0xb4, - 0x99, 0xf8, 0x33, 0xe7, 0xb7, 0xc6, 0xc0, 0xed, 0xe6, 0x2c, 0x1b, 0x29, 0x9c, 0xfd, 0xeb, 0x6f, 0x9b, 0x0a, 0x55, 0xd2, - 0x09, 0xa2, 0x64, 0x49, 0x39, 0x30, 0x33, 0xb2, 0x77, 0x31, 0x32, 0x81, 0x25, 0x58, 0x66, 0x4d, 0xd2, 0xc2, 0xa6, 0x18, - 0xdc, 0xfc, 0x0a, 0x73, 0x5f, 0xbc, 0xcc, 0xef, 0xfe, 0xee, 0x1d, 0x3d, 0xb8, 0x21, 0xfb, 0x52, 0x25, 0x6f, 0xc3, 0x99, - 0x67, 0xa1, 0x69, 0x20, 0xb3, 0x01, 0xb4, 0x75, 0xbe, 0x08, 0x49, 0x2e, 0xe3, 0x6f, 0x1a, 0xd0, 0xe9, 0x7c, 0xec, 0xbf, - 0x98, 0x45, 0x82, 0xf8, 0xc4, 0x77, 0x74, 0x20, 0xc9, 0x5f, 0xa1, 0x8b, 0xf4, 0xa8, 0x4d, 0x12, 0xd5, 0x92, 0xd1, 0xe1, - 0x42, 0x4b, 0xa2, 0x45, 0x18, 0x60, 0xaf, 0x9a, 0xf2, 0xe4, 0xcf, 0x3e, 0x66, 0x87, 0x12, 0x0e, 0xa7, 0x55, 0x53, 0x96, - 0xcb, 0xcf, 0xd3, 0x34, 0xab, 0xdd, 0x20, 0x0f, 0x62, 0x9a, 0xb4, 0x86, 0x2f, 0x9f, 0x01, 0xda, 0xd6, 0xe6, 0x2b, 0xe2, - 0x5b, 0xb9, 0x74, 0xd8, 0x28, 0xad, 0x94, 0x89, 0x3e, 0x3a, 0x2a, 0x82, 0xa2, 0x0a, 0x7b, 0x4b, 0x4f, 0x3f, 0xed, 0x7f, - 0x2a, 0x3a, 0x06, 0xc8, 0xd4, 0x65, 0xcd, 0x60, 0x19, 0x79, 0x36, 0x31, 0x4c, 0xc1, 0x1e, 0x55, 0x22, 0x4f, 0x6e, 0xe0, - 0x1b, 0xab, 0x0b, 0x49, 0xa8, 0x9f, 0xf9, 0xc9, 0x6c, 0xd4, 0xd6, 0xfa, 0x07, 0xcd, 0xf5, 0xe7, 0x94, 0x51, 0x1b, 0x3d, - 0xc5, 0x00, 0x79, 0x38, 0xaf, 0xc0, 0x23, 0x60, 0x2b, 0x92, 0xda, 0x76, 0x69, 0xf7, 0xda, 0x23, 0xf9, 0xa6, 0x21, 0x34, - 0xc6, 0xf3, 0xc3, 0x69, 0xa6, 0x25, 0x87, 0x70, 0x5c, 0x0c, 0xc1, 0xfc, 0x9c, 0x30, 0xbc, 0xdf, 0x26, 0xbe, 0x4b, 0x49, - 0x44, 0xdd, 0x2f, 0x21, 0xc1, 0xa8, 0xcd, 0x54, 0x7a, 0xa4, 0x1b, 0xae, 0x82, 0xce, 0x05, 0x50, 0x9c, 0xb6, 0x85, 0x5d, - 0xf9, 0xbd, 0xdd, 0x4a, 0x56, 0x51, 0x32, 0x50, 0xdd, 0xaa, 0x55, 0xfe, 0x26, 0x3c, 0xee, 0x36, 0xa4, 0xa8, 0x53, 0x66, - 0x72, 0x89, 0xf6, 0xa3, 0x25, 0x7a, 0x23, 0x53, 0x29, 0x4d, 0x34, 0x29, 0x62, 0x94, 0x4f, 0x4f, 0x1b, 0x53, 0xcb, 0xc1, - 0x7c, 0xd1, 0x50, 0x8e, 0xa3, 0x19, 0x89, 0xfa, 0x90, 0x42, 0x69, 0x16, 0xd0, 0x6f, 0xf8, 0x7a, 0xc2, 0x9e, 0x67, 0xe8, - 0xe8, 0xff, 0xf1, 0x61, 0x7b, 0x31, 0x19, 0xcf, 0xf1, 0x27, 0xee, 0xab, 0x63, 0xe8, 0xdb, 0xf7, 0x4c, 0xbf, 0xcf, 0x2f, - 0xe7, 0x83, 0x92, 0xf8, 0x6d, 0x15, 0x9e, 0x1d, 0x77, 0xef, 0x40, 0x79, 0x58, 0xe4, 0xf9, 0xa7, 0x3d, 0xb6, 0x2d, 0xd0, - 0xfc, 0x01, 0x66, 0x20, 0x2c, 0xd1, 0x29, 0x86, 0x9b, 0x88, 0xcd, 0x98, 0xb4, 0x66, 0x61, 0x94, 0x58, 0x56, 0xf4, 0xff, - 0x60, 0x90, 0xf2, 0x8c, 0x07, 0x1c, 0x0b, 0x13, 0xfe, 0xb6, 0x58, 0x15, 0x6a, 0x8a, 0xd7, 0x98, 0xb2, 0x3e, 0xee, 0x49, - 0xdb, 0x3a, 0x0f, 0x98, 0x27, 0xc6, 0x88, 0xc5, 0x15, 0xe5, 0x67, 0x08, 0x09, 0xfc, 0x63, 0x6c, 0x8f, 0x30, 0xf4, 0x95, - 0xb7, 0x69, 0xd4, 0x47, 0x93, 0xe5, 0xa6, 0xf9, 0x73, 0xdd, 0x98, 0xb4, 0x66, 0x02, 0x1f, 0x3b, 0xe7, 0x53, 0x9f, 0x54, - 0x44, 0x0b, 0x9b, 0xdb, 0xe8, 0xaa, 0x77, 0xc3, 0x89, 0x65, 0x12, 0xb2, 0xc5, 0x2f, 0x5e, 0xaa, 0xff, 0xab, 0x72, 0x1f, - 0xf1, 0xd3, 0xdc, 0x8f, 0xaf, 0x13, 0x31, 0xaa, 0x5d, 0x48, 0x5a, 0x1b, 0x31, 0x61, 0x0b, 0x48, 0x9b, 0xe6, 0x75, 0x2e, - 0xd5, 0xdb, 0xd3, 0x22, 0xb5, 0x77, 0x9b, 0x45, 0xc2, 0x9d, 0x1b, 0xe2, 0x2b, 0x8c, 0x14, 0x99, 0x10, 0x7c, 0x24, 0x18, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, - 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, - 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, - 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, - 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x03, 0xb0, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x11, 0x2c, 0x00, 0x00, 0x12, 0x50, 0x00, 0x00, 0x12, 0xb0, - 0x00, 0x00, 0x12, 0xe8, 0x00, 0x00, 0x13, 0x20, 0x00, 0x00, 0x13, 0x58, 0x00, 0x00, 0x13, 0x90, 0x00, 0x00, 0x13, 0xc8, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x38, 0x00, 0x00, 0x14, 0x70, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x70, 0x00, 0x00, 0x11, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, - 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, - 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, - 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, - 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, - 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, - 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x12, 0x78, 0x00, 0x00, 0x12, 0x94, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, - 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, - 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x12, 0xd8, 0x00, 0x00, 0x12, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x13, 0x10, 0x00, 0x00, 0x13, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x48, - 0x00, 0x00, 0x13, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x80, 0x00, 0x00, 0x13, 0x88, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0xb8, 0x00, 0x00, 0x13, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0xf0, 0x00, 0x00, 0x13, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x14, 0x28, 0x00, 0x00, 0x14, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x60, - 0x00, 0x00, 0x14, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x98, 0x00, 0x00, 0x14, 0xa0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1e, 0xbc, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38, - 0x00, 0x00, 0x15, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x02, 0xf8, - 0x00, 0x00, 0x05, 0xe4, 0x00, 0x00, 0x08, 0xa4, 0x00, 0x00, 0x0e, 0xfc, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x11, 0xe4, - 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x70, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf5, 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x02, 0x15, - 0x00, 0x00, 0x02, 0x19, 0x00, 0x00, 0x02, 0x1d, 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, - 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x6d, 0x00, 0x00, 0x02, 0x71, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x81, - 0x00, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, - 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, - 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x70, 0xea, 0x6d, 0x4d, 0x2b, 0x42, 0xd6, 0x1d, 0xa7, 0x00, 0x00, 0x00, 0x02, - 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x59, 0x1b, 0x38, 0x6f, 0x83, 0xff, 0xcf, 0x13, 0x00, 0xc5, 0x58, 0x14, - 0x81, 0x60, 0xd5, 0xf2, 0x76, 0x2d, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xe5, 0x1f, 0x40, 0x4b, 0xde, 0x16, 0xe0, 0x41, - 0xc5, 0xdc, 0x68, 0x83, 0xfb, 0x0f, 0x7b, 0xad, 0x62, 0x9d, 0xa3, 0xee, 0xea, 0xa9, 0x6b, 0x27, 0x69, 0x1e, 0xea, 0xc7, - 0x1c, 0xf7, 0x06, 0xa5, 0x76, 0xcd, 0x9d, 0x65, 0x3c, 0xb1, 0x30, 0x6a, 0x30, 0xd1, 0x31, 0xbd, 0x8a, 0x19, 0x90, 0x89, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, - 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, - 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, - 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, - 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xec, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x25, 0x00, 0x00, 0x02, 0x3d, - 0x00, 0x00, 0x02, 0x41, 0x00, 0x00, 0x02, 0x45, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x65, - 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa1, - 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xc5, - 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, - 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0xfa, 0xde, 0x07, 0x11, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x6c, 0x00, 0x00, 0x01, 0x9c, 0x8b, 0x41, 0x4a, 0x57, 0xa6, 0xf2, 0x36, 0xc2, - 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, - 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x9a, 0xfe, 0xce, 0x76, 0xf7, 0x40, 0x3a, 0x9f, - 0xd2, 0xc5, 0x69, 0x65, 0x60, 0xea, 0x1a, 0x98, 0xc7, 0xed, 0x28, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, - 0x00, 0x00, 0x0c, 0x00, 0x00, 0x5a, 0x4c, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, - 0x83, 0x67, 0xc1, 0x00, 0xdf, 0x03, 0x66, 0xb0, 0xbb, 0x20, 0xb3, 0x39, 0x84, 0xf0, 0x07, 0xc3, 0x17, 0x75, 0x8a, 0x1b, - 0xce, 0x2a, 0xb7, 0xc3, 0x31, 0xd7, 0xea, 0xba, 0xa4, 0x38, 0xf5, 0x78, 0x94, 0xa5, 0xff, 0x08, 0x6d, 0x36, 0x41, 0xa5, - 0x8d, 0x6e, 0xf7, 0x55, 0x1f, 0x6f, 0xe9, 0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, - 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, - 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, - 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, - 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf5, - 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x02, 0x15, 0x00, 0x00, 0x02, 0x19, 0x00, 0x00, 0x02, 0x1d, - 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x6d, - 0x00, 0x00, 0x02, 0x71, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x02, 0x91, - 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, - 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, - 0x00, 0x00, 0x02, 0xbd, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x70, - 0x44, 0x1d, 0x55, 0x6f, 0xda, 0x1b, 0x4a, 0x43, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, - 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, - 0x23, 0x07, 0xb7, 0x3f, 0xb3, 0x23, 0xad, 0xb2, 0xa9, 0x7f, 0x10, 0x8b, 0x76, 0x89, 0x68, 0x1b, 0x42, 0xb4, 0x45, 0x98, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, - 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xc5, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x23, 0xe5, 0x14, 0x64, 0x77, 0x35, 0x5f, 0x79, 0x3e, 0x4c, 0x4d, 0x5e, 0xee, 0xa7, 0x26, 0x39, 0x7d, - 0x28, 0x18, 0xd5, 0xf5, 0x08, 0x07, 0x99, 0x37, 0xb1, 0xea, 0x83, 0x7c, 0xbc, 0xeb, 0x64, 0x47, 0xc6, 0xe1, 0x82, 0xfe, - 0x1f, 0x20, 0x67, 0x1e, 0x37, 0x92, 0x57, 0xaa, 0xbe, 0x4f, 0xac, 0x5f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, - 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, - 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, - 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, - 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5c, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5, - 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, 0x00, 0x00, 0x03, 0x05, - 0x00, 0x00, 0x03, 0x09, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, 0x03, 0x1d, 0x00, 0x00, 0x03, 0x29, - 0x00, 0x00, 0x03, 0x2d, 0x00, 0x00, 0x03, 0x31, 0x00, 0x00, 0x03, 0x35, 0x00, 0x00, 0x03, 0x39, 0x00, 0x00, 0x03, 0x3d, - 0x00, 0x00, 0x03, 0x41, 0x00, 0x00, 0x03, 0x45, 0x00, 0x00, 0x03, 0x49, 0x00, 0x00, 0x03, 0x4d, 0x00, 0x00, 0x03, 0x51, - 0x00, 0x00, 0x03, 0x55, 0x00, 0x00, 0x03, 0x59, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xdc, - 0x00, 0x00, 0x02, 0x0c, 0x52, 0x60, 0x55, 0x9c, 0x4a, 0x26, 0x30, 0x1b, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, - 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x06, 0x93, 0x56, 0x67, 0xd4, 0x00, 0x07, 0x17, 0xac, 0xc1, 0xbd, 0xea, 0x93, 0x3b, 0xd3, 0x28, 0xa0, - 0x57, 0xe5, 0x77, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, - 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x74, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x9d, 0x01, 0xd2, 0x67, 0xcc, 0xce, 0x6d, 0x38, 0xee, 0x87, 0xc1, 0xcc, - 0x32, 0xbb, 0xee, 0x47, 0xfa, 0x77, 0x9b, 0xdf, 0x00, 0x00, 0x00, 0x44, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x62, 0x69, 0x6e, - 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x63, 0x6f, 0x6d, 0x2e, - 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, - 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x69, 0x63, - 0x74, 0x69, 0x76, 0x65, 0xad, 0xa7, 0xd1, 0x01, 0x67, 0x9c, 0xc4, 0xea, 0xc3, 0xdf, 0x8e, 0xc4, 0x08, 0x5b, 0x35, 0x71, - 0x96, 0xc4, 0xb0, 0x57, 0x19, 0x46, 0xb5, 0x63, 0xce, 0xbb, 0x8e, 0xe7, 0x35, 0x53, 0x02, 0xe2, 0xb2, 0x8d, 0xfa, 0xf4, - 0x08, 0xdd, 0x5f, 0xda, 0x2e, 0x3e, 0xf4, 0x8c, 0x14, 0x02, 0xe2, 0x53, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, - 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, - 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, - 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, - 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfc, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0xa4, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x29, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x51, - 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x79, 0x00, 0x00, 0x02, 0xa5, - 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc9, - 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, 0x00, 0x00, 0x02, 0xdd, - 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed, 0x00, 0x00, 0x02, 0xf1, - 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x7c, - 0x00, 0x00, 0x01, 0xa4, 0x3b, 0xaf, 0x30, 0xf6, 0xce, 0x08, 0x47, 0xad, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, - 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xcf, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x06, 0xeb, 0x22, 0x2e, 0xd0, 0xa1, 0x2a, 0x8b, 0xd2, 0x11, 0xac, 0x9f, 0x5b, 0x27, 0x35, 0x5d, 0xd8, - 0x58, 0x6d, 0x84, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xa8, 0x12, 0x5f, 0x3d, 0x91, 0x36, 0x30, 0x1a, 0x76, 0x25, 0x8c, 0xbf, - 0x1f, 0x58, 0xcb, 0x76, 0xd6, 0xbb, 0xff, 0xb1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xa8, 0x12, 0x5f, 0x3d, 0x91, 0x36, 0x30, 0x1a, - 0x76, 0x25, 0x8c, 0xbf, 0x1f, 0x58, 0xcb, 0x76, 0xd6, 0xbb, 0xff, 0xb1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, 0xc2, 0xa8, 0x12, 0x5f, 0x3d, 0xc2, 0x91, 0x36, 0x30, 0x1a, 0x76, 0x25, 0xc2, 0x8c, 0xc2, 0xbf, - 0x1f, 0x58, 0xc3, 0x8b, 0x76, 0xc3, 0x96, 0xc2, 0xbb, 0xc3, 0xbf, 0xc2, 0xb1, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, - 0xbf, 0xc2, 0x98, 0xc2, 0xb9, 0xc2, 0x89, 0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x54, 0x55, 0x4d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, - 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xe6, 0x50, 0x17, 0x0a, 0x9f, 0xb9, 0xab, 0x61, 0x5d, 0x77, 0x39, 0x8b, - 0x76, 0x2d, 0x3f, 0x20, 0xb2, 0xec, 0x7c, 0xbc, 0xa1, 0x54, 0xac, 0x1b, 0x1c, 0x6d, 0x6b, 0x88, 0x3b, 0xd2, 0x7b, 0x6b, - 0x24, 0x84, 0x7c, 0xca, 0xc7, 0xe8, 0x66, 0x8e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x18, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, - 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, - 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, - 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x02, 0xe8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0xa8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x00, 0x02, 0x31, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x41, - 0x00, 0x00, 0x02, 0x45, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x61, 0x00, 0x00, 0x02, 0x65, - 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa9, - 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xc5, - 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, - 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0xa8, 0xf4, 0x8e, 0xca, 0x78, 0x14, 0xb8, 0x41, 0x73, 0x00, 0x00, 0x00, 0x02, - 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x72, 0x3a, 0x27, 0x07, 0x00, 0xae, 0x19, 0xfc, 0x71, 0x1c, 0x6f, 0x2f, - 0xe2, 0x2b, 0x78, 0x9a, 0xdc, 0x88, 0xc1, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc9, 0x22, 0xdf, 0x1e, 0x94, 0x1b, 0x4d, 0x42, - 0x21, 0x42, 0x85, 0xcd, 0x32, 0xec, 0xe5, 0xd7, 0xf9, 0x61, 0x38, 0xe1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc9, 0x22, 0xdf, 0x1e, - 0x94, 0x1b, 0x4d, 0x42, 0x21, 0x42, 0x85, 0xcd, 0x32, 0xec, 0xe5, 0xd7, 0xf9, 0x61, 0x38, 0xe1, 0xff, 0xff, 0xff, 0xff, - 0x98, 0xb9, 0x89, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc3, 0x89, 0x22, 0xc3, 0x9f, 0x1e, 0xc2, 0x94, - 0x1b, 0x4d, 0x42, 0x21, 0x42, 0xc2, 0x85, 0xc3, 0x8d, 0x32, 0xc3, 0xac, 0xc3, 0xa5, 0xc3, 0x97, 0xc3, 0xb9, 0x61, 0x38, - 0xc3, 0xa1, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc2, 0x98, 0xc2, 0xb9, 0xc2, 0x89, 0x06, 0x01, 0x00, 0x4d, - 0x00, 0x54, 0x55, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, - 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0x7b, 0x74, 0x34, 0xf2, - 0x79, 0x55, 0x24, 0x13, 0xc5, 0x6c, 0xdd, 0xe2, 0xe7, 0xd5, 0xbf, 0x4e, 0xaa, 0xc8, 0x50, 0xa3, 0xc6, 0x46, 0x67, 0x62, - 0x08, 0x04, 0x0d, 0xe7, 0x54, 0xe1, 0xb5, 0x0a, 0x53, 0x0d, 0x90, 0xbc, 0xd7, 0x2e, 0x5f, 0x6d, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x08, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, - 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, - 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x02, 0x85, 0x00, 0x00, 0x02, 0x9d, - 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xc5, - 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0x00, 0x00, 0x02, 0xfd, 0x00, 0x00, 0x03, 0x01, - 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x03, 0x19, 0x00, 0x00, 0x03, 0x1d, 0x00, 0x00, 0x03, 0x21, 0x00, 0x00, 0x03, 0x25, - 0x00, 0x00, 0x03, 0x29, 0x00, 0x00, 0x03, 0x2d, 0x00, 0x00, 0x03, 0x31, 0x00, 0x00, 0x03, 0x35, 0x00, 0x00, 0x03, 0x39, - 0x00, 0x00, 0x03, 0x3d, 0x00, 0x00, 0x03, 0x41, 0x00, 0x00, 0x03, 0x45, 0x00, 0x00, 0x03, 0x49, 0xfa, 0xde, 0x07, 0x11, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x01, 0xfc, 0x1a, 0xe7, 0x86, 0xc7, 0x8e, 0x0c, 0x7b, 0xed, - 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, - 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0xbb, 0x34, 0xae, 0xf4, 0x96, 0x00, 0x3a, 0xa9, - 0x6c, 0x3b, 0x6c, 0xa6, 0x1b, 0xa0, 0xfd, 0x0d, 0x0b, 0x7b, 0xc1, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x6e, 0x6f, 0x62, 0x6f, - 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x50, 0x81, 0xee, 0xbe, 0x1f, 0x36, 0xff, 0x64, - 0xa1, 0x66, 0x43, 0xd7, 0xdc, 0x0e, 0x61, 0xf0, 0x17, 0xaf, 0x60, 0x35, 0x00, 0x00, 0x00, 0x60, 0x2f, 0x41, 0x70, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2f, - 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x00, - 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x60, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, - 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xb8, 0x58, 0xf2, 0xef, - 0xb1, 0x4e, 0x1e, 0x2e, 0x15, 0xe0, 0x0f, 0xb5, 0xea, 0xd4, 0xf5, 0x1e, 0x45, 0x79, 0x80, 0x58, 0xe2, 0xb2, 0x93, 0xf6, - 0x1c, 0xbf, 0x8c, 0x2b, 0x1d, 0xdb, 0xed, 0x58, 0xd3, 0x90, 0x91, 0xfd, 0x86, 0xbe, 0x01, 0xdd, 0x76, 0x36, 0x01, 0xf0, - 0x1a, 0x4f, 0xd8, 0x7d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, - 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, - 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, - 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, - 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x8c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x15, 0x64, - 0x00, 0x00, 0x18, 0xe0, 0x00, 0x00, 0x19, 0xf4, 0x00, 0x00, 0x1a, 0x7c, 0x00, 0x00, 0x1b, 0x04, 0x00, 0x00, 0x1b, 0x8c, - 0x00, 0x00, 0x1c, 0x14, 0x00, 0x00, 0x1c, 0x9c, 0x00, 0x00, 0x1d, 0x24, 0x00, 0x00, 0x1d, 0xac, 0x00, 0x00, 0x1e, 0x34, - 0x00, 0x00, 0x03, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x15, 0xd0, 0x00, 0x00, 0x16, 0x44, - 0x00, 0x00, 0x16, 0xb4, 0x00, 0x00, 0x17, 0x24, 0x00, 0x00, 0x17, 0x94, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x18, 0x74, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x17, 0x72, 0x65, 0x73, 0x74, - 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, - 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, - 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, - 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, - 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, - 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, - 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, - 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, - 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, - 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, - 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, - 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, - 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, - 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, - 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, - 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, - 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, - 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, - 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, - 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, - 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, - 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x19, 0x30, - 0x00, 0x00, 0x19, 0x50, 0x00, 0x00, 0x19, 0x6c, 0x00, 0x00, 0x19, 0x88, 0x00, 0x00, 0x19, 0xa4, 0x00, 0x00, 0x19, 0xc0, - 0x00, 0x00, 0x19, 0xdc, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x17, - 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, - 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, - 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9, - 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, - 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, - 0xdf, 0x25, 0xe4, 0x2d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1a, 0x44, 0x00, 0x00, 0x1a, 0x4c, - 0x00, 0x00, 0x1a, 0x54, 0x00, 0x00, 0x1a, 0x5c, 0x00, 0x00, 0x1a, 0x64, 0x00, 0x00, 0x1a, 0x6c, 0x00, 0x00, 0x1a, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1a, 0xcc, 0x00, 0x00, 0x1a, 0xd4, 0x00, 0x00, 0x1a, 0xdc, - 0x00, 0x00, 0x1a, 0xe4, 0x00, 0x00, 0x1a, 0xec, 0x00, 0x00, 0x1a, 0xf4, 0x00, 0x00, 0x1a, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1b, 0x54, 0x00, 0x00, 0x1b, 0x5c, 0x00, 0x00, 0x1b, 0x64, 0x00, 0x00, 0x1b, 0x6c, - 0x00, 0x00, 0x1b, 0x74, 0x00, 0x00, 0x1b, 0x7c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x1b, 0xdc, 0x00, 0x00, 0x1b, 0xe4, 0x00, 0x00, 0x1b, 0xec, 0x00, 0x00, 0x1b, 0xf4, 0x00, 0x00, 0x1b, 0xfc, - 0x00, 0x00, 0x1c, 0x04, 0x00, 0x00, 0x1c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1c, 0x64, - 0x00, 0x00, 0x1c, 0x6c, 0x00, 0x00, 0x1c, 0x74, 0x00, 0x00, 0x1c, 0x7c, 0x00, 0x00, 0x1c, 0x84, 0x00, 0x00, 0x1c, 0x8c, - 0x00, 0x00, 0x1c, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1c, 0xec, 0x00, 0x00, 0x1c, 0xf4, - 0x00, 0x00, 0x1c, 0xfc, 0x00, 0x00, 0x1d, 0x04, 0x00, 0x00, 0x1d, 0x0c, 0x00, 0x00, 0x1d, 0x14, 0x00, 0x00, 0x1d, 0x1c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1d, 0x74, 0x00, 0x00, 0x1d, 0x7c, 0x00, 0x00, 0x1d, 0x84, - 0x00, 0x00, 0x1d, 0x8c, 0x00, 0x00, 0x1d, 0x94, 0x00, 0x00, 0x1d, 0x9c, 0x00, 0x00, 0x1d, 0xa4, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, - 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1d, 0xfc, 0x00, 0x00, 0x1e, 0x04, 0x00, 0x00, 0x1e, 0x0c, 0x00, 0x00, 0x1e, 0x14, - 0x00, 0x00, 0x1e, 0x1c, 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1e, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x1e, 0x84, 0x00, 0x00, 0x1e, 0x8c, 0x00, 0x00, 0x1e, 0x94, 0x00, 0x00, 0x1e, 0x9c, 0x00, 0x00, 0x1e, 0xa4, - 0x00, 0x00, 0x1e, 0xac, 0x00, 0x00, 0x1e, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xdc, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x02, 0x38, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, - 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xf5, - 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d, - 0x4a, 0x16, 0x48, 0x81, 0x4a, 0xfb, 0x22, 0x80, 0x56, 0xd0, 0x65, 0x2b, 0x3e, 0x11, 0x11, 0xe2, 0x12, 0x2b, 0xc6, 0x87, - 0xa1, 0xd0, 0x14, 0x1e, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, 0x30, 0x36, 0x5a, 0x00, - 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, 0x30, 0x36, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x16, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa9, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, - 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x01, 0x15, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, - 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0xfd, 0xc0, 0xab, 0x3b, 0xfc, 0x61, 0xe6, 0xd5, 0xdd, 0xcf, 0x26, 0x91, - 0xe5, 0xe9, 0xfb, 0x2c, 0xc0, 0x8d, 0xfe, 0x4c, 0x96, 0xf5, 0x08, 0x64, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, - 0x31, 0x38, 0x35, 0x31, 0x31, 0x37, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, - 0x31, 0x37, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, - 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, - 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0xd9, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9, - 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0xdc, 0xaf, 0x18, 0xfa, 0xad, 0xad, 0x06, 0xf6, 0x32, 0x30, 0x31, 0x36, - 0x30, 0x34, 0x31, 0x31, 0x32, 0x31, 0x35, 0x31, 0x31, 0x35, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x31, 0x31, - 0x32, 0x31, 0x35, 0x31, 0x31, 0x35, 0x5a, 0x00, 0x61, 0x61, 0x70, 0x6c, 0x69, 0x70, 0x72, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, - 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x11, - 0x73, 0x73, 0x75, 0x69, 0x00, 0x00, 0x00, 0x20, 0x87, 0x19, 0x1c, 0xa3, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, - 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x64, 0x62, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x21, 0x7e, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x4b, 0x65, - 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x61, 0x73, 0x64, 0x66, 0x2d, 0x64, 0x62, - 0x00, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, - 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, - 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, - 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, - 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, - 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb4, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x05, 0x5c, 0x00, 0x00, 0x00, 0xb4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x61, 0x63, 0x63, 0x74, 0x73, 0x76, 0x63, 0x65, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x70, 0x00, 0x00, 0x04, 0x94, 0x00, 0x00, 0x04, 0xc8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x24, - 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x6c, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x05, 0x34, 0x00, 0x00, 0x05, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, - 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x05, 0x8c, 0x00, 0x00, 0x05, 0xa4, 0x00, 0x00, 0x05, 0xb8, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, - 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, - 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x05, 0x2c, 0x80, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x01, 0x58, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, - 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x21, - 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x01, 0x2d, 0x00, 0x00, 0x01, 0x31, 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, - 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0xce, 0x58, 0x3c, 0x63, 0xf0, 0xe1, 0x4b, 0xfc, - 0xee, 0x88, 0x20, 0xa4, 0xc4, 0x20, 0xc4, 0x8c, 0xaf, 0x9d, 0xe6, 0x89, 0x39, 0xe3, 0xcc, 0x27, 0x32, 0x30, 0x31, 0x36, - 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x33, 0x34, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, - 0x31, 0x38, 0x34, 0x39, 0x33, 0x34, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x61, 0x20, 0x75, 0x73, - 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x68, 0x74, 0x70, 0x73, - 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xed, - 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x05, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x01, 0x11, - 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, - 0x60, 0x88, 0xd4, 0xf3, 0x53, 0x7d, 0x89, 0x6e, 0xc1, 0x4f, 0xfd, 0x7b, 0x4b, 0x9d, 0x0d, 0xe0, 0xe9, 0xd6, 0x84, 0xdf, - 0x0f, 0x23, 0x90, 0x0b, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x34, 0x33, 0x5a, 0x00, - 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x34, 0x33, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x61, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, - 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0c, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04, - 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x02, 0x94, 0x00, 0x00, 0x03, 0x5c, 0x00, 0x00, 0x03, 0xac, 0x00, 0x00, 0x03, 0xe4, 0x00, 0x00, 0x04, 0x44, - 0x00, 0x00, 0x04, 0x7c, 0x00, 0x00, 0x04, 0xbc, 0x00, 0x00, 0x04, 0xf4, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x61, 0x63, 0x63, 0x74, 0x73, 0x64, 0x6d, 0x6e, 0x73, 0x72, 0x76, 0x72, - 0x70, 0x74, 0x63, 0x6c, 0x61, 0x74, 0x79, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x02, 0xd4, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, - 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x68, 0x74, 0x70, 0x73, - 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, - 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, - 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04, - 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x84, - 0x00, 0x00, 0x03, 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xd4, - 0x00, 0x00, 0x03, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x04, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x6c, 0x00, 0x00, 0x04, 0x74, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, 0x74, 0x70, 0x73, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x74, 0x79, 0x70, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0xa4, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, - 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x70, 0x61, 0x74, 0x68, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x1c, 0x00, 0x00, 0x05, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1d, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x24, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x61, 0x63, 0x63, 0x74, 0x76, 0x6c, 0x6d, 0x65, - 0x61, 0x64, 0x64, 0x72, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x64, 0x64, 0x72, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0b, 0xd8, 0x00, 0x00, 0x05, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x45, 0x00, 0x00, 0x04, 0x49, - 0x00, 0x00, 0x04, 0x4d, 0x00, 0x00, 0x04, 0x5d, 0x00, 0x00, 0x04, 0x71, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x05, 0xb9, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xc1, 0x30, 0x82, 0x04, 0x01, 0x30, 0x82, 0x02, 0xe9, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, - 0x05, 0x00, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, - 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, - 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, - 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, - 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x35, 0x33, 0x32, 0x5a, 0x17, - 0x0d, 0x32, 0x36, 0x30, 0x34, 0x30, 0x36, 0x31, 0x38, 0x35, 0x35, 0x33, 0x32, 0x5a, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, - 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, - 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, - 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, - 0x62, 0x6f, 0x64, 0x79, 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, 0xb3, 0xaa, 0xa8, 0x77, 0xe7, 0x3e, 0x2d, 0x0c, 0xf4, 0x83, 0x55, 0xc2, 0x9e, - 0x50, 0x10, 0xc9, 0xef, 0xc8, 0x48, 0x38, 0xe4, 0x43, 0x96, 0xfa, 0x93, 0x32, 0xbf, 0x66, 0xad, 0x84, 0xa2, 0x8b, 0x6b, - 0x07, 0x8c, 0xc6, 0x93, 0x8c, 0x4d, 0x65, 0x0f, 0xad, 0x76, 0x73, 0x0c, 0x4d, 0x43, 0xee, 0x35, 0xd4, 0x68, 0x4a, 0x9a, - 0x6d, 0x4d, 0xa5, 0xae, 0x66, 0xcf, 0xfb, 0xbb, 0x93, 0xd3, 0x6a, 0xe3, 0xfc, 0x41, 0x97, 0xae, 0x90, 0xc3, 0xd8, 0x83, - 0xfb, 0x8d, 0x67, 0x84, 0xc1, 0xd5, 0x7d, 0x1d, 0x12, 0xca, 0x0c, 0xb5, 0xae, 0xf0, 0xe3, 0x36, 0x39, 0xf1, 0x68, 0x92, - 0x6f, 0xda, 0x2d, 0x48, 0x87, 0xf0, 0x4b, 0x15, 0x4e, 0x4f, 0x7a, 0x3a, 0x16, 0xb9, 0x02, 0x89, 0x95, 0x98, 0xab, 0xb2, - 0x58, 0x5b, 0x31, 0x7f, 0x49, 0x90, 0x48, 0xfd, 0x8d, 0x8a, 0x37, 0x3a, 0x4e, 0xd8, 0x00, 0x4a, 0xdc, 0xd4, 0x02, 0x9f, - 0xcd, 0x4b, 0xde, 0x75, 0x4a, 0xb2, 0x27, 0x8e, 0xe6, 0x2d, 0xea, 0x35, 0x89, 0x85, 0x8a, 0x37, 0x59, 0xd6, 0xd1, 0xf8, - 0x36, 0x7c, 0x93, 0x9e, 0xd6, 0xd1, 0xc3, 0xd9, 0x75, 0xa4, 0x4f, 0x40, 0x24, 0xe9, 0xc0, 0xde, 0xeb, 0xc0, 0x5e, 0xd6, - 0x04, 0xe1, 0xd0, 0x07, 0x29, 0xc1, 0x9d, 0x6f, 0x78, 0x2d, 0x5a, 0xef, 0xe6, 0xff, 0x25, 0x16, 0xcf, 0x60, 0x77, 0xa2, - 0x10, 0x2b, 0xa4, 0x2a, 0xff, 0x74, 0x3b, 0xe6, 0x4d, 0xc1, 0x13, 0xba, 0x8b, 0xe8, 0x15, 0x8e, 0xc7, 0xc3, 0xd4, 0x31, - 0xb0, 0x99, 0x51, 0x32, 0x30, 0x03, 0x0b, 0x1c, 0xa0, 0x0a, 0x17, 0x15, 0x34, 0x57, 0x38, 0xd3, 0x08, 0x13, 0xc4, 0xd6, - 0x7c, 0x24, 0x16, 0xd0, 0x2f, 0x00, 0x88, 0xd7, 0xd9, 0xca, 0x1e, 0x6b, 0x50, 0x3b, 0x5f, 0xb6, 0x08, 0xb1, 0x29, 0x42, - 0x70, 0xf1, 0x89, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x47, 0x30, 0x45, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, - 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, - 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, - 0x14, 0x30, 0x12, 0x81, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, - 0x00, 0x00, 0xa3, 0x3e, 0x5c, 0x33, 0x06, 0x0b, 0x74, 0xf7, 0x59, 0x56, 0x2e, 0x26, 0x18, 0xe0, 0x59, 0xc9, 0x20, 0x9d, - 0xaa, 0xf2, 0xfb, 0xa0, 0xf8, 0x11, 0x00, 0x71, 0x53, 0x3d, 0xfa, 0xdc, 0xe9, 0x12, 0x4c, 0x8a, 0xa1, 0x1c, 0x7c, 0xb3, - 0x4b, 0xa5, 0xa0, 0xfa, 0x03, 0xc5, 0x82, 0x1c, 0xab, 0x44, 0xf6, 0xcb, 0x59, 0x4b, 0x80, 0xeb, 0xc0, 0xa8, 0x0e, 0xc6, - 0x93, 0xea, 0xbf, 0x67, 0x41, 0xa9, 0x64, 0xcb, 0xb4, 0x3e, 0xf7, 0x64, 0xcf, 0x4c, 0xef, 0x24, 0x62, 0x73, 0x2d, 0xed, - 0xb4, 0xec, 0x30, 0x97, 0x91, 0x9f, 0x18, 0xe9, 0x12, 0x93, 0x18, 0x83, 0x70, 0xb0, 0xc4, 0x35, 0x33, 0x67, 0x17, 0xb0, - 0x8b, 0xbe, 0x45, 0xde, 0x98, 0x23, 0xf2, 0x02, 0x77, 0x79, 0x55, 0x53, 0xc4, 0xd7, 0x67, 0x81, 0xde, 0xa1, 0x3f, 0x63, - 0xb5, 0x87, 0xb6, 0x20, 0x8d, 0x4f, 0x5e, 0x7e, 0x27, 0x30, 0x99, 0xe0, 0xff, 0x91, 0x8b, 0x00, 0x8d, 0x7d, 0xe5, 0x57, - 0x57, 0xd8, 0xd9, 0x7d, 0x6f, 0xc6, 0xb8, 0x6f, 0x84, 0xed, 0x84, 0x9d, 0xd9, 0xac, 0x13, 0xd8, 0x4a, 0x96, 0x55, 0x2d, - 0x8e, 0x21, 0x11, 0xc9, 0xa4, 0x81, 0x10, 0x7a, 0x0a, 0x15, 0xce, 0x99, 0x98, 0x09, 0xdd, 0xec, 0x8d, 0x1b, 0xfb, 0x17, - 0x55, 0x03, 0xa6, 0x44, 0xb5, 0xc9, 0xa9, 0x1f, 0x52, 0xd7, 0x35, 0x06, 0x8d, 0x0a, 0x5a, 0x01, 0x2a, 0xb0, 0xd2, 0x0c, - 0xfa, 0xd9, 0x66, 0xfa, 0x35, 0x6e, 0xa0, 0xbc, 0x21, 0xe4, 0xe1, 0xe0, 0x3c, 0x3b, 0x7a, 0xef, 0x7d, 0xe1, 0x34, 0x2e, - 0xe3, 0x9c, 0xc0, 0xa9, 0x4c, 0x16, 0xab, 0x00, 0x60, 0xe0, 0x44, 0xeb, 0x62, 0xcc, 0x1d, 0x27, 0x84, 0x0f, 0x33, 0x37, - 0x9d, 0xc5, 0xc4, 0xa1, 0xd3, 0xe8, 0x38, 0xff, 0xf2, 0xdf, 0xcd, 0x7c, 0xbb, 0xc3, 0xa1, 0xae, 0x4d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, - 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, - 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, - 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, - 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, - 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, - 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, - 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, - 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, - 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x05, 0xd8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x31, 0x00, 0x00, 0x04, 0x35, 0x00, 0x00, 0x04, 0x39, - 0x00, 0x00, 0x04, 0x4d, 0x00, 0x00, 0x04, 0x61, 0x00, 0x00, 0x05, 0x0d, 0x00, 0x00, 0x05, 0xb9, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x05, 0xc1, 0x30, 0x82, 0x03, 0xee, 0x30, 0x82, 0x02, 0xd6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x06, - 0xe0, 0x2a, 0x1d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, - 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, - 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, - 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, - 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, - 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, - 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x36, 0x34, 0x36, 0x5a, - 0x17, 0x0d, 0x32, 0x36, 0x30, 0x34, 0x30, 0x36, 0x31, 0x38, 0x35, 0x36, 0x34, 0x36, 0x5a, 0x30, 0x81, 0xa2, 0x31, 0x19, - 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, - 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, - 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, - 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, - 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, - 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 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, 0xb6, 0x07, 0xac, 0x5c, 0xc6, 0xcb, 0xf0, - 0xb7, 0x97, 0x0d, 0x43, 0x1a, 0xe9, 0x61, 0xe7, 0x34, 0x63, 0x6a, 0x26, 0x0d, 0x77, 0xba, 0x25, 0xaa, 0xc8, 0x46, 0xf8, - 0xc9, 0xdd, 0x21, 0xb4, 0x3e, 0x2e, 0x11, 0x8e, 0xb6, 0x72, 0xf2, 0x01, 0x16, 0x07, 0xcf, 0x88, 0x91, 0xc4, 0xc0, 0x48, - 0x64, 0x41, 0x91, 0xf7, 0x63, 0x72, 0xd5, 0x37, 0xef, 0x37, 0x62, 0xed, 0x33, 0xb3, 0xf9, 0x6e, 0x31, 0xd1, 0x68, 0xe7, - 0xde, 0x62, 0x9f, 0x82, 0xb8, 0x9e, 0x11, 0xe7, 0x66, 0x91, 0xc1, 0xbe, 0xe5, 0x5c, 0xd6, 0x71, 0x83, 0x91, 0xbc, 0x0f, - 0xa8, 0x06, 0xc3, 0xe9, 0xb6, 0x76, 0x16, 0xae, 0x69, 0x0a, 0x47, 0xe4, 0x65, 0xaa, 0x13, 0x71, 0x48, 0xb3, 0x5c, 0x25, - 0xa5, 0x1a, 0xd0, 0x2a, 0x57, 0x57, 0xf9, 0xb7, 0x13, 0xbd, 0xf4, 0x13, 0x5a, 0x11, 0x1b, 0xcc, 0xd8, 0x9a, 0x5f, 0x82, - 0x3f, 0xa7, 0x6b, 0x64, 0x47, 0x54, 0xb6, 0x81, 0xaf, 0xcb, 0x4b, 0x94, 0x39, 0x65, 0x15, 0xba, 0x6a, 0x02, 0x7c, 0x71, - 0x30, 0x60, 0x21, 0x12, 0x63, 0x28, 0xe0, 0x85, 0xca, 0xcc, 0x07, 0xb1, 0x13, 0x40, 0x19, 0x72, 0x02, 0x35, 0x0e, 0x2d, - 0x4b, 0x8a, 0xcd, 0x1d, 0x09, 0x65, 0xb0, 0x81, 0x49, 0xea, 0x70, 0x15, 0x92, 0x19, 0x7b, 0xfe, 0x15, 0xf7, 0x4a, 0x3f, - 0x1e, 0x3c, 0x63, 0x7a, 0x0f, 0x17, 0x32, 0x1a, 0xb7, 0x26, 0xa1, 0xa0, 0x9b, 0x3f, 0x4e, 0x7c, 0x38, 0xe6, 0x27, 0xbf, - 0xa8, 0x1b, 0xf7, 0xbd, 0x2d, 0xfd, 0x9b, 0x05, 0x0c, 0xaa, 0x81, 0xb8, 0x09, 0xd4, 0xe2, 0xe3, 0xbd, 0x6c, 0x70, 0xc0, - 0x7e, 0x95, 0xd4, 0x0b, 0x13, 0xab, 0xb8, 0xdd, 0x3d, 0x4c, 0x59, 0xf0, 0xc7, 0x8e, 0x47, 0xb5, 0xd8, 0x31, 0x78, 0x80, - 0xd2, 0x5f, 0x0c, 0x0b, 0xae, 0x22, 0xe7, 0x9e, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x2a, 0x30, 0x28, 0x30, 0x0e, - 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, - 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xaf, 0xe3, - 0x41, 0xaa, 0x63, 0xdc, 0x3e, 0xd1, 0x46, 0x1e, 0x7a, 0x09, 0x04, 0x4a, 0xfd, 0x54, 0xc7, 0xd9, 0x25, 0x2f, 0xce, 0x8e, - 0x5d, 0x34, 0x96, 0x04, 0x67, 0xbc, 0x6f, 0xb6, 0x99, 0x35, 0xc2, 0x16, 0x1c, 0x2a, 0xc3, 0x5f, 0xdf, 0x6e, 0xe2, 0xe4, - 0x2e, 0xbb, 0x64, 0x1c, 0x0a, 0xff, 0x62, 0x79, 0x70, 0x7c, 0xc6, 0x8e, 0xd9, 0x95, 0xb6, 0x8a, 0x3d, 0xf6, 0xdd, 0x79, - 0x1c, 0xeb, 0x73, 0x05, 0x2f, 0x7e, 0x38, 0xb8, 0x9c, 0xfc, 0x06, 0x8f, 0x5f, 0xd7, 0xec, 0xd3, 0x23, 0xae, 0x75, 0x0f, - 0x8e, 0x70, 0xb2, 0xd8, 0x88, 0xa0, 0x4f, 0x53, 0x0a, 0xcc, 0xee, 0x18, 0xf2, 0x5b, 0xf8, 0xe1, 0x22, 0x6b, 0xeb, 0x4d, - 0x9d, 0x2a, 0xa1, 0x46, 0xf4, 0xc7, 0x99, 0x26, 0x5b, 0xaf, 0x92, 0x54, 0x72, 0xe7, 0xea, 0x49, 0x34, 0x98, 0x8d, 0x93, - 0x18, 0xc5, 0x6e, 0x79, 0x79, 0xb3, 0x63, 0x76, 0xf7, 0x84, 0x49, 0x06, 0x58, 0x14, 0x1a, 0x86, 0xbd, 0xe5, 0x5a, 0xf8, - 0x81, 0x06, 0x15, 0x0c, 0xf7, 0x57, 0x4e, 0xeb, 0xbe, 0xc9, 0xe6, 0x09, 0xa3, 0x1d, 0xcc, 0xc6, 0x08, 0xbc, 0x71, 0x4b, - 0x62, 0x1a, 0xec, 0xdd, 0xad, 0xe3, 0x00, 0xd9, 0xf3, 0x98, 0x94, 0x75, 0xb5, 0xc2, 0x64, 0xec, 0xec, 0xe1, 0x88, 0x5b, - 0x24, 0xd6, 0xa2, 0x27, 0x86, 0x10, 0xc4, 0xfc, 0xf7, 0x8d, 0x79, 0x95, 0x20, 0x3e, 0xc5, 0x7a, 0xdc, 0x57, 0xc8, 0x2e, - 0x78, 0x63, 0xd5, 0x09, 0xc3, 0xa9, 0xa4, 0xd9, 0x83, 0x99, 0xbe, 0x17, 0xdc, 0x22, 0x85, 0x98, 0x0b, 0xe1, 0xf6, 0x67, - 0x47, 0xf7, 0x1d, 0xed, 0x40, 0xe4, 0x5c, 0x5e, 0x58, 0xf1, 0x27, 0x5b, 0xe2, 0x7b, 0xb0, 0xf5, 0xbf, 0x37, 0xc3, 0xe2, - 0x73, 0xa8, 0xd6, 0xf1, 0x42, 0xb2, 0x56, 0x90, 0x00, 0xa4, 0x35, 0x4a, 0x5a, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, - 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, - 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, - 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, - 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, - 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, - 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, - 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, - 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, - 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, 0x00, 0x00, 0x00, 0x14, - 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, - 0x00, 0x00, 0x06, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x00, 0x00, 0x04, 0x85, 0x00, 0x00, 0x04, 0x89, 0x00, 0x00, 0x04, 0xa5, - 0x00, 0x00, 0x04, 0xc5, 0x00, 0x00, 0x05, 0x81, 0x00, 0x00, 0x06, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x45, - 0x30, 0x82, 0x04, 0x3d, 0x30, 0x82, 0x03, 0x25, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, - 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, - 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, - 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x31, 0x31, 0x32, 0x32, 0x34, 0x30, 0x32, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, - 0x34, 0x30, 0x39, 0x32, 0x32, 0x34, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, - 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, - 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, - 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, - 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 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, 0xc3, 0xe8, 0xe0, 0x34, 0xff, 0x63, 0x08, 0xce, 0x36, 0x82, 0x02, 0xe7, 0x91, - 0x0b, 0x73, 0x84, 0xb9, 0xad, 0xd8, 0x79, 0x92, 0x34, 0x20, 0x96, 0xd1, 0x3a, 0xc7, 0x7f, 0x19, 0xd7, 0xcf, 0x9f, 0xab, - 0x2b, 0xc0, 0x0c, 0xe1, 0xf6, 0x0e, 0x9e, 0x9f, 0x73, 0x42, 0x95, 0xf1, 0x2c, 0x63, 0xff, 0x3f, 0x31, 0xb1, 0xe3, 0x24, - 0x1a, 0x75, 0x7d, 0x50, 0x2c, 0x23, 0x59, 0x53, 0x2c, 0xab, 0xaf, 0xd7, 0x5c, 0xf1, 0x27, 0xd2, 0xe9, 0xf5, 0x8f, 0x76, - 0xc4, 0x96, 0x74, 0x3c, 0xda, 0x65, 0xd4, 0x9e, 0xde, 0x33, 0x25, 0x5d, 0xed, 0x04, 0x94, 0x2c, 0xb5, 0x18, 0xeb, 0x64, - 0x8e, 0xf4, 0xd4, 0xe0, 0xb6, 0xfc, 0xcc, 0xd7, 0xfb, 0x90, 0x9c, 0xc1, 0xe6, 0x09, 0xb9, 0x8c, 0xc9, 0xba, 0x91, 0x4d, - 0x63, 0x5f, 0xa1, 0x75, 0x13, 0x11, 0x7d, 0x13, 0xa9, 0x2c, 0x07, 0xbd, 0xcb, 0x5d, 0xc5, 0xb0, 0x4f, 0xed, 0x95, 0xc6, - 0x8c, 0xe9, 0x78, 0xa2, 0xa5, 0x42, 0x15, 0x5a, 0xd0, 0x9c, 0x9c, 0x85, 0x85, 0x6e, 0x50, 0xae, 0x19, 0xd5, 0x91, 0x13, - 0x62, 0x96, 0xd9, 0x4a, 0x47, 0xe3, 0xfe, 0x8f, 0x7d, 0x47, 0xbd, 0xbe, 0xaa, 0x37, 0x64, 0xe3, 0xf0, 0xa3, 0xa4, 0xd0, - 0xef, 0xef, 0x2a, 0xa7, 0x45, 0xbf, 0x21, 0x79, 0xb8, 0x5c, 0x04, 0x8a, 0x2f, 0x7b, 0xe0, 0xe2, 0x32, 0x58, 0x75, 0xec, - 0xec, 0x2f, 0x78, 0xa5, 0x9a, 0x7b, 0xa3, 0x3c, 0xf6, 0x67, 0x00, 0x83, 0xe5, 0x77, 0x1d, 0x2b, 0xdd, 0x74, 0xd0, 0x45, - 0xcf, 0xa4, 0x0c, 0xf2, 0xe2, 0x60, 0xa8, 0x70, 0x87, 0x05, 0x0b, 0x7c, 0xef, 0x88, 0x09, 0x23, 0x15, 0xdf, 0xdb, 0x9f, - 0xc2, 0x80, 0x1f, 0x0a, 0x12, 0xcb, 0x00, 0xa4, 0x8a, 0x77, 0xa7, 0x54, 0x8f, 0xcb, 0x91, 0xbb, 0x55, 0x52, 0x51, 0x8f, - 0xca, 0xf6, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, - 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, - 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, - 0x20, 0x30, 0x1e, 0x81, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8c, 0x44, 0x70, 0xda, 0xd9, 0x65, 0x52, - 0xfd, 0x46, 0x0e, 0xab, 0xbb, 0xb5, 0x1c, 0x46, 0x0a, 0xcb, 0x3d, 0xc3, 0x71, 0x79, 0xa8, 0x5f, 0x3b, 0x45, 0x49, 0x29, - 0x0c, 0xf5, 0x69, 0xb4, 0x27, 0x4d, 0x79, 0xad, 0xa9, 0x93, 0x11, 0x7b, 0xad, 0x45, 0xc6, 0x49, 0x54, 0x8b, 0x5d, 0x5f, - 0xcc, 0x9d, 0xd9, 0xe4, 0x8f, 0xff, 0x21, 0x0f, 0x7a, 0x40, 0xf2, 0xd6, 0xce, 0xe1, 0x97, 0x5f, 0x7d, 0x9c, 0x76, 0x22, - 0x73, 0x30, 0x3b, 0xb4, 0x5b, 0xa0, 0x07, 0x70, 0x96, 0x97, 0x84, 0xe1, 0x47, 0x5b, 0x3e, 0xd2, 0xed, 0x3f, 0xca, 0x97, - 0x3a, 0x33, 0x52, 0xb8, 0x22, 0x89, 0xe2, 0x2e, 0x61, 0x5e, 0x20, 0x1a, 0xf9, 0x4f, 0x9a, 0x18, 0xde, 0xf3, 0x8e, 0x11, - 0x3b, 0x19, 0x09, 0xce, 0x8e, 0xb9, 0x28, 0x5f, 0x64, 0x54, 0xc1, 0x33, 0x19, 0x68, 0x96, 0x54, 0x53, 0x84, 0xb6, 0xf2, - 0xdb, 0xb3, 0x6b, 0xca, 0x36, 0x08, 0xb1, 0xa3, 0x0d, 0x19, 0x4e, 0xac, 0x17, 0x25, 0x96, 0x0d, 0x4c, 0x9e, 0xc5, 0xa0, - 0xcc, 0xe4, 0x52, 0x98, 0x1c, 0xcf, 0x0a, 0x77, 0x91, 0xf2, 0xc8, 0xae, 0x8c, 0x1c, 0x1d, 0xae, 0x79, 0xf6, 0x0c, 0x65, - 0xf0, 0xb4, 0xdd, 0x0c, 0x6f, 0x35, 0x12, 0x93, 0xb7, 0x20, 0xd1, 0x29, 0xa3, 0x40, 0xb5, 0x66, 0x67, 0x69, 0xdd, 0x97, - 0xcf, 0x48, 0x9f, 0xe9, 0x00, 0x33, 0x0e, 0x8e, 0xae, 0xc6, 0x40, 0xe3, 0x40, 0xdb, 0xab, 0x8b, 0x1e, 0x34, 0xbb, 0x0b, - 0xb7, 0x42, 0xd4, 0x0d, 0x9e, 0x86, 0x99, 0x3c, 0xbd, 0x34, 0xc5, 0xba, 0xac, 0x03, 0x8b, 0xcd, 0xa3, 0xee, 0x36, 0x52, - 0x28, 0x59, 0x7a, 0x29, 0xd7, 0x1f, 0xa1, 0x18, 0xc5, 0xba, 0x7a, 0xc4, 0xf0, 0x67, 0x4a, 0x61, 0x5c, 0x83, 0xad, 0x6c, - 0x89, 0x0b, 0xdd, 0x40, 0xf8, 0xfd, 0x8c, 0xce, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, - 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, - 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, - 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, - 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, - 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, - 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, - 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, - 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x14, 0xd7, 0x58, 0x0b, 0xdf, 0xe7, 0x97, 0x49, 0x7e, 0xd7, 0x44, 0x80, 0x01, - 0xf5, 0xf3, 0x7f, 0xf6, 0x1d, 0x5c, 0x24, 0x16, 0x00, 0x00, 0x08, 0xe8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x12, 0x5c, - 0x00, 0x00, 0x14, 0xd0, 0x00, 0x00, 0x15, 0x18, 0x00, 0x00, 0x15, 0x9c, 0x00, 0x00, 0x17, 0xe4, 0x00, 0x00, 0x1a, 0x2c, - 0x00, 0x00, 0x1a, 0x80, 0x00, 0x00, 0x1a, 0x98, 0x00, 0x00, 0x02, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x03, 0x63, 0x74, 0x79, 0x70, 0x69, 0x73, 0x73, 0x75, 0x73, 0x6e, 0x62, 0x72, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x12, 0x94, 0x00, 0x00, 0x13, 0x48, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, - 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, - 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, - 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, - 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, - 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, - 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, - 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, - 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, - 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, - 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, - 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, - 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, - 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x48, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x00, 0x15, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x15, 0x48, 0x00, 0x00, 0x15, 0x60, - 0x00, 0x00, 0x15, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, - 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, - 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x75, 0x62, 0x6a, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x15, 0xcc, 0x00, 0x00, 0x16, 0x74, 0x00, 0x00, 0x17, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, - 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, - 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, - 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xac, - 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, - 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, - 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, - 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, - 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0xb8, - 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, - 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, - 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, - 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, - 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x18, 0x14, 0x00, 0x00, 0x18, 0xbc, 0x00, 0x00, 0x19, 0x6c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa0, - 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, - 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, - 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, - 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, - 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, - 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, - 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, - 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, - 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, - 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, - 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, - 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, - 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x73, 0x6e, 0x62, 0x72, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1a, 0x5c, 0x00, 0x00, 0x1a, 0x68, - 0x00, 0x00, 0x1a, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x6b, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, - 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x1a, 0xc8, 0x00, 0x00, 0x1a, 0xe4, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, - 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, - 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xd7, 0x58, 0x0b, 0xdf, 0xe7, 0x97, 0x49, 0x7e, 0xd7, 0x44, 0x80, 0x01, - 0xf5, 0xf3, 0x7f, 0xf6, 0x1d, 0x5c, 0x24, 0x16, 0x00, 0x00, 0x00, 0xe8, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa8, - 0x00, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xa8, - 0x52, 0xba, 0xd6, 0xe8, 0x80, 0xd9, 0x0e, 0xbb, 0x2e, 0x64, 0x65, 0xce, 0xcd, 0xe6, 0xa9, 0x71, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xff, 0xff, 0x00, 0x7f, 0x00, 0x00, 0x58, 0xcc, 0x46, 0xd5, 0x94, 0x46, 0x74, 0xb1, 0x30, 0x40, 0x9b, 0x78, - 0xb0, 0x30, 0x4b, 0x1a, 0xa1, 0x93, 0x58, 0x1f, 0x48, 0xd4, 0x81, 0x1e, 0x1e, 0x1e, 0xe2, 0xaf, 0xda, 0x6a, 0x3e, 0x6e, - 0x08, 0x90, 0x5e, 0xd5, 0xf1, 0xce, 0x8b, 0x78, 0x8a, 0x5e, 0xe2, 0x36, 0x45, 0x92, 0xee, 0xeb, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0xe6, 0xb4, 0xf8, 0xd6, 0xa3, 0x68, 0x66, 0xde, 0x70, 0xd4, 0xe0, 0xd6, 0x9a, 0x46, 0x5d, 0xbd, - 0x60, 0x41, 0x2b, 0x19, 0x2b, 0x4b, 0x55, 0x64, 0x60, 0xe4, 0x91, 0x17, 0x5e, 0xa2, 0x08, 0xe0, 0x1c, 0x6e, 0xbd, 0xf1, - 0x08, 0xfd, 0x2d, 0x7b, 0x42, 0x6a, 0x7c, 0xa3, 0x73, 0x6d, 0xb0, 0xfd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x48 -}; -unsigned int test_keychain_len = 45864; +extern unsigned int test_keychain_len; diff --git a/OSX/libsecurity_keychain/xpc-tsa/timestampclient.h b/OSX/libsecurity_keychain/xpc-tsa/timestampclient.h index 4f3d3ae0..7221de7a 100644 --- a/OSX/libsecurity_keychain/xpc-tsa/timestampclient.h +++ b/OSX/libsecurity_keychain/xpc-tsa/timestampclient.h @@ -35,7 +35,7 @@ void sendTSARequest(CFDataRef tsaReq, const char *tsaURL, TSARequestCompletionBl @interface TimeStampClient : NSObject { - id delegate; + __weak id delegate; NSURL *url; NSMutableURLRequest *urlRequest; } diff --git a/OSX/libsecurity_mds/lib/mds.h b/OSX/libsecurity_mds/lib/mds.h index c2d590e4..78764f52 100644 --- a/OSX/libsecurity_mds/lib/mds.h +++ b/OSX/libsecurity_mds/lib/mds.h @@ -38,9 +38,9 @@ extern "C" { typedef CSSM_DL_HANDLE MDS_HANDLE; -typedef CSSM_DL_DB_HANDLE MDS_DB_HANDLE; +typedef CSSM_DL_DB_HANDLE MDS_DB_HANDLE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -typedef struct mds_funcs { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER mds_funcs { CSSM_RETURN (CSSMAPI *DbOpen) (MDS_HANDLE MdsHandle, const char *DbName, diff --git a/OSX/libsecurity_smime/lib/SecCMS.c b/OSX/libsecurity_smime/lib/SecCMS.c index 9cfc874e..53e74aac 100644 --- a/OSX/libsecurity_smime/lib/SecCMS.c +++ b/OSX/libsecurity_smime/lib/SecCMS.c @@ -56,6 +56,7 @@ CFTypeRef kSecCMSSignDate = CFSTR("kSecCMSSignDate"); CFTypeRef kSecCMSAllCerts = CFSTR("kSecCMSAllCerts"); CFTypeRef kSecCMSHashAgility = CFSTR("kSecCMSHashAgility"); CFTypeRef kSecCMSHashAgilityV2 = CFSTR("kSecCMSHashAgilityV2"); +CFTypeRef kSecCMSExpirationDate = CFSTR("kSecCMSExpirationDate"); CFTypeRef kSecCMSBulkEncryptionAlgorithm = CFSTR("kSecCMSBulkEncryptionAlgorithm"); CFTypeRef kSecCMSEncryptionAlgorithmDESCBC = CFSTR("kSecCMSEncryptionAlgorithmDESCBC"); @@ -402,6 +403,15 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det CFDictionarySetValue(attrs, kSecCMSHashAgilityV2, hash_agility_values); } } + + CFAbsoluteTime expiration_time; + if (errSecSuccess == SecCmsSignerInfoGetAppleExpirationTime(sigd->signerInfos[0], &expiration_time)) { + CFDateRef expiration_date = CFDateCreate(NULL, expiration_time); + if (expiration_date) { + CFDictionarySetValue(attrs, kSecCMSExpirationDate, expiration_date); + CFRetainSafe(expiration_date); + } + } *signed_attributes = attrs; if (certs) CFRelease(certs); @@ -449,6 +459,10 @@ CFArrayRef SecCMSCertificatesOnlyMessageCopyCertificates(CFDataRef message) { SecCmsSignedDataRef sigd = NULL; CFMutableArrayRef certs = NULL; + if (!message) { + return NULL; + } + CSSM_DATA encoded_message = { CFDataGetLength(message), (uint8_t*)CFDataGetBytePtr(message) }; require_noerr_quiet(SecCmsMessageDecode(&encoded_message, NULL, NULL, NULL, NULL, NULL, NULL, &cmsg), out); /* expected to be a signed data message at the top level */ @@ -473,8 +487,10 @@ CFArrayRef SecCMSCertificatesOnlyMessageCopyCertificates(CFDataRef message) { } out: - if (cmsg) - SecCmsMessageDestroy(cmsg); + if (cmsg) { SecCmsMessageDestroy(cmsg); } + if (certs && CFArrayGetCount(certs) < 1) { + CFReleaseNull(certs); + } return certs; } diff --git a/OSX/libsecurity_smime/lib/SecCMS.h b/OSX/libsecurity_smime/lib/SecCMS.h index de9a7520..3f6fd394 100644 --- a/OSX/libsecurity_smime/lib/SecCMS.h +++ b/OSX/libsecurity_smime/lib/SecCMS.h @@ -39,6 +39,7 @@ extern const void * kSecCMSSignDate; extern const void * kSecCMSAllCerts; extern const void * kSecCMSHashAgility; extern const void * kSecCMSHashAgilityV2; +extern const void * kSecCMSExpirationDate; extern const void * kSecCMSHashingAlgorithmSHA1; extern const void * kSecCMSHashingAlgorithmSHA256; diff --git a/OSX/libsecurity_smime/lib/SecCmsBase.h b/OSX/libsecurity_smime/lib/SecCmsBase.h index ae85fe2a..8bc62d4c 100644 --- a/OSX/libsecurity_smime/lib/SecCmsBase.h +++ b/OSX/libsecurity_smime/lib/SecCmsBase.h @@ -53,7 +53,7 @@ typedef struct SECOidDataStr SECOidData; @typedef @discussion XXX We might want to get rid of this alltogether. */ -typedef CSSM_X509_ALGORITHM_IDENTIFIER SECAlgorithmID; +typedef CSSM_X509_ALGORITHM_IDENTIFIER SECAlgorithmID DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @typedef @@ -155,7 +155,7 @@ typedef void (*SecCmsContentCallback)(void *arg, const char *buf, size_t len); @typedef @discussion Type of function passed to SecCmsDecode or SecCmsDecoderStart to retrieve the decryption key. This function is intended to be used for EncryptedData content info's which do not have a key available in a certificate, etc. */ -typedef SecSymmetricKeyRef(*SecCmsGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid); +typedef SecSymmetricKeyRef(*SecCmsGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @enum SecCmsVerificationStatus @@ -488,6 +488,9 @@ typedef enum { SEC_OID_APPLE_HASH_AGILITY = 214, SEC_OID_APPLE_HASH_AGILITY_V2 = 215, + /* Apple Expiration Time Attribute */ + SEC_OID_APPLE_EXPIRATION_TIME = 216, + SEC_OID_TOTAL } SECOidTag; diff --git a/OSX/libsecurity_smime/lib/SecCmsContentInfo.h b/OSX/libsecurity_smime/lib/SecCmsContentInfo.h index b9f5d68e..ecc223cf 100644 --- a/OSX/libsecurity_smime/lib/SecCmsContentInfo.h +++ b/OSX/libsecurity_smime/lib/SecCmsContentInfo.h @@ -69,7 +69,7 @@ SecCmsContentInfoGetContent(SecCmsContentInfoRef cinfo); @discussion This is typically only called by SecCmsMessageGetContent(). */ extern CSSM_DATA_PTR -SecCmsContentInfoGetInnerContent(SecCmsContentInfoRef cinfo); +SecCmsContentInfoGetInnerContent(SecCmsContentInfoRef cinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -84,7 +84,7 @@ SecCmsContentInfoGetContentTypeTag(SecCmsContentInfoRef cinfo); @discussion Caches pointer to lookup result for future reference. */ extern CSSM_OID * -SecCmsContentInfoGetContentTypeOID(SecCmsContentInfoRef cinfo); +SecCmsContentInfoGetContentTypeOID(SecCmsContentInfoRef cinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -99,7 +99,7 @@ SecCmsContentInfoGetContentEncAlgTag(SecCmsContentInfoRef cinfo); @discussion Caches pointer to lookup result for future reference. */ extern SECAlgorithmID * -SecCmsContentInfoGetContentEncAlg(SecCmsContentInfoRef cinfo); +SecCmsContentInfoGetContentEncAlg(SecCmsContentInfoRef cinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @functiongroup Message construction */ @@ -115,7 +115,7 @@ SecCmsContentInfoGetContentEncAlg(SecCmsContentInfoRef cinfo); @availability 10.4 and later */ extern OSStatus -SecCmsContentInfoSetContentData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached); +SecCmsContentInfoSetContentData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -170,21 +170,21 @@ extern OSStatus SecCmsContentInfoSetContentEncryptedData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, SecCmsEncryptedDataRef encd); OSStatus -SecCmsContentInfoSetContentOther(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached, const CSSM_OID *eContentType); +SecCmsContentInfoSetContentOther(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached, const CSSM_OID *eContentType) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function */ extern OSStatus SecCmsContentInfoSetContentEncAlg(SecArenaPoolRef pool, SecCmsContentInfoRef cinfo, - SECOidTag bulkalgtag, CSSM_DATA_PTR parameters, int keysize); + SECOidTag bulkalgtag, CSSM_DATA_PTR parameters, int keysize) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function */ extern OSStatus SecCmsContentInfoSetContentEncAlgID(SecArenaPoolRef pool, SecCmsContentInfoRef cinfo, - SECAlgorithmID *algid, int keysize); + SECAlgorithmID *algid, int keysize) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function diff --git a/OSX/libsecurity_smime/lib/SecCmsDecoder.h b/OSX/libsecurity_smime/lib/SecCmsDecoder.h index 01bfe7a2..81efbf57 100644 --- a/OSX/libsecurity_smime/lib/SecCmsDecoder.h +++ b/OSX/libsecurity_smime/lib/SecCmsDecoder.h @@ -71,7 +71,7 @@ SecCmsDecoderCreate(SecArenaPoolRef arena, PK11PasswordFunc pwfn, void *pwfn_arg, SecCmsGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, - SecCmsDecoderRef *outDecoder); + SecCmsDecoderRef *outDecoder) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -133,7 +133,7 @@ SecCmsMessageDecode(const CSSM_DATA *encodedMessage, SecCmsContentCallback cb, void *cb_arg, PK11PasswordFunc pwfn, void *pwfn_arg, SecCmsGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, - SecCmsMessageRef *outMessage); + SecCmsMessageRef *outMessage) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; #if defined(__cplusplus) diff --git a/OSX/libsecurity_smime/lib/SecCmsDigestContext.h b/OSX/libsecurity_smime/lib/SecCmsDigestContext.h index 653cf9b5..a51626d0 100644 --- a/OSX/libsecurity_smime/lib/SecCmsDigestContext.h +++ b/OSX/libsecurity_smime/lib/SecCmsDigestContext.h @@ -46,7 +46,7 @@ extern "C" { @abstract Start digest calculation using all the digest algorithms in "digestalgs" in parallel. */ extern SecCmsDigestContextRef -SecCmsDigestContextStartMultiple(SECAlgorithmID **digestalgs); +SecCmsDigestContextStartMultiple(SECAlgorithmID **digestalgs) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -69,7 +69,7 @@ SecCmsDigestContextCancel(SecCmsDigestContextRef cmsdigcx); */ extern OSStatus SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, SecArenaPoolRef arena, - CSSM_DATA_PTR **digestsp); + CSSM_DATA_PTR **digestsp) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; #if defined(__cplusplus) } diff --git a/OSX/libsecurity_smime/lib/SecCmsDigestedData.h b/OSX/libsecurity_smime/lib/SecCmsDigestedData.h index 4168aff2..cc060727 100644 --- a/OSX/libsecurity_smime/lib/SecCmsDigestedData.h +++ b/OSX/libsecurity_smime/lib/SecCmsDigestedData.h @@ -53,7 +53,7 @@ extern "C" { digest will be calculated while encoding */ extern SecCmsDigestedDataRef -SecCmsDigestedDataCreate(SecCmsMessageRef cmsg, SECAlgorithmID *digestalg); +SecCmsDigestedDataCreate(SecCmsMessageRef cmsg, SECAlgorithmID *digestalg) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function diff --git a/OSX/libsecurity_smime/lib/SecCmsEncoder.h b/OSX/libsecurity_smime/lib/SecCmsEncoder.h index 681f3ae8..a8b43263 100644 --- a/OSX/libsecurity_smime/lib/SecCmsEncoder.h +++ b/OSX/libsecurity_smime/lib/SecCmsEncoder.h @@ -75,7 +75,7 @@ SecCmsEncoderCreate(SecCmsMessageRef cmsg, PK11PasswordFunc pwfn, void *pwfn_arg, SecCmsGetDecryptKeyCallback encrypt_key_cb, void *encrypt_key_cb_arg, SECAlgorithmID **detached_digestalgs, CSSM_DATA_PTR *detached_digests, - SecCmsEncoderRef *outEncoder); + SecCmsEncoderRef *outEncoder) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -120,7 +120,7 @@ SecCmsEncoderFinish(SecCmsEncoderRef encoder); */ extern OSStatus SecCmsMessageEncode(SecCmsMessageRef cmsg, const CSSM_DATA *input, SecArenaPoolRef arena, - CSSM_DATA_PTR outBer); + CSSM_DATA_PTR outBer) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; #if defined(__cplusplus) } diff --git a/OSX/libsecurity_smime/lib/SecCmsMessage.h b/OSX/libsecurity_smime/lib/SecCmsMessage.h index 39aa7275..f9bd38c6 100644 --- a/OSX/libsecurity_smime/lib/SecCmsMessage.h +++ b/OSX/libsecurity_smime/lib/SecCmsMessage.h @@ -99,7 +99,7 @@ SecCmsMessageGetContentInfo(SecCmsMessageRef cmsg); In case of nested contentInfos, this descends and retrieves the innermost content. */ extern CSSM_DATA_PTR -SecCmsMessageGetContent(SecCmsMessageRef cmsg); +SecCmsMessageGetContent(SecCmsMessageRef cmsg) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function diff --git a/OSX/libsecurity_smime/lib/SecCmsRecipientInfo.h b/OSX/libsecurity_smime/lib/SecCmsRecipientInfo.h index 805ec221..6661e7da 100644 --- a/OSX/libsecurity_smime/lib/SecCmsRecipientInfo.h +++ b/OSX/libsecurity_smime/lib/SecCmsRecipientInfo.h @@ -58,7 +58,7 @@ SecCmsRecipientInfoCreate(SecCmsMessageRef cmsg, SecCertificateRef cert); extern SecCmsRecipientInfoRef SecCmsRecipientInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg, CSSM_DATA_PTR subjKeyID, - SecPublicKeyRef pubKey); + SecPublicKeyRef pubKey) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function diff --git a/OSX/libsecurity_smime/lib/SecCmsSignedData.h b/OSX/libsecurity_smime/lib/SecCmsSignedData.h index e7680fa2..a5d9f5b9 100644 --- a/OSX/libsecurity_smime/lib/SecCmsSignedData.h +++ b/OSX/libsecurity_smime/lib/SecCmsSignedData.h @@ -82,7 +82,7 @@ SecCmsSignedDataGetSignerInfo(SecCmsSignedDataRef sigd, int i); @abstract Retrieve the SignedData's digest algorithm list. */ extern SECAlgorithmID ** -SecCmsSignedDataGetDigestAlgs(SecCmsSignedDataRef sigd); +SecCmsSignedDataGetDigestAlgs(SecCmsSignedDataRef sigd) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -161,7 +161,7 @@ SecCmsSignedDataContainsCertsOrCrls(SecCmsSignedDataRef sigd); @abstract Retrieve the SignedData's certificate list. */ extern CSSM_DATA_PTR * -SecCmsSignedDataGetCertificateList(SecCmsSignedDataRef sigd); +SecCmsSignedDataGetCertificateList(SecCmsSignedDataRef sigd) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -176,7 +176,7 @@ SecCmsSignedDataAddSignerInfo(SecCmsSignedDataRef sigd, extern OSStatus SecCmsSignedDataSetDigests(SecCmsSignedDataRef sigd, SECAlgorithmID **digestalgs, - CSSM_DATA_PTR *digests); + CSSM_DATA_PTR *digests) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function diff --git a/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h b/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h index f72605fb..da7117e9 100644 --- a/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h +++ b/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h @@ -55,7 +55,7 @@ SecCmsSignerInfoCreate(SecCmsMessageRef cmsg, SecIdentityRef identity, SECOidTag @function */ extern SecCmsSignerInfoRef -SecCmsSignerInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg, CSSM_DATA_PTR subjKeyID, SecPublicKeyRef pubKey, SecPrivateKeyRef signingKey, SECOidTag digestalgtag); +SecCmsSignerInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg, CSSM_DATA_PTR subjKeyID, SecPublicKeyRef pubKey, SecPrivateKeyRef signingKey, SECOidTag digestalgtag) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -86,7 +86,7 @@ SecCmsSignerInfoVerifyUnAuthAttrsWithPolicy(SecCmsSignerInfoRef signerinfo,CFTyp @function */ extern CSSM_DATA * -SecCmsSignerInfoGetEncDigest(SecCmsSignerInfoRef signerinfo); +SecCmsSignerInfoGetEncDigest(SecCmsSignerInfoRef signerinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -169,6 +169,16 @@ SecCmsSignerInfoGetAppleCodesigningHashAgility(SecCmsSignerInfoRef sinfo, CFData extern OSStatus SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDictionaryRef *sdict); +/*! + @function SecCmsSignerInfoGetAppleExpirationTime + @abstract Return the expriation time, in CFAbsoluteTime, of a CMS signerInfo. + @param sinfo SignerInfo data for this signer. + @discussion Returns a CFAbsoluteTime + @result A return value of SECFailure is an error. + */ +extern OSStatus +SecCmsSignerInfoGetAppleExpirationTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *etime); + /*! @function @abstract Return the signing cert of a CMS signerInfo. @@ -241,7 +251,7 @@ SecCmsSignerInfoAddMSSMIMEEncKeyPrefs(SecCmsSignerInfoRef signerinfo, SecCertifi @abstract Create a timestamp unsigned attribute with a TimeStampToken. */ OSStatus -SecCmsSignerInfoAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA *tstoken); +SecCmsSignerInfoAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA *tstoken) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /*! @function @@ -269,6 +279,16 @@ SecCmsSignerInfoAddCounterSignature(SecCmsSignerInfoRef signerinfo, OSStatus SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef signerinfo, CFDictionaryRef attrValues); +/*! + @function SecCmsSignerInfoAddAppleExpirationTime + @abstract Add the expiration time to the authenticated (i.e. signed) attributes of "signerinfo". + @discussion This is expected to be included in outgoing signed messages for Asset Receipts but is likely + useful in other situations. This should only be added once; a second call will do nothing. + @result A result of SECFailure indicates an error adding the attribute. + */ +extern OSStatus +SecCmsSignerInfoAddAppleExpirationTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t); + /*! @function @abstract The following needs to be done in the S/MIME layer code after signature of a signerinfo has been verified. diff --git a/OSX/libsecurity_smime/lib/cert.c b/OSX/libsecurity_smime/lib/cert.c index 97a5e3d0..2f3bc4ae 100644 --- a/OSX/libsecurity_smime/lib/cert.c +++ b/OSX/libsecurity_smime/lib/cert.c @@ -249,6 +249,7 @@ CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Bo SecTrustRef trust = NULL; CFMutableArrayRef certs = NULL; OSStatus status = 0; + SecTrustResultType trustResult = kSecTrustResultInvalid; if (!cert) goto loser; @@ -264,7 +265,7 @@ CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Bo /* SecTrustEvaluate will build us the best chain available using its heuristics. * We'll ignore the trust result. */ - status = SecTrustEvaluate(trust, NULL); + status = SecTrustEvaluate(trust, &trustResult); if (status) goto loser; CFIndex idx, count = SecTrustGetCertificateCount(trust); @@ -318,9 +319,7 @@ CFArrayRef CERT_DupCertList(CFArrayRef oldList) // Extract a public key object from a SubjectPublicKeyInfo SecPublicKeyRef CERT_ExtractPublicKey(SecCertificateRef cert) { - SecPublicKeyRef keyRef = NULL; - SecCertificateCopyPublicKey(cert,&keyRef); - return keyRef; + return SecCertificateCopyKey(cert); } SECStatus CERT_CheckCertUsage (SecCertificateRef cert,unsigned char usage) @@ -357,9 +356,7 @@ SecCertificateRef CERT_FindCertByDERCert(SecKeychainRef keychainOrArray, const S return cert; } -static int compareCssmData( - const CSSM_DATA *d1, - const CSSM_DATA *d2) +int CERT_CompareCssmData(const CSSM_DATA *d1, const CSSM_DATA *d2) { if((d1 == NULL) || (d2 == NULL)) { return 0; @@ -398,11 +395,11 @@ SecCertificateRef CERT_FindCertByIssuerAndSN (CFTypeRef keychainOrArray, CFRelease(certificate); continue; } - if(!compareCssmData(&isn->derIssuer, &issuerAndSN->derIssuer)) { + if(!CERT_CompareCssmData(&isn->derIssuer, &issuerAndSN->derIssuer)) { CFRelease(certificate); continue; } - if(!compareCssmData(&isn->serialNumber, &issuerAndSN->serialNumber)) { + if(!CERT_CompareCssmData(&isn->serialNumber, &issuerAndSN->serialNumber)) { CFRelease(certificate); continue; } @@ -420,10 +417,10 @@ SecCertificateRef CERT_FindCertByIssuerAndSN (CFTypeRef keychainOrArray, if(isn == NULL) { continue; } - if(!compareCssmData(&isn->derIssuer, &issuerAndSN->derIssuer)) { + if(!CERT_CompareCssmData(&isn->derIssuer, &issuerAndSN->derIssuer)) { continue; } - if(!compareCssmData(&isn->serialNumber, &issuerAndSN->serialNumber)) { + if(!CERT_CompareCssmData(&isn->serialNumber, &issuerAndSN->serialNumber)) { continue; } certificate = cert; @@ -469,7 +466,7 @@ SecCertificateRef CERT_FindCertBySubjectKeyID (CFTypeRef keychainOrArray, /* not present */ continue; } - match = compareCssmData(subjKeyID, &skid); + match = CERT_CompareCssmData(subjKeyID, &skid); SECITEM_FreeItem(&skid, PR_FALSE); if(match) { /* got it */ diff --git a/OSX/libsecurity_smime/lib/cert.h b/OSX/libsecurity_smime/lib/cert.h index 500eb9c1..74d88af0 100644 --- a/OSX/libsecurity_smime/lib/cert.h +++ b/OSX/libsecurity_smime/lib/cert.h @@ -127,6 +127,8 @@ SECStatus CERT_VerifyCert(SecKeychainRef keychainOrArray, SecCertificateRef cert CFTypeRef CERT_PolicyForCertUsage(SECCertUsage certUsage); +int CERT_CompareCssmData(const CSSM_DATA *d1, const CSSM_DATA *d2); + /************************************************************************/ SEC_END_PROTOS diff --git a/OSX/libsecurity_smime/lib/cmsattr.c b/OSX/libsecurity_smime/lib/cmsattr.c index 28e9ba11..8497904b 100644 --- a/OSX/libsecurity_smime/lib/cmsattr.c +++ b/OSX/libsecurity_smime/lib/cmsattr.c @@ -262,6 +262,7 @@ cms_attr_choose_attr_value_template(void *src_or_dest, Boolean encoding, const c theTemplate = SEC_ASN1_GET(kSecAsn1OctetStringTemplate); break; case SEC_OID_PKCS9_SIGNING_TIME: + case SEC_OID_APPLE_EXPIRATION_TIME: encoded = PR_FALSE; theTemplate = SEC_ASN1_GET(kSecAsn1UTCTimeTemplate); // @@@ This should be a choice between UTCTime and GeneralizedTime -- mb break; diff --git a/OSX/libsecurity_smime/lib/cmspriv.h b/OSX/libsecurity_smime/lib/cmspriv.h index db88bb49..5e41d83e 100644 --- a/OSX/libsecurity_smime/lib/cmspriv.h +++ b/OSX/libsecurity_smime/lib/cmspriv.h @@ -298,7 +298,7 @@ SecCmsSignerInfoGetVersion(SecCmsSignerInfoRef signerinfo); * Implemented in siginfoUtils.cpp for access to C++ Dictionary class. */ extern bool -SecCmsMsEcdsaCompatMode(); +SecCmsMsEcdsaCompatMode(void); /************************************************************************ diff --git a/OSX/libsecurity_smime/lib/cmspubkey.c b/OSX/libsecurity_smime/lib/cmspubkey.c index ea27d7ce..c4dc0eaa 100644 --- a/OSX/libsecurity_smime/lib/cmspubkey.c +++ b/OSX/libsecurity_smime/lib/cmspubkey.c @@ -65,15 +65,16 @@ * according to PKCS#1 and RFC2633 (S/MIME) */ OSStatus -SecCmsUtilEncryptSymKeyRSA(PLArenaPool *poolp, SecCertificateRef cert, +SecCmsUtilEncryptSymKeyRSA(PLArenaPool *poolp, SecCertificateRef cert, SecSymmetricKeyRef bulkkey, CSSM_DATA_PTR encKey) { - SecPublicKeyRef publickey = SecCertificateCopyPublicKey_ios(cert); + OSStatus rv; + SecPublicKeyRef publickey = SecCertificateCopyKey(cert); if (publickey == NULL) return SECFailure; - OSStatus rv = SecCmsUtilEncryptSymKeyRSAPubKey(poolp, publickey, bulkkey, encKey); + rv = SecCmsUtilEncryptSymKeyRSAPubKey(poolp, publickey, bulkkey, encKey); CFRelease(publickey); return rv; } @@ -92,15 +93,6 @@ SecCmsUtilEncryptSymKeyRSAPubKey(PLArenaPool *poolp, mark = PORT_ArenaMark(poolp); if (!mark) goto loser; - -#if 0 - /* sanity check */ - keyType = SECKEY_GetPublicKeyType(publickey); - PORT_Assert(keyType == rsaKey); - if (keyType != rsaKey) { - goto loser; - } -#endif /* allocate memory for the encrypted key */ theirKeyAttrs = SecKeyCopyAttributes(publickey); if (!theirKeyAttrs) { @@ -779,11 +771,7 @@ SecCmsUtilEncryptSymKeyECDH( encKey->Length = 0; /* Copy the recipient's static public ECDH key */ -#if TARGET_OS_IPHONE - theirPubKey = SecCertificateCopyPublicKey(cert); -#else - rv = SecCertificateCopyPublicKey(cert, &theirPubKey); -#endif + theirPubKey = SecCertificateCopyKey(cert); if (rv || !theirPubKey) { dprintf("SecCmsUtilEncryptSymKeyECDH: failed to get public key from cert, %d\n", (int)rv); goto out; diff --git a/OSX/libsecurity_smime/lib/cmssigdata.c b/OSX/libsecurity_smime/lib/cmssigdata.c index 474d7633..a173aa13 100644 --- a/OSX/libsecurity_smime/lib/cmssigdata.c +++ b/OSX/libsecurity_smime/lib/cmssigdata.c @@ -223,7 +223,7 @@ SecCmsSignedDataEncodeBeforeData(SecCmsSignedDataRef sigd) extern const SecAsn1Template kSecAsn1TSATSTInfoTemplate; -OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR encDigest, +OSStatus createTSAMessageImprint(SecCmsSignerInfoRef signerInfo, SECAlgorithmID *digestAlg, CSSM_DATA_PTR encDigest, SecAsn1TSAMessageImprint *messageImprint) { // Calculate hash of encDigest and put in messageImprint.hashedMessage @@ -231,21 +231,17 @@ OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR e OSStatus status = SECFailure; - require(signedData && messageImprint, xit); - - SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData); - require(digestAlgorithms, xit); + require(signerInfo && digestAlg && messageImprint, xit); - SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestAlgorithms); + SecCmsDigestContextRef digcx = SecCmsDigestContextStartSingle(digestAlg); require(digcx, xit); require(encDigest, xit); - SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(signedData, 0); // NB - assume 1 signer only! - messageImprint->hashAlgorithm = signerinfo->digestAlg; + messageImprint->hashAlgorithm = *digestAlg; SecCmsDigestContextUpdate(digcx, encDigest->Data, encDigest->Length); - require_noerr(SecCmsDigestContextFinishSingle(digcx, (SecArenaPoolRef)signedData->cmsg->poolp, + require_noerr(SecCmsDigestContextFinishSingle(digcx, (SecArenaPoolRef)signerInfo->cmsg->poolp, &messageImprint->hashedMessage), xit); status = SECSuccess; @@ -354,7 +350,8 @@ static OSStatus validateTSAResponseAndAddTimeStamp(SecCmsSignerInfoRef signerinf The code for this is essentially the same code taht is done during a timestamp verify, except that we also need to check the nonce. */ - require_noerr(status = decodeTimeStampToken(signerinfo, &respDER.timeStampTokenDER, NULL, expectedNonce), xit); + CSSM_DATA *encDigest = SecCmsSignerInfoGetEncDigest(signerinfo); + require_noerr(status = decodeTimeStampToken(signerinfo, &respDER.timeStampTokenDER, encDigest, expectedNonce), xit); status = SecCmsSignerInfoAddTimeStamp(signerinfo, &respDER.timeStampTokenDER); @@ -500,7 +497,7 @@ SecCmsSignedDataEncodeAfterData(SecCmsSignedDataRef sigd) // Calculate hash of encDigest and put in messageImprint.hashedMessage SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(sigd, 0); // NB - assume 1 signer only! CSSM_DATA *encDigest = SecCmsSignerInfoGetEncDigest(signerinfo); - require_noerr(createTSAMessageImprint(sigd, encDigest, &messageImprint), tsxit); + require_noerr(createTSAMessageImprint(signerinfo, &signerinfo->digestAlg, encDigest, &messageImprint), tsxit); // Callback to fire up XPC service to talk to TimeStamping server, etc. require_noerr(rv =(*sigd->cmsg->tsaCallback)(sigd->cmsg->tsaContext, &messageImprint, diff --git a/OSX/libsecurity_smime/lib/cmssiginfo.c b/OSX/libsecurity_smime/lib/cmssiginfo.c index ea597eeb..3c1ff754 100644 --- a/OSX/libsecurity_smime/lib/cmssiginfo.c +++ b/OSX/libsecurity_smime/lib/cmssiginfo.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -633,9 +634,7 @@ SecCmsSignerInfoVerifyWithPolicy(SecCmsSignerInfoRef signerinfo,CFTypeRef timeSt debugShowSigningCertificate(signerinfo); - OSStatus status; - if ((status = SecCertificateCopyPublicKey(cert, &publickey))) { - syslog(LOG_ERR, "SecCmsSignerInfoVerifyWithPolicy: copy public key failed %d", (int)status); + if (NULL == (publickey = SecCertificateCopyKey(cert))) { vs = SecCmsVSProcessingError; goto loser; } @@ -821,6 +820,10 @@ SecCmsSignerInfoVerifyUnAuthAttrsWithPolicy(SecCmsSignerInfoRef signerinfo,CFTyp dprintf("found an id-ct-TSTInfo\n"); // Don't check the nonce in this case status = decodeTimeStampTokenWithPolicy(signerinfo, timeStampPolicy, (attr->values)[0], &signerinfo->encDigest, 0); + if (status != errSecSuccess) { + secerror("timestamp verification failed: %d", (int)status); + } + xit: return status; } @@ -1095,6 +1098,41 @@ SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDi return errSecAllocate; } +/* + * SecCmsSignerInfoGetAppleExpirationTime - return the expiration time, + * in UTCTime format, of a CMS signerInfo. + * + * sinfo - signerInfo data for this signer + * + * Returns a pointer to XXXX (what?) + * A return value of NULL is an error. + */ +OSStatus +SecCmsSignerInfoGetAppleExpirationTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *etime) +{ + SecCmsAttribute *attr = NULL; + SecAsn1Item * value = NULL; + + if (sinfo == NULL || etime == NULL) { + return SECFailure; + } + + if (sinfo->expirationTime != 0) { + *etime = sinfo->expirationTime; /* cached copy */ + return SECSuccess; + } + + attr = SecCmsAttributeArrayFindAttrByOidTag(sinfo->authAttr, SEC_OID_APPLE_EXPIRATION_TIME, PR_TRUE); + if (attr == NULL || (value = SecCmsAttributeGetValue(attr)) == NULL) { + return SECFailure; + } + if (DER_UTCTimeToCFDate(value, etime) != SECSuccess) { + return SECFailure; + } + sinfo->expirationTime = *etime; /* make cached copy */ + return SECSuccess; +} + /* * Return the signing cert of a CMS signerInfo. * @@ -1621,6 +1659,46 @@ loser: return status; } +/* + * SecCmsSignerInfoAddAppleExpirationTime - add the expiration time to the + * authenticated (i.e. signed) attributes of "signerinfo". + * + * This is expected to be included in outgoing signed + * messages for Asset Receipts but is likely useful in other situations. + * + * This should only be added once; a second call will do nothing. + */ +OSStatus +SecCmsSignerInfoAddAppleExpirationTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t) +{ + SecCmsAttribute *attr = NULL; + PLArenaPool *poolp = signerinfo->cmsg->poolp; + void *mark = PORT_ArenaMark(poolp); + + /* create new expiration time attribute */ + SecAsn1Item etime; + if (DER_CFDateToUTCTime(t, &etime) != SECSuccess) { + goto loser; + } + + if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_APPLE_EXPIRATION_TIME, &etime, PR_FALSE)) == NULL) { + SECITEM_FreeItem (&etime, PR_FALSE); + goto loser; + } + + SECITEM_FreeItem(&etime, PR_FALSE); + + if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) { + goto loser; + } + + PORT_ArenaUnmark(poolp, mark); + return SECSuccess; + +loser: + PORT_ArenaRelease(poolp, mark); + return SECFailure; +} SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSignerInfoRef signerinfo) { SecCertificateRef cert = NULL; diff --git a/OSX/libsecurity_smime/lib/cmstpriv.h b/OSX/libsecurity_smime/lib/cmstpriv.h index 483c1985..5d0f5617 100644 --- a/OSX/libsecurity_smime/lib/cmstpriv.h +++ b/OSX/libsecurity_smime/lib/cmstpriv.h @@ -229,6 +229,7 @@ struct SecCmsSignerInfoStr { SecCertificateRef timestampCert; CFDataRef hashAgilityAttrValue; CFDictionaryRef hashAgilityV2AttrValues; + CFAbsoluteTime expirationTime; }; #define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */ #define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */ diff --git a/OSX/libsecurity_smime/lib/secoid.c b/OSX/libsecurity_smime/lib/secoid.c index 54904fb8..cb1c9b9d 100644 --- a/OSX/libsecurity_smime/lib/secoid.c +++ b/OSX/libsecurity_smime/lib/secoid.c @@ -477,6 +477,9 @@ CONST_OID mqvSinglePassSha1kdf[] = {ANSI_X9_63_SCHEME, 4 }; CONST_OID appleHashAgility[] = {APPLE_CMS_ATTRIBUTES, 1}; CONST_OID appleHashAgilityV2[] = {APPLE_CMS_ATTRIBUTES, 2}; +/* Apple Expiration Time */ +CONST_OID appleExpirationTime[] = {APPLE_CMS_ATTRIBUTES, 3}; + /* a special case: always associated with a caller-specified OID */ CONST_OID noOid[] = { 0 }; @@ -1155,6 +1158,11 @@ const static SECOidData oids[] = { OD( appleHashAgilityV2, SEC_OID_APPLE_HASH_AGILITY_V2, "appleCodesigningHashAgilityAttribute", CSSM_ALGID_NONE, INVALID_CERT_EXTENSION), + + /* Apple Expiration Time */ + OD( appleExpirationTime, SEC_OID_APPLE_EXPIRATION_TIME, + "appleExpirationTimeAttribute", CSSM_ALGID_NONE, + INVALID_CERT_EXTENSION), }; /* diff --git a/OSX/libsecurity_smime/lib/smimeutil.c b/OSX/libsecurity_smime/lib/smimeutil.c index 87dfc41b..61bd6f05 100644 --- a/OSX/libsecurity_smime/lib/smimeutil.c +++ b/OSX/libsecurity_smime/lib/smimeutil.c @@ -139,13 +139,13 @@ typedef struct { static smime_cipher_map_entry smime_cipher_map[] = { /* cipher algtag parms enabled allowed */ /* ---------------------------------------------------------------------------------- */ - { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, ¶m_int40, PR_TRUE, PR_TRUE }, - { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL, PR_TRUE, PR_TRUE }, - { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, ¶m_int64, PR_TRUE, PR_TRUE }, + { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, ¶m_int40, PR_FALSE,PR_TRUE }, + { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL, PR_FALSE,PR_TRUE }, + { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, ¶m_int64, PR_FALSE,PR_TRUE }, { SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, ¶m_int128, PR_TRUE, PR_TRUE }, { SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL, PR_TRUE, PR_TRUE }, { SMIME_AES_CBC_128, SEC_OID_AES_128_CBC, NULL, PR_TRUE, PR_TRUE }, - { SMIME_FORTEZZA, SEC_OID_FORTEZZA_SKIPJACK, NULL, PR_TRUE, PR_TRUE } + { SMIME_FORTEZZA, SEC_OID_FORTEZZA_SKIPJACK, NULL, PR_FALSE, PR_TRUE } }; static const int smime_cipher_map_count = sizeof(smime_cipher_map) / sizeof(smime_cipher_map_entry); @@ -377,10 +377,9 @@ smime_choose_cipher(SecCertificateRef scert, SecCertificateRef *rcerts) { PRArenaPool *poolp; long cipher; - long chosen_cipher; + long chosen_cipher = SMIME_DES_EDE3_168; int *cipher_abilities; int *cipher_votes; - int weak_mapi; int strong_mapi; int rcount, mapi, max, i; #if 1 @@ -390,9 +389,6 @@ smime_choose_cipher(SecCertificateRef scert, SecCertificateRef *rcerts) Boolean scert_is_fortezza = (scert == NULL) ? PR_FALSE : PK11_FortezzaHasKEA(scert); #endif - chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */ - weak_mapi = smime_mapi_by_cipher(chosen_cipher); - poolp = PORT_NewArena (1024); /* XXX what is right value? */ if (poolp == NULL) goto done; @@ -445,39 +441,10 @@ smime_choose_cipher(SecCertificateRef scert, SecCertificateRef *rcerts) } } } else { - /* no profile found - so we can only assume that the user can do - * the mandatory algorithms which is RC2-40 (weak crypto) and 3DES (strong crypto) */ - SecPublicKeyRef key; - unsigned int pklen_bits; - - /* - * if recipient's public key length is > 512, vote for a strong cipher - * please not that the side effect of this is that if only one recipient - * has an export-level public key, the strong cipher is disabled. - * - * XXX This is probably only good for RSA keys. What I would - * really like is a function to just say; Is the public key in - * this cert an export-length key? Then I would not have to - * know things like the value 512, or the kind of key, or what - * a subjectPublicKeyInfo is, etc. - */ - key = CERT_ExtractPublicKey(rcerts[rcount]); - pklen_bits = 0; - if (key != NULL) { - SecKeyGetStrengthInBits(key, NULL, &pklen_bits); - SECKEY_DestroyPublicKey (key); - } - - if (pklen_bits > 512) { - /* cast votes for the strong algorithm */ - cipher_abilities[strong_mapi]++; - cipher_votes[strong_mapi] += pref; - pref--; - } - - /* always cast (possibly less) votes for the weak algorithm */ - cipher_abilities[weak_mapi]++; - cipher_votes[weak_mapi] += pref; + /* cast votes for the strong algorithm */ + cipher_abilities[strong_mapi]++; + cipher_votes[strong_mapi] += pref; + pref--; } if (profile != NULL) SECITEM_FreeItem(profile, PR_TRUE); diff --git a/OSX/libsecurity_smime/lib/tsaSupport.c b/OSX/libsecurity_smime/lib/tsaSupport.c index bf92c7bd..ac6c155f 100644 --- a/OSX/libsecurity_smime/lib/tsaSupport.c +++ b/OSX/libsecurity_smime/lib/tsaSupport.c @@ -48,11 +48,13 @@ #include #include #include +#include #include "tsaSupport.h" #include "tsaSupportPriv.h" #include "tsaTemplates.h" #include "cmslocal.h" +#include "cert.h" #include "secoid.h" #include "secitem.h" @@ -896,7 +898,7 @@ xit: return result; } -static OSStatus verifyTSTInfo(const CSSM_DATA_PTR content, SecCertificateRef signerCert, SecAsn1TSATSTInfo *tstInfo, CFAbsoluteTime *timestampTime, uint64_t expectedNonce) +static OSStatus verifyTSTInfo(const CSSM_DATA_PTR content, SecCmsSignerInfoRef signerinfo, SecAsn1TSATSTInfo *tstInfo, CFAbsoluteTime *timestampTime, uint64_t expectedNonce, CSSM_DATA_PTR encDigest) { OSStatus status = paramErr; SecAsn1CoderRef coder = NULL; @@ -904,6 +906,9 @@ static OSStatus verifyTSTInfo(const CSSM_DATA_PTR content, SecCertificateRef sig if (!tstInfo) return SECFailure; + SecCertificateRef signerCert = SecCmsSignerInfoGetTimestampSigningCert(signerinfo); + SecAsn1TSAMessageImprint expectedMessageImprint; + require_noerr(SecAsn1CoderCreate(&coder), xit); require_noerr(SecAsn1Decode(coder, content->Data, content->Length, kSecAsn1TSATSTInfoTemplate, tstInfo), xit); @@ -918,9 +923,18 @@ static OSStatus verifyTSTInfo(const CSSM_DATA_PTR content, SecCertificateRef sig require_action(expectedNonce==nonce, xit, status = errSecTimestampRejection); } - status = SecTSAValidateTimestamp(tstInfo, signerCert, timestampTime); + // Check the times in the timestamp + require_noerr(status = SecTSAValidateTimestamp(tstInfo, signerCert, timestampTime), xit); dtprintf("SecTSAValidateTimestamp result: %ld\n", (long)status); + // Check the message imprint against the encDigest from the signerInfo containing this timestamp + SECOidTag hashAlg = SECOID_GetAlgorithmTag(&tstInfo->messageImprint.hashAlgorithm); + require_action(hashAlg == SEC_OID_SHA256 || hashAlg == SEC_OID_SHA1, xit, status = errSecInvalidDigestAlgorithm); + require_noerr(status = createTSAMessageImprint(signerinfo, &tstInfo->messageImprint.hashAlgorithm, + encDigest, &expectedMessageImprint), xit); + require_action(CERT_CompareCssmData(&expectedMessageImprint.hashedMessage, &tstInfo->messageImprint.hashedMessage), xit, + status = errSecTimestampInvalid; secerror("Timestamp MessageImprint did not match the signature's hash")); + xit: if (coder) SecAsn1CoderRelease(coder); @@ -1235,15 +1249,15 @@ OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inDa OSStatus decodeTimeStampTokenWithPolicy(SecCmsSignerInfoRef signerinfo, CFTypeRef timeStampPolicy, CSSM_DATA_PTR inData, CSSM_DATA_PTR encDigest, uint64_t expectedNonce) { /* - We update signerinfo with timestamp and tsa certificate chain. - encDigest is the original signed blob, which we must hash and compare. - inData comes from the unAuthAttr section of the CMS message - - These are set in signerinfo as side effects: - timestampTime - timestampCertList - timestampCert - */ + We update signerinfo with timestamp and tsa certificate chain. + encDigest is the original signed blob, which we must hash and compare. + inData comes from the unAuthAttr section of the CMS message + + These are set in signerinfo as side effects: + timestampTime + timestampCertList + timestampCert + */ SecCmsDecoderRef decoderContext = NULL; SecCmsMessageRef cmsMessage = NULL; @@ -1261,23 +1275,22 @@ OSStatus decodeTimeStampTokenWithPolicy(SecCmsSignerInfoRef signerinfo, CFTypeRe /* decode the message */ require_noerr(result = SecCmsDecoderCreate (NULL, NULL, NULL, NULL, NULL, NULL, NULL, &decoderContext), xit); result = SecCmsDecoderUpdate(decoderContext, inData->Data, inData->Length); - if (result) - { + if (result) { result = errSecTimestampInvalid; SecCmsDecoderDestroy(decoderContext); goto xit; - } + } require_noerr(result = SecCmsDecoderFinish(decoderContext, &cmsMessage), xit); // process the results contentLevelCount = SecCmsMessageContentLevelCount(cmsMessage); - if (encDigest) + if (encDigest) { printDataAsHex("encDigest",encDigest, 0); + } - for (ix = 0; ix < contentLevelCount; ++ix) - { + for (ix = 0; ix < contentLevelCount; ++ix) { dtprintf("\n----- Content Level %d -----\n", ix); // get content information contentInfo = SecCmsMessageContentLevel (cmsMessage, ix); @@ -1287,115 +1300,102 @@ OSStatus decodeTimeStampTokenWithPolicy(SecCmsSignerInfoRef signerinfo, CFTypeRe debugShowContentTypeOID(contentInfo); - switch (contentTypeTag) - { - case SEC_OID_PKCS7_SIGNED_DATA: - { - require((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(contentInfo)) != NULL, xit); + switch (contentTypeTag) { + case SEC_OID_PKCS7_SIGNED_DATA: { + require((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(contentInfo)) != NULL, xit); + + debugShowSignerInfo(signedData); + + SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData); + unsigned digestAlgCount = SecCmsArrayCount((void **)digestAlgorithms); + dtprintf("digestAlgCount: %d\n", digestAlgCount); + if (signedData->digests) { + int jx; + char buffer[128]; + for (jx=0;jx < digestAlgCount;jx++) { + sprintf(buffer, " digest[%u]", jx); + printDataAsHex(buffer,signedData->digests[jx], 0); + } + } else { + dtprintf("digests not yet computed\n"); + CSSM_DATA_PTR innerContent = SecCmsContentInfoGetInnerContent(contentInfo); + if (innerContent) + { + dtprintf("inner content length: %ld\n", innerContent->Length); + SecAsn1TSAMessageImprint fakeMessageImprint = {{{0}},}; + SecCmsSignerInfoRef tsaSigner = SecCmsSignedDataGetSignerInfo(signedData, 0); + OSStatus status = createTSAMessageImprint(tsaSigner, &tsaSigner->digestAlg, innerContent, &fakeMessageImprint); + require_noerr_action(status, xit, dtprintf("createTSAMessageImprint status: %d\n", (int)status); result = status); + printDataAsHex("inner content hash",&fakeMessageImprint.hashedMessage, 0); + CSSM_DATA_PTR digestdata = &fakeMessageImprint.hashedMessage; + CSSM_DATA_PTR digests[2] = {digestdata, NULL}; + status = SecCmsSignedDataSetDigests(signedData, digestAlgorithms, (CSSM_DATA_PTR *)&digests); + require_noerr_action(status, xit, dtprintf("createTSAMessageImprint status: %d\n", (int)status); result = status); + } else { + dtprintf("no inner content\n"); + } + } - debugShowSignerInfo(signedData); + /* + Import the certificates. We leave this as a warning, since + there are configurations where the certificates are not returned. + */ + signingCerts = SecCmsSignedDataGetCertificateList(signedData); + if (signingCerts == NULL) { + dtprintf("SecCmsSignedDataGetCertificateList returned NULL\n"); + } else { + if (!signerinfo->timestampCertList) { + signerinfo->timestampCertList = CFArrayCreateMutable(kCFAllocatorDefault, 10, &kCFTypeArrayCallBacks); + } + saveTSACertificates(signingCerts, signerinfo->timestampCertList); + require_noerr(result = setTSALeafValidityDates(signerinfo), xit); + debugSaveCertificates(signingCerts); + } - SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData); - unsigned digestAlgCount = SecCmsArrayCount((void **)digestAlgorithms); - dtprintf("digestAlgCount: %d\n", digestAlgCount); - if (signedData->digests) - { - int jx; - char buffer[128]; - for (jx=0;jx < digestAlgCount;jx++) - { - sprintf(buffer, " digest[%u]", jx); - printDataAsHex(buffer,signedData->digests[jx], 0); + int numberOfSigners = SecCmsSignedDataSignerInfoCount (signedData); + + if (numberOfSigners > 0) { + /* @@@ assume there's only one signer since SecCms can't handle multiple signers anyway */ + signerinfo->timestampCert = CFRetainSafe(SecCmsSignerInfoGetSigningCertificate(signedData->signerInfos[0], NULL)); } - } - else - { - dtprintf("No digests\n"); - CSSM_DATA_PTR innerContent = SecCmsContentInfoGetInnerContent(contentInfo); - if (innerContent) - { - dtprintf("inner content length: %ld\n", innerContent->Length); - SecAsn1TSAMessageImprint fakeMessageImprint = {{{0}},}; - OSStatus status = createTSAMessageImprint(signedData, innerContent, &fakeMessageImprint); - require_noerr_action(status, xit, dtprintf("createTSAMessageImprint status: %d\n", (int)status); result = status); - printDataAsHex("inner content hash",&fakeMessageImprint.hashedMessage, 0); - CSSM_DATA_PTR digestdata = &fakeMessageImprint.hashedMessage; - CSSM_DATA_PTR digests[2] = {digestdata, NULL}; - status = SecCmsSignedDataSetDigests(signedData, digestAlgorithms, (CSSM_DATA_PTR *)&digests); - require_noerr_action(status, xit, dtprintf("createTSAMessageImprint status: %d\n", (int)status); result = status); + + result = verifySigners(signedData, numberOfSigners, timeStampPolicy); + if (result) { + dtprintf("verifySigners failed: %ld\n", (long)result); // warning + goto xit; // remap to SecCmsVSTimestampNotTrusted ? } - else - dtprintf("no inner content\n"); - } - /* - Import the certificates. We leave this as a warning, since - there are configurations where the certificates are not returned. - */ - signingCerts = SecCmsSignedDataGetCertificateList(signedData); - if (signingCerts == NULL) - { dtprintf("SecCmsSignedDataGetCertificateList returned NULL\n"); } - else - { - if (!signerinfo->timestampCertList) - signerinfo->timestampCertList = CFArrayCreateMutable(kCFAllocatorDefault, 10, &kCFTypeArrayCallBacks); - saveTSACertificates(signingCerts, signerinfo->timestampCertList); - require_noerr(result = setTSALeafValidityDates(signerinfo), xit); - debugSaveCertificates(signingCerts); + break; } - - int numberOfSigners = SecCmsSignedDataSignerInfoCount (signedData); - - if (numberOfSigners > 0) { - /* @@@ assume there's only one signer since SecCms can't handle multiple signers anyway */ - signerinfo->timestampCert = CFRetainSafe(SecCmsSignerInfoGetSigningCertificate(signedData->signerInfos[0], NULL)); + case SEC_OID_PKCS9_SIGNING_CERTIFICATE: { + dtprintf("SEC_OID_PKCS9_SIGNING_CERTIFICATE seen\n"); + break; } - - result = verifySigners(signedData, numberOfSigners, timeStampPolicy); - if (result) - dtprintf("verifySigners failed: %ld\n", (long)result); // warning - - - if (result) // remap to SecCmsVSTimestampNotTrusted ? - goto xit; - - break; - } - case SEC_OID_PKCS9_SIGNING_CERTIFICATE: - { - dtprintf("SEC_OID_PKCS9_SIGNING_CERTIFICATE seen\n"); - break; - } - - case SEC_OID_PKCS9_ID_CT_TSTInfo: - { - SecAsn1TSATSTInfo tstInfo = {{0},}; - SecCertificateRef signerCert = SecCmsSignerInfoGetTimestampSigningCert(signerinfo); - result = verifyTSTInfo(contentInfo->rawContent, signerCert, &tstInfo, &signerinfo->timestampTime, expectedNonce); - if (signerinfo->timestampTime) - { - const char *tstamp = cfabsoluteTimeToString(signerinfo->timestampTime); - if (tstamp) - { - dtprintf("Timestamp Authority timestamp: %s\n", tstamp); - free((void *)tstamp); + case SEC_OID_PKCS9_ID_CT_TSTInfo: { + SecAsn1TSATSTInfo tstInfo = {{0},}; + result = verifyTSTInfo(contentInfo->rawContent, signerinfo, &tstInfo, &signerinfo->timestampTime, expectedNonce, encDigest); + if (signerinfo->timestampTime) { + const char *tstamp = cfabsoluteTimeToString(signerinfo->timestampTime); + if (tstamp) { + dtprintf("Timestamp Authority timestamp: %s\n", tstamp); + free((void *)tstamp); + } } + break; } - break; - } - case SEC_OID_OTHER: - { - dtprintf("otherContent : %p\n", (char *)SecCmsContentInfoGetContent (contentInfo)); - break; - } - default: - dtprintf("ContentTypeTag : %x\n", contentTypeTag); - break; + case SEC_OID_OTHER: { + dtprintf("otherContent : %p\n", (char *)SecCmsContentInfoGetContent (contentInfo)); + break; + } + default: + dtprintf("ContentTypeTag : %x\n", contentTypeTag); + break; } } xit: - if (cmsMessage) - SecCmsMessageDestroy(cmsMessage); + if (cmsMessage) { + SecCmsMessageDestroy(cmsMessage); + } return result; } diff --git a/OSX/libsecurity_smime/lib/tsaSupport.h b/OSX/libsecurity_smime/lib/tsaSupport.h index 9ccbd6e6..149381f1 100644 --- a/OSX/libsecurity_smime/lib/tsaSupport.h +++ b/OSX/libsecurity_smime/lib/tsaSupport.h @@ -40,7 +40,7 @@ extern "C" { extern const CFStringRef kTSAContextKeyURL; // CFURLRef extern const CFStringRef kTSAContextKeyNoCerts; // CFBooleanRef -OSStatus SecCmsTSADefaultCallback(CFTypeRef context, void *messageImprint, uint64_t nonce, CSSM_DATA *signedDERBlob); +OSStatus SecCmsTSADefaultCallback(CFTypeRef context, void *messageImprint, uint64_t nonce, CSSM_DATA *signedDERBlob) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; CFMutableDictionaryRef SecCmsTSAGetDefaultContext(CFErrorRef *error); void SecCmsMessageSetTSAContext(SecCmsMessageRef cmsg, CFTypeRef tsaContext); diff --git a/OSX/libsecurity_smime/lib/tsaSupportPriv.h b/OSX/libsecurity_smime/lib/tsaSupportPriv.h index 985df045..4a3817d1 100644 --- a/OSX/libsecurity_smime/lib/tsaSupportPriv.h +++ b/OSX/libsecurity_smime/lib/tsaSupportPriv.h @@ -42,7 +42,8 @@ extern const CFStringRef kTSADebugContextKeyBadNonce; // CFBooleanRef OSStatus SecTSAResponseCopyDEREncoding(SecAsn1CoderRef coder, const CSSM_DATA *tsaResponse, SecAsn1TimeStampRespDER *respDER); OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inData, CSSM_DATA_PTR encDigest, uint64_t expectedNonce); OSStatus decodeTimeStampTokenWithPolicy(SecCmsSignerInfoRef signerinfo, CFTypeRef timeStampPolicy, CSSM_DATA_PTR inData, CSSM_DATA_PTR encDigest, uint64_t expectedNonce); -OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR encDigest, SecAsn1TSAMessageImprint *messageImprint); +OSStatus createTSAMessageImprint(SecCmsSignerInfoRef signerInfo, SECAlgorithmID *digestAlg, + CSSM_DATA_PTR encDigest, SecAsn1TSAMessageImprint *messageImprint); #ifndef NDEBUG int tsaWriteFileX(const char *fileName, const unsigned char *bytes, size_t numBytes); diff --git a/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj b/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj index d8597b00..c0fd98b1 100644 --- a/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj +++ b/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj @@ -416,7 +416,7 @@ 4C2741E803E9FBAF00A80181 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0810; + LastUpgradeCheck = 1000; }; buildConfigurationList = C23B0CD909A298C100B7FCED /* Build configuration list for PBXProject "libsecurity_smime" */; compatibilityVersion = "Xcode 3.2"; @@ -500,12 +500,14 @@ 054049910A3769AC0035F195 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; }; name = Debug; }; 054049950A3769AC0035F195 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; }; name = Release; }; @@ -587,6 +589,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 182BB39F146F1A68000BF1F3 /* debug.xcconfig */; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; }; @@ -596,6 +599,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 182BB3A1146F1A68000BF1F3 /* release.xcconfig */; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; }; @@ -607,12 +611,20 @@ buildSettings = { ASSETCATALOG_COMPRESSION = lossless; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -632,12 +644,20 @@ buildSettings = { ASSETCATALOG_COMPRESSION = "respect-asset-catalog"; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; diff --git a/OSX/libsecurity_ssl/lib/SecureTransport.h b/OSX/libsecurity_ssl/lib/SecureTransport.h index f884dee9..7b4ce804 100644 --- a/OSX/libsecurity_ssl/lib/SecureTransport.h +++ b/OSX/libsecurity_ssl/lib/SecureTransport.h @@ -190,6 +190,18 @@ typedef CF_ENUM(int, SSLClientCertificateState) { kSSLClientCertRejected }; +/* + * Convenience ciphersuite groups that collate ciphersuites of comparable security + * properties into a single alias. + */ +typedef CF_ENUM(int, SSLCiphersuiteGroup) { + kSSLCiphersuiteGroupDefault, + kSSLCiphersuiteGroupCompatibility, + kSSLCiphersuiteGroupLegacy, + kSSLCiphersuiteGroupATS, + kSSLCiphersuiteGroupATSCompatibility, +}; + /* * R/W functions. The application using this library provides * these functions via SSLSetIOFuncs(). diff --git a/OSX/libsecurity_ssl/lib/SecureTransportPriv.h b/OSX/libsecurity_ssl/lib/SecureTransportPriv.h index 4df1cbc3..d7cab1af 100644 --- a/OSX/libsecurity_ssl/lib/SecureTransportPriv.h +++ b/OSX/libsecurity_ssl/lib/SecureTransportPriv.h @@ -37,6 +37,16 @@ extern "C" { #include +/* Return the list of ciphersuites associated with a SSLCiphersuiteGroup */ +const SSLCipherSuite *SSLCiphersuiteGroupToCiphersuiteList(SSLCiphersuiteGroup group, + size_t *listSize); + +/* Determine minimum allowed TLS version for the given ciphersuite */ +SSLProtocol SSLCiphersuiteMinimumTLSVersion(SSLCipherSuite ciphersuite); + +/* Determine maximum allowed TLS version for the given ciphersuite */ +SSLProtocol SSLCiphersuiteMaximumTLSVersion(SSLCipherSuite ciphersuite); + /* Create an SSL Context with an external record layer - eg: kernel accelerated layer */ SSLContextRef SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc, @@ -463,7 +473,7 @@ OSStatus SSLGetDHEEnabled(SSLContextRef ctx, bool *enabled); OSStatus _SSLSetProtocolVersionEnabled (SSLContextRef context, SSLProtocol protocol, - Boolean enable); + Boolean enable) API_UNAVAILABLE(iosmac); /* * Obtain a value specified in SSLSetProtocolVersionEnabled. @@ -473,7 +483,7 @@ _SSLSetProtocolVersionEnabled (SSLContextRef context, OSStatus _SSLGetProtocolVersionEnabled(SSLContextRef context, SSLProtocol protocol, - Boolean *enable); /* RETURNED */ + Boolean *enable) API_UNAVAILABLE(iosmac); /* RETURNED */ /* * Get/set SSL protocol version; optional. Default is kSSLProtocolUnknown, @@ -488,7 +498,7 @@ _SSLGetProtocolVersionEnabled(SSLContextRef context, */ OSStatus _SSLSetProtocolVersion (SSLContextRef context, - SSLProtocol version); + SSLProtocol version) API_UNAVAILABLE(iosmac); /* * Obtain the protocol version specified in SSLSetProtocolVersion. @@ -502,7 +512,7 @@ _SSLSetProtocolVersion (SSLContextRef context, */ OSStatus _SSLGetProtocolVersion (SSLContextRef context, - SSLProtocol *protocol); /* RETURNED */ + SSLProtocol *protocol) API_UNAVAILABLE(iosmac); /* RETURNED */ /* API REVIEW: The following 15 calls were used to change the behaviour of the trust @@ -520,11 +530,11 @@ _SSLGetProtocolVersion (SSLContextRef context, */ OSStatus _SSLSetEnableCertVerify (SSLContextRef context, - Boolean enableVerify); + Boolean enableVerify) API_UNAVAILABLE(iosmac); OSStatus _SSLGetEnableCertVerify (SSLContextRef context, - Boolean *enableVerify); /* RETURNED */ + Boolean *enableVerify) API_UNAVAILABLE(iosmac); /* RETURNED */ /* * Specify the option of ignoring certificates' "expired" times. @@ -534,14 +544,14 @@ _SSLGetEnableCertVerify (SSLContextRef context, */ OSStatus _SSLSetAllowsExpiredCerts (SSLContextRef context, - Boolean allowsExpired); + Boolean allowsExpired) API_UNAVAILABLE(iosmac); /* * Obtain the current value of an SSLContext's "allowExpiredCerts" flag. */ OSStatus _SSLGetAllowsExpiredCerts (SSLContextRef context, - Boolean *allowsExpired); /* RETURNED */ + Boolean *allowsExpired) API_UNAVAILABLE(iosmac); /* RETURNED */ /* * Similar to SSLSetAllowsExpiredCerts(), this function allows the @@ -551,11 +561,11 @@ _SSLGetAllowsExpiredCerts (SSLContextRef context, */ OSStatus _SSLSetAllowsExpiredRoots (SSLContextRef context, - Boolean allowsExpired); + Boolean allowsExpired) API_UNAVAILABLE(iosmac); OSStatus _SSLGetAllowsExpiredRoots (SSLContextRef context, - Boolean *allowsExpired); /* RETURNED */ + Boolean *allowsExpired) API_UNAVAILABLE(iosmac); /* RETURNED */ /* * Specify option of allowing for an unknown root cert, i.e., one which @@ -574,14 +584,14 @@ _SSLGetAllowsExpiredRoots (SSLContextRef context, */ OSStatus _SSLSetAllowsAnyRoot (SSLContextRef context, - Boolean anyRoot); + Boolean anyRoot) API_UNAVAILABLE(iosmac); /* * Obtain the current value of an SSLContext's "allow any root" flag. */ OSStatus _SSLGetAllowsAnyRoot (SSLContextRef context, - Boolean *anyRoot); /* RETURNED */ + Boolean *anyRoot) API_UNAVAILABLE(iosmac); /* RETURNED */ /* * Augment or replace the system's default trusted root certificate set @@ -598,7 +608,7 @@ _SSLGetAllowsAnyRoot (SSLContextRef context, OSStatus _SSLSetTrustedRoots (SSLContextRef context, CFArrayRef trustedRoots, - Boolean replaceExisting); + Boolean replaceExisting) API_UNAVAILABLE(iosmac); /* * Obtain an array of SecCertificateRefs representing the current @@ -609,7 +619,7 @@ _SSLSetTrustedRoots (SSLContextRef context, */ OSStatus _SSLCopyTrustedRoots (SSLContextRef context, - CFArrayRef *trustedRoots); /* RETURNED */ + CFArrayRef *trustedRoots) API_UNAVAILABLE(iosmac); /* RETURNED */ /* * Add a SecCertificateRef, or a CFArray of them, to a server's list @@ -627,7 +637,7 @@ _SSLCopyTrustedRoots (SSLContextRef context, OSStatus _SSLSetCertificateAuthorities(SSLContextRef context, CFTypeRef certificateOrArray, - Boolean replaceExisting); + Boolean replaceExisting) API_UNAVAILABLE(iosmac); /* * Obtain the certificates specified in SSLSetCertificateAuthorities(), @@ -638,7 +648,7 @@ _SSLSetCertificateAuthorities(SSLContextRef context, OSStatus _SSLCopyCertificateAuthorities(SSLContextRef context, - CFArrayRef *certificates); /* RETURNED */ + CFArrayRef *certificates) API_UNAVAILABLE(iosmac); /* RETURNED */ /* * Request peer certificates. Valid anytime, subsequent to @@ -663,7 +673,7 @@ _SSLCopyCertificateAuthorities(SSLContextRef context, */ OSStatus _SSLCopyPeerCertificates (SSLContextRef context, - CFArrayRef *certs); /* RETURNED */ + CFArrayRef *certs) API_UNAVAILABLE(iosmac); /* RETURNED */ /* * Specify Diffie-Hellman parameters. Optional; if we are configured to allow @@ -673,7 +683,7 @@ _SSLCopyPeerCertificates (SSLContextRef context, */ OSStatus _SSLSetDiffieHellmanParams (SSLContextRef context, const void *dhParams, - size_t dhParamsLen); + size_t dhParamsLen) API_UNAVAILABLE(iosmac); /* * Return parameter block specified in SSLSetDiffieHellmanParams. @@ -681,7 +691,7 @@ OSStatus _SSLSetDiffieHellmanParams (SSLContextRef context, */ OSStatus _SSLGetDiffieHellmanParams (SSLContextRef context, const void **dhParams, - size_t *dhParamsLen); + size_t *dhParamsLen) API_UNAVAILABLE(iosmac); /* * Enable/Disable RSA blinding. This feature thwarts a known timing @@ -690,10 +700,10 @@ OSStatus _SSLGetDiffieHellmanParams (SSLContextRef context, * enabled. */ OSStatus _SSLSetRsaBlinding (SSLContextRef context, - Boolean blinding); + Boolean blinding) API_UNAVAILABLE(iosmac); OSStatus _SSLGetRsaBlinding (SSLContextRef context, - Boolean *blinding); + Boolean *blinding) API_UNAVAILABLE(iosmac); /* * Create a new SSL/TLS session context. @@ -701,14 +711,14 @@ OSStatus _SSLGetRsaBlinding (SSLContextRef context, */ OSStatus _SSLNewContext (Boolean isServer, - SSLContextRef *tlsContextPtr); /* RETURNED */ + SSLContextRef *tlsContextPtr) API_UNAVAILABLE(iosmac); /* RETURNED */ /* * Dispose of an SSLContextRef. This is effectivly a CFRelease. * Deprecated. */ OSStatus -_SSLDisposeContext (SSLContextRef context); +_SSLDisposeContext (SSLContextRef context) API_UNAVAILABLE(iosmac); /* We redefine the names of all SPIs to avoid collision with unavailable APIs */ #define SSLSetProtocolVersionEnabled _SSLSetProtocolVersionEnabled @@ -754,7 +764,7 @@ _SSLProtocolVersionToWireFormatValue (SSLProtocol protocol); */ OSStatus SSLNewDatagramContext (Boolean isServer, - SSLContextRef *dtlsContextPtr); /* RETURNED */ + SSLContextRef *dtlsContextPtr) API_UNAVAILABLE(iosmac); /* RETURNED */ diff --git a/OSX/libsecurity_ssl/lib/sslBuildFlags.h b/OSX/libsecurity_ssl/lib/sslBuildFlags.h index 650d0909..fcb19aeb 100644 --- a/OSX/libsecurity_ssl/lib/sslBuildFlags.h +++ b/OSX/libsecurity_ssl/lib/sslBuildFlags.h @@ -84,7 +84,6 @@ extern "C" { #define ENABLE_DTLS 1 #define ENABLE_3DES 1 /* normally enabled */ -#define ENABLE_RC4 1 /* normally enabled */ #define ENABLE_DES 0 /* normally disabled */ #define ENABLE_RC2 0 /* normally disabled */ #define ENABLE_AES 1 /* normally enabled, our first preference */ diff --git a/OSX/libsecurity_ssl/lib/sslCipherSpecs.c b/OSX/libsecurity_ssl/lib/sslCipherSpecs.c index bb59efcf..b898a933 100644 --- a/OSX/libsecurity_ssl/lib/sslCipherSpecs.c +++ b/OSX/libsecurity_ssl/lib/sslCipherSpecs.c @@ -112,15 +112,6 @@ static const uint16_t STKnownCipherSuites[] = { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, -#if ENABLE_RC4 - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS_ECDHE_RSA_WITH_RC4_128_SHA, - TLS_ECDH_ECDSA_WITH_RC4_128_SHA, - TLS_ECDH_RSA_WITH_RC4_128_SHA, - SSL_RSA_WITH_RC4_128_SHA, - SSL_RSA_WITH_RC4_128_MD5, -#endif - /* TLS 1.3 ciphersuites */ #if ENABLE_AES_GCM TLS_AES_128_GCM_SHA256, @@ -144,7 +135,6 @@ static const uint16_t STKnownCipherSuites[] = { TLS_DH_anon_WITH_AES_256_CBC_SHA256, TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_DH_anon_WITH_AES_256_CBC_SHA, - SSL_DH_anon_WITH_RC4_128_MD5, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_NULL_SHA, @@ -159,7 +149,6 @@ static const uint16_t STKnownCipherSuites[] = { TLS_PSK_WITH_AES_128_CBC_SHA256, TLS_PSK_WITH_AES_256_CBC_SHA, TLS_PSK_WITH_AES_128_CBC_SHA, - TLS_PSK_WITH_RC4_128_SHA, TLS_PSK_WITH_3DES_EDE_CBC_SHA, TLS_PSK_WITH_NULL_SHA384, TLS_PSK_WITH_NULL_SHA256, @@ -169,11 +158,220 @@ static const uint16_t STKnownCipherSuites[] = { TLS_RSA_WITH_NULL_SHA256, SSL_RSA_WITH_NULL_SHA, SSL_RSA_WITH_NULL_MD5 - }; static const unsigned STCipherSuiteCount = sizeof(STKnownCipherSuites)/sizeof(STKnownCipherSuites[0]); +#define CiphersuitesTLS13 \ + TLS_AES_128_GCM_SHA256, \ + TLS_AES_256_GCM_SHA384, \ + TLS_CHACHA20_POLY1305_SHA256 + +#define CiphersuitesPFS \ + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, \ + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, \ + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, \ + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, \ + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, \ + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, \ + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, \ + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, \ + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, \ + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, \ + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, \ + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, \ + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, \ + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + +#define CiphersuitesNonPFS \ + TLS_RSA_WITH_AES_256_GCM_SHA384, \ + TLS_RSA_WITH_AES_128_GCM_SHA256, \ + TLS_RSA_WITH_AES_256_CBC_SHA256, \ + TLS_RSA_WITH_AES_128_CBC_SHA256, \ + TLS_RSA_WITH_AES_256_CBC_SHA, \ + TLS_RSA_WITH_AES_128_CBC_SHA + +#define CiphersuitesTLS10 \ + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, \ + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, \ + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, \ + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, \ + TLS_RSA_WITH_AES_256_CBC_SHA, \ + TLS_RSA_WITH_AES_128_CBC_SHA + +#define CiphersuitesTLS10_3DES \ + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, \ + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, \ + SSL_RSA_WITH_3DES_EDE_CBC_SHA + +#define CiphersuitesDHE \ + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, \ + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, \ + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, \ + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, \ + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, \ + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, \ + SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA + + +#define DefineTLSCiphersuiteGroupList(XXX, ...) \ +static const SSLCipherSuite List##XXX[] = { \ + __VA_ARGS__ \ +}; + +DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupDefault, + CiphersuitesTLS13, + CiphersuitesPFS); +DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupCompatibility, + CiphersuitesNonPFS, + CiphersuitesTLS10, + CiphersuitesTLS10_3DES); +DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupLegacy, + CiphersuitesDHE); +DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupATS, + CiphersuitesTLS13, + CiphersuitesPFS); +DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupATSCompatibility, + CiphersuitesNonPFS); + +typedef struct tls_ciphersuite_definition { + SSLCipherSuite ciphersuite; + SSLProtocol min_version; + SSLProtocol max_version; + char ciphersuite_name[64]; +} *tls_ciphersuite_definition_t; + +#define DefineTLSCiphersuiteDefinition(XXX, MIN_VERSION, MAX_VERSION) \ +{ \ + .ciphersuite = XXX, \ + .ciphersuite_name = "##XXX", \ + .min_version = MIN_VERSION, \ + .max_version = MAX_VERSION, \ +} + +static const struct tls_ciphersuite_definition tls_ciphersuite_definitions[] = { + // TLS 1.3 ciphersuites + DefineTLSCiphersuiteDefinition(TLS_AES_128_GCM_SHA256, kTLSProtocol13, kTLSProtocolMaxSupported), + DefineTLSCiphersuiteDefinition(TLS_AES_256_GCM_SHA384, kTLSProtocol13, kTLSProtocolMaxSupported), + DefineTLSCiphersuiteDefinition(TLS_CHACHA20_POLY1305_SHA256, kTLSProtocol13, kTLSProtocolMaxSupported), + + // RFC 7905: ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS) + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, kTLSProtocol12, kTLSProtocol12), + + // RFC 5289: TLS Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM) + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, kTLSProtocol12, kTLSProtocol12), + + // RFC 5288: AES Galois Counter Mode (GCM) Cipher Suites for TLS + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_GCM_SHA384, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_GCM_SHA256, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, kTLSProtocol12, kTLSProtocol12), + + // RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA256, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA256, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(SSL_RSA_WITH_3DES_EDE_CBC_SHA, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, kTLSProtocol12, kTLSProtocol12), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, kTLSProtocol12, kTLSProtocol12), + + // RFC 4492: Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS) + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + + // RFC 3268: Advanced Encryption Standard (AES) Ciphersuites for Transport Layer Security (TLS) + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11), +}; + +// Size of the definition list +static const size_t tls_ciphersuite_definitions_length = \ + sizeof(tls_ciphersuite_definitions) / sizeof(struct tls_ciphersuite_definition); + +// Remove macro definitions +#undef CiphersuitesTLS13 +#undef CiphersuitesPFS +#undef CiphersuitesNonPFS +#undef CiphersuitesTLS10_3DES +#undef CiphersuitesTLS10 +#undef CiphersuitesDHE +#undef DefineTLSCiphersuiteGroupList +#undef DefineTLSCiphersuiteDefinition + +const SSLCipherSuite * +SSLCiphersuiteGroupToCiphersuiteList(SSLCiphersuiteGroup group, size_t *listSize) +{ + if (listSize == NULL) { + return NULL; + } + + const SSLCipherSuite *ciphersuites = NULL; + size_t count = 0; + +#define CASE_CONFIG(GROUPNAME) \ + case GROUPNAME: \ + ciphersuites = List##GROUPNAME; \ + count = sizeof(List##GROUPNAME) / sizeof(SSLCipherSuite); \ + break; + + switch (group) { + CASE_CONFIG(kSSLCiphersuiteGroupDefault); + CASE_CONFIG(kSSLCiphersuiteGroupCompatibility); + CASE_CONFIG(kSSLCiphersuiteGroupLegacy); + CASE_CONFIG(kSSLCiphersuiteGroupATS); + CASE_CONFIG(kSSLCiphersuiteGroupATSCompatibility); + } + +#undef CASE_CONFIG + + if (ciphersuites != NULL) { + *listSize = count; + return ciphersuites; + } + + *listSize = 0; + return NULL; +} + +SSLProtocol +SSLCiphersuiteMinimumTLSVersion(SSLCipherSuite ciphersuite) +{ + for (size_t i = 0; i < tls_ciphersuite_definitions_length; i++) { + if (tls_ciphersuite_definitions[i].ciphersuite == ciphersuite) { + return tls_ciphersuite_definitions[i].min_version; + } + } + return kSSLProtocolUnknown; +} + +SSLProtocol +SSLCiphersuiteMaximumTLSVersion(SSLCipherSuite ciphersuite) +{ + for (size_t i = 0; i < tls_ciphersuite_definitions_length; i++) { + if (tls_ciphersuite_definitions[i].ciphersuite == ciphersuite) { + return tls_ciphersuite_definitions[i].max_version; + } + } + return kSSLProtocolUnknown; +} /* * Convert an array of uint16_t diff --git a/OSX/libsecurity_ssl/lib/sslContext.c b/OSX/libsecurity_ssl/lib/sslContext.c index eed80f1b..a0b80866 100644 --- a/OSX/libsecurity_ssl/lib/sslContext.c +++ b/OSX/libsecurity_ssl/lib/sslContext.c @@ -1195,12 +1195,12 @@ SSLSetProtocolVersionMax (SSLContextRef ctx, if (version > MINIMUM_DATAGRAM_VERSION || version < MAXIMUM_DATAGRAM_VERSION) return errSSLIllegalParam; - if (version > ctx->minProtocolVersion) + if (version > (SSLProtocolVersion)ctx->minProtocolVersion) ctx->minProtocolVersion = version; } else { if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) return errSSLIllegalParam; - if (version < ctx->minProtocolVersion) + if (version < (SSLProtocolVersion)ctx->minProtocolVersion) ctx->minProtocolVersion = version; } ctx->maxProtocolVersion = version; @@ -1289,12 +1289,12 @@ SSLSetProtocolVersionEnabled(SSLContextRef ctx, if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) { return errSecParam; } - if (version > ctx->maxProtocolVersion) { + if (version > (SSLProtocolVersion)ctx->maxProtocolVersion) { ctx->maxProtocolVersion = version; if (ctx->minProtocolVersion == SSL_Version_Undetermined) ctx->minProtocolVersion = version; } - if (version < ctx->minProtocolVersion) { + if (version < (SSLProtocolVersion)ctx->minProtocolVersion) { ctx->minProtocolVersion = version; } } else { @@ -1324,7 +1324,7 @@ SSLSetProtocolVersionEnabled(SSLContextRef ctx, nextVersion = SSL_Version_Undetermined; break; } - ctx->minProtocolVersion = max(ctx->minProtocolVersion, nextVersion); + ctx->minProtocolVersion = (tls_protocol_version)max((SSLProtocolVersion)ctx->minProtocolVersion, nextVersion); if (ctx->minProtocolVersion > ctx->maxProtocolVersion) { ctx->minProtocolVersion = SSL_Version_Undetermined; ctx->maxProtocolVersion = SSL_Version_Undetermined; @@ -1358,8 +1358,8 @@ SSLGetProtocolVersionEnabled(SSLContextRef ctx, case kTLSProtocol12: { SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol); - *enable = (ctx->minProtocolVersion <= version - && ctx->maxProtocolVersion >= version); + *enable = ((SSLProtocolVersion)ctx->minProtocolVersion <= version + && (SSLProtocolVersion)ctx->maxProtocolVersion >= version); break; } case kSSLProtocolAll: diff --git a/OSX/libsecurity_ssl/lib/sslCrypto.c b/OSX/libsecurity_ssl/lib/sslCrypto.c index 166a105b..60362e4a 100644 --- a/OSX/libsecurity_ssl/lib/sslCrypto.c +++ b/OSX/libsecurity_ssl/lib/sslCrypto.c @@ -53,11 +53,7 @@ */ CFIndex sslPubKeyGetAlgorithmID(SecKeyRef pubKey) { -#if TARGET_OS_IPHONE - return SecKeyGetAlgorithmID(pubKey); -#else return SecKeyGetAlgorithmId(pubKey); -#endif } /* @@ -65,11 +61,7 @@ CFIndex sslPubKeyGetAlgorithmID(SecKeyRef pubKey) */ CFIndex sslPrivKeyGetAlgorithmID(SecKeyRef privKey) { -#if TARGET_OS_IPHONE - return SecKeyGetAlgorithmID(privKey); -#else return SecKeyGetAlgorithmId(privKey); -#endif } diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/Info.plist b/OSX/libsecurity_ssl/regressions/SecureTransportTests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+ciphers.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+ciphers.m new file mode 100644 index 00000000..aeb66843 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+ciphers.m @@ -0,0 +1,685 @@ +#include +#import "STLegacyTests.h" +#include +#include +#include +#include +#include + +#include + +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#include "ssl-utils.h" + +/* + SSL CipherSuite tests +*/ +@implementation STLegacyTests (ciphers) + +static const SSLCipherSuite SupportedCipherSuites[] = { + + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + + TLS_RSA_WITH_AES_256_GCM_SHA384, + TLS_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + SSL_RSA_WITH_3DES_EDE_CBC_SHA, + + /* Unsafe ciphersuites */ + + TLS_DH_anon_WITH_AES_256_GCM_SHA384, + TLS_DH_anon_WITH_AES_128_GCM_SHA256, + TLS_DH_anon_WITH_AES_128_CBC_SHA256, + TLS_DH_anon_WITH_AES_256_CBC_SHA256, + TLS_DH_anon_WITH_AES_128_CBC_SHA, + TLS_DH_anon_WITH_AES_256_CBC_SHA, + SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, + + TLS_ECDH_anon_WITH_NULL_SHA, + TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_anon_WITH_AES_128_CBC_SHA, + TLS_ECDH_anon_WITH_AES_256_CBC_SHA, + + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, + + TLS_PSK_WITH_AES_256_CBC_SHA384, + TLS_PSK_WITH_AES_128_CBC_SHA256, + TLS_PSK_WITH_AES_256_CBC_SHA, + TLS_PSK_WITH_AES_128_CBC_SHA, + TLS_PSK_WITH_3DES_EDE_CBC_SHA, + TLS_PSK_WITH_NULL_SHA384, + TLS_PSK_WITH_NULL_SHA256, + TLS_PSK_WITH_NULL_SHA, + + TLS_RSA_WITH_NULL_SHA256, + SSL_RSA_WITH_NULL_SHA, + SSL_RSA_WITH_NULL_MD5 + +}; + +static const unsigned SupportedCipherSuitesCount = sizeof(SupportedCipherSuites)/sizeof(SupportedCipherSuites[0]); + + +static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12, kDTLSProtocol1 }; +static int nprotos = sizeof(protos)/sizeof(protos[0]); + + +static unsigned char dh_param_1024_bytes[] = { + 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0xf2, 0x56, 0xb9, 0x41, 0x74, + 0x8c, 0x54, 0x22, 0xad, 0x94, 0x2b, 0xed, 0x83, 0xb9, 0xa0, 0x2f, 0x40, + 0xce, 0xf8, 0xec, 0x96, 0xed, 0xcd, 0x8e, 0xfc, 0xf8, 0xdd, 0x06, 0x15, + 0xbc, 0x68, 0x0d, 0x0e, 0x2c, 0xef, 0x00, 0x71, 0x28, 0x3d, 0x27, 0x6d, + 0x5e, 0x42, 0x8c, 0xbd, 0x0f, 0x07, 0x23, 0x9d, 0x07, 0x8e, 0x52, 0x47, + 0xa2, 0x5d, 0xf8, 0xd9, 0x9a, 0x7b, 0xb4, 0xab, 0xd2, 0xa3, 0x39, 0xe9, + 0x2c, 0x3b, 0x9b, 0xaa, 0xbe, 0x4e, 0x01, 0x36, 0x16, 0xc2, 0x9e, 0x7b, + 0x38, 0x78, 0x82, 0xd0, 0xed, 0x8e, 0x1e, 0xce, 0xa6, 0x23, 0x95, 0xae, + 0x31, 0x66, 0x58, 0x60, 0x44, 0xdf, 0x1f, 0x9c, 0x68, 0xbf, 0x8b, 0xf1, + 0xb4, 0xa8, 0xe7, 0xb2, 0x43, 0x8b, 0xa9, 0x3d, 0xa1, 0xb7, 0x1a, 0x11, + 0xcf, 0xf4, 0x5e, 0xf7, 0x08, 0xf6, 0x84, 0x1c, 0xd7, 0xfa, 0x40, 0x10, + 0xdc, 0x64, 0x83, 0x02, 0x01, 0x02 +}; +static unsigned char *dh_param_der = dh_param_1024_bytes; +static unsigned int dh_param_der_len = sizeof(dh_param_1024_bytes); + + +typedef struct { + uint32_t session_id; + bool is_session_resume; + SSLContextRef st; + bool is_server; + bool is_dtls; + SSLAuthenticate client_side_auth; + bool dh_anonymous; + int comm; + CFArrayRef certs; + CFArrayRef peer_certs; + SSLProtocol proto; + uint64_t time; // output +} ssl_test_handle; + +#if 0 // currently unused +static CFArrayRef SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity) +{ + CFMutableArrayRef chain = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + SecTrustResultType trust_result; + + do { + policy = SecPolicyCreateSSL(false, NULL); + if (!policy) + break; + + SecCertificateRef cert = NULL; + if (SecIdentityCopyCertificate(identity, &cert)) + break; + + CFArrayRef certs = CFArrayCreate(NULL, (const void **)&cert, + 1, &kCFTypeArrayCallBacks); + CFRelease(cert); + if (!certs) + break; + + if (SecTrustCreateWithCertificates(certs, policy, &trust)) + break; + CFRelease(certs); + CFRelease(policy); + if (SecTrustEvaluate(trust, &trust_result)) + break; + + int i, count = SecTrustGetCertificateCount(trust); + chain = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); + CFArrayAppendValue(chain, identity); + for (i = 1; i < count; i++) { + if ((i+1 == count) && (trust_result == kSecTrustResultUnspecified)) + continue; /* skip anchor if chain is complete */ + SecCertificateRef s = SecTrustGetCertificateAtIndex(trust, i); + CFArrayAppendValue(chain, s); + } + } while (0); + if (trust) + CFRelease(trust); + if (policy) + CFRelease(policy); + return chain; +} +#endif // currently unused + +// MARK: - +// MARK: SecureTransport support + +#if 0 +static void hexdump(const uint8_t *bytes, size_t len) { + size_t ix; + printf("socket write(%p, %lu)\n", bytes, len); + for (ix = 0; ix < len; ++ix) { + if (!(ix % 16)) + printf("\n"); + printf("%02X ", bytes[ix]); + } + printf("\n"); +} +#else +#define hexdump(bytes, len) +#endif + +static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + hexdump(ptr, len); + ret = write((int)conn, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = read((int)conn, ptr, len); + } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } else { + printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno); + return -errno; + } + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static unsigned char dn[] = { + 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74 +}; +static unsigned int dn_len = 96; + +static SSLContextRef make_ssl_ref(bool server, SSLAuthenticate client_side_auth, bool dh_anonymous, + bool dtls, int sock, CFArrayRef certs, SSLProtocol proto) +{ + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType); + require(ctx, out); + + if(dtls) { + size_t mtu; + require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out); + require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out); + } + require_noerr(SSLSetProtocolVersionMax(ctx, proto), out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out); + static const char *peer_domain_name = "localhost"; + require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name, + strlen(peer_domain_name)), out); + + require_noerr(SSLSetMinimumDHGroupSize(ctx, 512), out); + + if (!dh_anonymous) { + if (server) + require_noerr(SSLSetCertificate(ctx, certs), out); + if ((client_side_auth != kNeverAuthenticate) && server) { + SSLAuthenticate auth; + require_noerr(SSLSetClientSideAuthenticate(ctx, client_side_auth), out); + require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out); + require(auth==client_side_auth, out); + require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out); + } +#if 0 /* Setting client certificate in advance */ + if ((client_side_auth == kAlwaysAuthenticate) && !server) + require_noerr(SSLSetCertificate(ctx, certs), out); +#endif + if ((client_side_auth != kNeverAuthenticate) && !server) /* enable break from SSLHandshake */ + require_noerr(SSLSetSessionOption(ctx, + kSSLSessionOptionBreakOnCertRequested, true), out); + } + + /* Set this option, even if doing anonDH or PSK - it should NOT break out in those case */ + require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true), out); + + /* Tell SecureTransport to not check certs itself: it will break out of the + handshake to let us take care of it instead. */ + require_noerr(SSLSetEnableCertVerify(ctx, false), out); + + if (server) { + require_noerr(SSLSetDiffieHellmanParams(ctx, + dh_param_der, dh_param_der_len), out); + } + else /* if client */ { + } + + return ctx; +out: + if (ctx) + CFRelease(ctx); + return NULL; +} + +static bool check_peer_cert(SSLContextRef ctx, const ssl_test_handle *ssl, SecTrustRef *trust) +{ + CFMutableArrayRef peer_cert_array = NULL; + CFMutableArrayRef orig_peer_cert_array = NULL; + + /* verify peer cert chain */ + require_noerr(SSLCopyPeerTrust(ctx, trust), out); + SecTrustResultType trust_result = 0; + /* this won't verify without setting up a trusted anchor */ + require_noerr(SecTrustEvaluate(*trust, &trust_result), out); + + CFIndex n_certs = SecTrustGetCertificateCount(*trust); + + peer_cert_array = CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks); + orig_peer_cert_array = CFArrayCreateMutableCopy(NULL, n_certs, ssl->peer_certs); + while (n_certs--) + CFArrayInsertValueAtIndex(peer_cert_array, 0, + SecTrustGetCertificateAtIndex(*trust, n_certs)); + + SecIdentityRef ident = + (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0); + SecCertificateRef peer_cert = NULL; + require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out); + CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert); + CFRelease(peer_cert); + + require(CFEqual(orig_peer_cert_array, peer_cert_array), out); + CFReleaseNull(orig_peer_cert_array); + CFReleaseNull(peer_cert_array); + + return true; +out: + CFReleaseNull(orig_peer_cert_array); + CFReleaseNull(peer_cert_array); + return false; +} + + +#include + +#define perf_start() uint64_t _perf_time = mach_absolute_time(); +#define perf_scale_factor() ({struct mach_timebase_info info; mach_timebase_info(&info); ((double)info.numer) / (1000000.0 * info.denom);}) +#define perf_time() ((mach_absolute_time() - _perf_time) * perf_scale_factor()) + + +static void *securetransport_ssl_thread(void *arg) +{ + OSStatus ortn; + ssl_test_handle * ssl = (ssl_test_handle *)arg; + SSLContextRef ctx = ssl->st; + SecTrustRef trust = NULL; + bool got_server_auth = false, got_client_cert_req = false; + SSLSessionState ssl_state; + + perf_start(); + + pthread_setname_np(ssl->is_server?"server thread":"client thread"); + + require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); + require_action(ssl_state==kSSLIdle, out, ortn = -1); + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLPeerAuthCompleted) + { + require_action(ssl_state==kSSLHandshake, out, ortn = -1); + require_string(!got_server_auth, out, "second server auth"); + require_string(!ssl->dh_anonymous, out, "server auth with anon cipher"); + // Note: Previously, the implementation always returned errSSLPeerAuthCompleted before + // errSSLClientCertRequested. Due to OCSP stappling implementation, this is no longer guaranteed. + // This behavior change should not be an issue, but it's possible that some applications will + // have issue with this new behavior. If we do find out that this is causing an issue, then + // the following require statement should be re-enabled, and the implementation changed + // to implement the former behavior. + //require_string(!got_client_cert_req, out, "got client cert req before server auth"); + got_server_auth = true; + require_string(!trust, out, "Got errSSLServerAuthCompleted twice?"); + require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed"); + } else if (ortn == errSSLClientCertRequested) { + require_action(ssl_state==kSSLHandshake, out, ortn = -1); + require_string(!got_client_cert_req, out, "second client cert req"); + // Note: see Note above. + //require_string(got_server_auth, out, "didn't get server auth first"); + got_client_cert_req = true; + + /* set client cert */ + require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server"); + require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH"); + + CFArrayRef DNs = NULL; + require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out); + require(DNs, out); + CFRelease(DNs); + + require_string(ssl->client_side_auth != kNeverAuthenticate, out, "errSSLClientCertRequested in run not testing that"); + if(ssl->client_side_auth == kAlwaysAuthenticate) { // Only set a client cert in mode 1. + require_noerr(SSLSetCertificate(ctx, ssl->certs), out); + } + } else if (ortn == errSSLWouldBlock) { + require_action(ssl_state==kSSLHandshake, out, ortn = -1); + } + } while (ortn == errSSLWouldBlock + || ortn == errSSLServerAuthCompleted + || ortn == errSSLClientCertRequested); + require_noerr_action_quiet(ortn, out, + fprintf(stderr, "Fell out of SSLHandshake with error: %d (%s)\n", (int)ortn, ssl->is_server?"server":"client")); + + require_action(ssl_state==kSSLConnected, out, ortn = -1); + + if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) { + require_string(got_server_auth, out, "never got server auth"); + if (ssl->client_side_auth != kNeverAuthenticate) + require_string(got_client_cert_req, out, "never got client cert req"); + } + + if (!ssl->is_server && !ssl->dh_anonymous && ssl->is_session_resume) { + require_string(!got_server_auth, out, "got server auth during resumption??"); + require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed (resumption case)"); + } + + SSLCipherSuite cipherSuite; + require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out); + + if(ssl->is_dtls) { + size_t sz; + SSLGetDatagramWriteSize(ctx, &sz); + } + + Boolean sessionWasResumed = false; + uint8_t session_id_data[MAX_SESSION_ID_LENGTH]; + size_t session_id_length = sizeof(session_id_data); + require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out); + require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1); + +#define BUFSIZE (8*1024) + unsigned char ibuf[BUFSIZE], obuf[BUFSIZE]; + + for(int i=0; i<10; i++) { + size_t len; + if (ssl->is_server) { + memset(obuf, i, BUFSIZE); + require_noerr(ortn = SSLWrite(ctx, obuf, BUFSIZE, &len), out); + require_action(len == BUFSIZE, out, ortn = -1); + + require_noerr(ortn = SSLWrite(ctx, obuf, 0, &len), out); + require_action(len == 0, out, ortn = -1); + } + + len=0; + while(lenis_server) { + require_noerr(memcmp(ibuf, obuf, BUFSIZE), out); + } else { + require_noerr(ortn = SSLWrite(ctx, ibuf, BUFSIZE, &len), out); + require_action(len == BUFSIZE, out, ortn = -1); + } + } + +out: + SSLClose(ctx); + CFRelease(ctx); + if (trust) CFRelease(trust); + close(ssl->comm); + + ssl->time = perf_time(); + + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + + +static ssl_test_handle * +ssl_test_handle_create(uint32_t session_id, bool resume, bool server, SSLAuthenticate client_side_auth, bool dh_anonymous, bool dtls, + int comm, CFArrayRef certs, CFArrayRef peer_certs, SSLProtocol proto) +{ + ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle)); + if (handle) { + handle->session_id = session_id; + handle->is_session_resume = resume; + handle->is_server = server; + handle->is_dtls = dtls; + handle->client_side_auth = client_side_auth; + handle->dh_anonymous = dh_anonymous; + handle->comm = comm; + handle->certs = certs; + handle->peer_certs = peer_certs; + handle->proto = proto; + handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto); + } + return handle; +} + +-(void)testCiphers +{ + pthread_t client_thread, server_thread; + + CFArrayRef server_rsa_certs = server_chain(); + CFArrayRef server_ec_certs = server_ec_chain(); + CFArrayRef client_certs = trusted_client_chain(); + XCTAssert(server_rsa_certs != NULL); + XCTAssert(server_ec_certs != NULL); + XCTAssert(client_certs != NULL); + + int i,k,l, p; + + for (p=0; pst, &session_id, sizeof(session_id))); + XCTAssertEqual(errSecSuccess, SSLSetPeerID(client->st, &session_id, sizeof(session_id))); + + /* set single cipher on client, default ciphers on server */ + num_supported_ciphers = 0; + XCTAssertEqual(errSecSuccess, SSLSetEnabledCiphers(client->st, &(SupportedCipherSuites[i]), 1)); + XCTAssertEqual(errSecSuccess, SSLGetNumberSupportedCiphers(server->st, &num_supported_ciphers)); + XCTAssert(supported_ciphers=malloc(num_supported_ciphers*sizeof(SSLCipherSuite))); + XCTAssertEqual(errSecSuccess, SSLGetSupportedCiphers(server->st, supported_ciphers, &num_supported_ciphers)); + XCTAssertEqual(errSecSuccess, SSLSetEnabledCiphers(server->st, supported_ciphers, num_supported_ciphers)); + + XCTAssertEqual(errSecSuccess, SSLSetPSKSharedSecret(client->st, "123456789", 9)); + XCTAssertEqual(errSecSuccess, SSLSetPSKSharedSecret(server->st, "123456789", 9)); + + pthread_create(&client_thread, NULL, securetransport_ssl_thread, client); + pthread_create(&server_thread, NULL, securetransport_ssl_thread, server); + + intptr_t server_err, client_err; + pthread_join(client_thread, (void*)&client_err); + pthread_join(server_thread, (void*)&server_err); + +#if 0 + // If you want to print an approximate time for each handshake. + printf("%4llu - %40s CSA:%d RESUME:%d PROTO:0x%04x\n", + client->time, + ciphersuite_name(SupportedCipherSuites[i]), + server->client_side_auth, + l, protos[p]); +#endif + + XCTAssert(!server_err && !client_err, + "%40s CSA:%d RESUME:%d PROTO:0x%04x", + ciphersuite_name(SupportedCipherSuites[i]), + server->client_side_auth, + l, protos[p]); +out: + free(client); + free(server); + free(supported_ciphers); + } + } /* all ciphers */ + } /* all configs */ + + +end: + CFReleaseSafe(client_certs); + CFReleaseSafe(server_ec_certs); + CFReleaseSafe(server_rsa_certs); +} + +@end + +/* +TODO: count errSSLWouldBlock +TODO: skip tests that don't matter: client_auth and anonymous dh +TODO: we seem to only be negotiating tls - force a round of sslv3 +TODO: allow secure transport to also defer client side auth to client +TODO: make sure anonymous dh is never selected if not expicitly enabled +TODO: make sure DHE is not available if not explicitly enabled and no parameters + are set +TODO: resumable sessions +*/ diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth.m new file mode 100644 index 00000000..efaf9780 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth.m @@ -0,0 +1,407 @@ + +#include +#include +#include +#include +#include + +#include + +#include +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#include "ssl-utils.h" +#import "STLegacyTests.h" + +@implementation STLegacyTests (clientauth) + +/* + SSL Client Auth tests: + + Test both the client and server side. + + Server side test goals: + Verify Server behavior in the following cases: + Server configuration: + - when using kTryAuthenticate vs kAlwaysAuthenticate + - with or without breakOnClientAuth. + - AnonDH and PSK ciphersuites. + Client configuration: + - Client sends back no cert vs a cert. + - Client sends back an unsupported cert. + - Client sends back a malformed cert. + - Client cert is trusted vs untrusted. + - Client does not have private key (ie: Certificate Verify message should fail). + Behavior to verify: + - handshake pass or fail + - SSLGetClientCertificateState returns expected results + + Client side test goals: + Client configuration: + - with or without breakOnCertRequest. + - no cert, vs cert. + Server config: + - No client cert requested, vs client cert requested vs client cert required. + Behavior to verify: + - handshake pass or fail + - SSLGetClientCertificateState returns expected results + +*/ + + +static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = write((int)conn, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = read((int)conn, ptr, len); + } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } else { + printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno); + return -errno; + } + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +typedef struct { + SSLContextRef st; + int comm; + bool break_on_req; + CFArrayRef certs; + int auth; //expected client auth behavior of the server (0=no request, 1=optional , 2=required) +} ssl_client_handle; + +static ssl_client_handle * +ssl_client_handle_create(bool break_on_req, int comm, CFArrayRef certs, CFArrayRef trustedCA, int auth) +{ + ssl_client_handle *handle = calloc(1, sizeof(ssl_client_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType); + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + static const char *peer_domain_name = "localhost"; + require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name, + strlen(peer_domain_name)), out); + + require_noerr(SSLSetTrustedRoots(ctx, trustedCA, true), out); + + + /* Setting client certificate in advance */ + if (!break_on_req && certs) { + require_noerr(SSLSetCertificate(ctx, certs), out); + } + + if (break_on_req) { + require_noerr(SSLSetSessionOption(ctx, + kSSLSessionOptionBreakOnCertRequested, true), out); + } + + handle->break_on_req = break_on_req; + handle->comm = comm; + handle->certs = certs; + handle->st = ctx; + handle->auth = auth; + + return handle; + +out: + if (ctx) + CFRelease(ctx); + if (handle) + free(handle); + + return NULL; +} + +static void +ssl_client_handle_destroy(ssl_client_handle *handle) +{ + if(handle) { + SSLClose(handle->st); + CFRelease(handle->st); + free(handle); + } +} + +static void *securetransport_ssl_client_thread(void *arg) +{ + OSStatus ortn; + ssl_client_handle * ssl = (ssl_client_handle *)arg; + SSLContextRef ctx = ssl->st; + bool got_client_cert_req = false; + SSLSessionState ssl_state; + + pthread_setname_np("client thread"); + + require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); + require_action(ssl_state==kSSLIdle, out, ortn = -1); + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLClientCertRequested) { + require_string(ssl->auth, out, "cert req not expected"); + require_string(ssl_state==kSSLHandshake, out, "wrong client handshake state after errSSLClientCertRequested"); + require_string(!got_client_cert_req, out, "second client cert req"); + got_client_cert_req = true; + + SSLClientCertificateState clientState; + SSLGetClientCertificateState(ctx, &clientState); + require_string(clientState==kSSLClientCertRequested, out, "Wrong client cert state after cert request"); + + require_string(ssl->break_on_req, out, "errSSLClientCertRequested in run not testing that"); + if(ssl->certs) { + require_noerr(SSLSetCertificate(ctx, ssl->certs), out); + } + + } else if (ortn == errSSLWouldBlock) { + require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock"); + } + } while (ortn == errSSLWouldBlock || ortn == errSSLClientCertRequested); + + require_string((got_client_cert_req || !ssl->auth || !ssl->break_on_req), out, "didn't get client cert req as expected"); + + +out: + SSLClose(ssl->st); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + +typedef struct { + SSLContextRef st; + int comm; + SSLAuthenticate client_auth; + CFArrayRef certs; +} ssl_server_handle; + +static ssl_server_handle * +ssl_server_handle_create(SSLAuthenticate client_auth, int comm, CFArrayRef certs, CFArrayRef trustedCA) +{ + ssl_server_handle *handle = calloc(1, sizeof(ssl_server_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType); + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + + require_noerr(SSLSetCertificate(ctx, certs), out); + + require_noerr(SSLSetTrustedRoots(ctx, trustedCA, true), out); + + SSLAuthenticate auth; + require_noerr(SSLSetClientSideAuthenticate(ctx, client_auth), out); + require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out); + require(auth==client_auth, out); + + handle->client_auth = client_auth; + handle->comm = comm; + handle->certs = certs; + handle->st = ctx; + + return handle; + +out: + if (ctx) + CFRelease(ctx); + if (handle) + free(handle); + + return NULL; +} + +static void +ssl_server_handle_destroy(ssl_server_handle *handle) +{ + if(handle) { + SSLClose(handle->st); + CFRelease(handle->st); + free(handle); + } +} + +static void *securetransport_ssl_server_thread(void *arg) +{ + OSStatus ortn; + ssl_server_handle * ssl = (ssl_server_handle *)arg; + SSLContextRef ctx = ssl->st; + SSLSessionState ssl_state; + + pthread_setname_np("server thread"); + + require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); + require_action(ssl_state==kSSLIdle, out, ortn = -1); + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLWouldBlock) { + require_action(ssl_state==kSSLHandshake, out, ortn = -1); + } + } while (ortn == errSSLWouldBlock); + + require_noerr_quiet(ortn, out); + + require_action(ssl_state==kSSLConnected, out, ortn = -1); + +out: + SSLClose(ssl->st); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + + +-(void)testClientAuth +{ + pthread_t client_thread, server_thread; + CFArrayRef server_certs = server_chain(); + CFArrayRef trusted_ca = trusted_roots(); + + XCTAssert(server_certs, "got server certs"); + XCTAssert(trusted_ca, "got trusted roots"); + + int i, j, k; + + for (i=0; i<3; i++) {/* client side cert: 0 = no cert, 1 = trusted cert, 2 = untrusted cert. */ + for (j=0; j<2; j++) { /* break on cert request */ + for (k=0; k<3; k++) { /* server behvior: 0 = no cert request, 1 = optional cert, 2 = required cert */ + + int sp[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno); + fcntl(sp[0], F_SETNOSIGPIPE, 1); + fcntl(sp[1], F_SETNOSIGPIPE, 1); + + bool break_on_req = (j!=0); + SSLClientAuthenticationType auth = (k == 0) ? kNeverAuthenticate + : (k == 1) ? kTryAuthenticate + : kAlwaysAuthenticate; + + CFArrayRef client_certs = (i == 0) ? NULL + : (i == 1) ? trusted_client_chain() + : untrusted_client_chain(); + + ssl_client_handle *client; + client = ssl_client_handle_create(break_on_req, sp[0], client_certs, trusted_ca, auth); + + ssl_server_handle *server; + server = ssl_server_handle_create(auth, sp[1], server_certs, trusted_ca); + + pthread_create(&client_thread, NULL, securetransport_ssl_client_thread, client); + pthread_create(&server_thread, NULL, securetransport_ssl_server_thread, server); + + intptr_t server_err, client_err; + int expected_server_err = 0, expected_client_err = 0; + SSLClientCertificateState client_cauth_state, server_cauth_state; + SSLClientCertificateState expected_client_cauth_state = 0, expected_server_cauth_state = 0; + + + if(((k == 2) && (i != 1)) // Server requires good cert, but client not sending good cert, + || ((k == 1) && (i == 2)) // Or server request optionally, and client sending bad cert. + ) { + expected_client_err = errSSLPeerCertUnknown; + expected_server_err = errSSLXCertChainInvalid; + } + + + if(k != 0) { + if(i == 0) { + expected_client_cauth_state = kSSLClientCertRequested; + expected_server_cauth_state = kSSLClientCertRequested; + } else { + expected_client_cauth_state = kSSLClientCertSent; + expected_server_cauth_state = kSSLClientCertSent; + } + } + + pthread_join(client_thread, (void*)&client_err); + pthread_join(server_thread, (void*)&server_err); + + + XCTAssertEqual(errSecSuccess, SSLGetClientCertificateState(client->st, &client_cauth_state), "SSLGetClientCertificateState (client %d:%d:%d)", i, j, k); + XCTAssertEqual(errSecSuccess, SSLGetClientCertificateState(client->st, &server_cauth_state), "SSLGetClientCertificateState (server %d:%d:%d)", i, j, k); + + XCTAssertEqual(client_err, expected_client_err, "unexpected error %d!=%d (client %d:%d:%d)", (int)client_err, expected_client_err, i, j, k); + XCTAssertEqual(server_err, expected_server_err, "unexpected error %d!=%d (server %d:%d:%d)", (int)server_err, expected_server_err, i, j, k); + + XCTAssertEqual(client_cauth_state, expected_client_cauth_state, "unexpected client auth state %d!=%d (client %d:%d:%d)", client_cauth_state, expected_client_cauth_state, i, j, k); + XCTAssertEqual(server_cauth_state, expected_server_cauth_state, "unexpected client auth state %d!=%d (server %d:%d:%d)", server_cauth_state, expected_server_cauth_state, i, j, k); + + + ssl_server_handle_destroy(server); + ssl_client_handle_destroy(client); + + CFReleaseSafe(client_certs); + } + } + } + + CFReleaseSafe(server_certs); + CFReleaseSafe(trusted_ca); +} + +@end diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth41.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth41.m new file mode 100644 index 00000000..5cf1ce6b --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth41.m @@ -0,0 +1,375 @@ +/* + * ssl-40-clientauth.c + * Security + * + * Copyright (c) 2008-2010,2012-2014 Apple Inc. All Rights Reserved. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#import "STLegacyTests.h" + +@implementation STLegacyTests (clientauth41) + +#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) { CFRelease(_cf); } } +#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) { (CF) = NULL; CFRelease(_cf); } } + +/* + Bag Attributes +friendlyName: uranusLeaf +localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23 +subject=/CN=uranusLeaf/emailAddress=uranus@uranus.com +issuer=/CN=plutoCA/emailAddress=pluto@pluto.com + */ +static const uint8_t _c1[] = { + 0x30, 0x82, 0x02, 0xe0, 0x30, 0x82, 0x01, 0xc8, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, + 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x30, 0x32, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43, + 0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x0c, 0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40, + 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31, + 0x32, 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, + 0x35, 0x5a, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32, + 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, 0x35, + 0x5a, 0x30, 0x37, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x75, 0x72, + 0x61, 0x6e, 0x75, 0x73, 0x4c, 0x65, 0x61, 0x66, + 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c, + 0x11, 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x40, + 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 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, 0xa6, 0x82, 0x8e, 0xc6, 0x7e, + 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, 0x35, + 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, 0xa8, + 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, 0x80, + 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, 0x93, + 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, 0xd7, + 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, 0xfb, + 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, 0xac, + 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, 0x2a, + 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, 0xc3, + 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, 0x78, + 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, 0x9b, + 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, 0xf6, + 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, 0xe7, + 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, 0xdc, + 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, 0xaa, + 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, 0xe2, + 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, 0x4f, + 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, 0x04, + 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, 0xb2, + 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, 0x71, + 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, 0x44, + 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, 0x48, + 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, 0x4b, + 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, 0x47, + 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, 0x08, + 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, 0x32, + 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, 0x26, + 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, 0x23, + 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, 0xd4, + 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, 0x9e, + 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, 0xf8, + 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x17, 0xa5, 0x22, 0xed, + 0xb8, 0x3e, 0x1f, 0x11, 0x99, 0xc5, 0xba, 0x28, + 0x3e, 0x7e, 0xa6, 0xeb, 0x02, 0x81, 0x06, 0xa1, + 0xc6, 0x80, 0xb9, 0x7e, 0x5c, 0x5a, 0x63, 0xe0, + 0x8d, 0xeb, 0xd0, 0xec, 0x9c, 0x3a, 0x94, 0x64, + 0x7c, 0x13, 0x54, 0x0d, 0xd6, 0xe3, 0x27, 0x88, + 0xa6, 0xd2, 0x4b, 0x36, 0xdd, 0x2e, 0xfa, 0x94, + 0xe5, 0x03, 0x27, 0xc9, 0xa6, 0x31, 0x02, 0xea, + 0x40, 0x77, 0x2e, 0x93, 0xc4, 0x4d, 0xe2, 0x70, + 0xe2, 0x67, 0x1c, 0xa8, 0x0d, 0xcd, 0x1a, 0x72, + 0x86, 0x2c, 0xea, 0xdc, 0x7f, 0x8c, 0x49, 0x2c, + 0xe7, 0x99, 0x13, 0xda, 0x3f, 0x58, 0x9e, 0xf5, + 0x4d, 0x3c, 0x8c, 0x1c, 0xed, 0x85, 0xa7, 0xe2, + 0xae, 0xda, 0x5f, 0xbe, 0x36, 0x1c, 0x9f, 0x5a, + 0xa0, 0xdc, 0x2a, 0xc0, 0xee, 0x71, 0x07, 0x26, + 0x8b, 0xe8, 0x8a, 0xf8, 0x2d, 0x36, 0x78, 0xc9, + 0x79, 0xfa, 0xbe, 0x98, 0x59, 0x95, 0x12, 0x24, + 0xf1, 0xda, 0x20, 0xc7, 0x78, 0xf9, 0x7c, 0x6a, + 0x24, 0x43, 0x82, 0xa8, 0x0f, 0xb1, 0x7d, 0x94, + 0xaa, 0x30, 0x35, 0xe5, 0x69, 0xdc, 0x0a, 0x0e, + 0xaf, 0x10, 0x5e, 0x1a, 0x81, 0x50, 0x5c, 0x7e, + 0x24, 0xb3, 0x07, 0x65, 0x4b, 0xc1, 0x7e, 0xc6, + 0x38, 0xdb, 0xd3, 0x6a, 0xf0, 0xd8, 0x85, 0x61, + 0x9a, 0x9f, 0xfe, 0x02, 0x46, 0x29, 0xb2, 0x9a, + 0xe2, 0x04, 0xe7, 0x72, 0xcc, 0x87, 0x46, 0xba, + 0x7d, 0xa8, 0xf9, 0xd0, 0x0f, 0x29, 0xfc, 0xfd, + 0xd1, 0xd0, 0x7f, 0x36, 0xc1, 0xd8, 0x7d, 0x88, + 0x03, 0x62, 0xf5, 0x8c, 0x00, 0xb5, 0xc2, 0x81, + 0x44, 0x67, 0x58, 0x11, 0xb4, 0x3a, 0xbb, 0xd1, + 0x8c, 0x94, 0x20, 0x60, 0xea, 0xa0, 0xac, 0xc1, + 0xf1, 0x08, 0x54, 0xb8, 0xf6, 0x5e, 0xac, 0xf1, + 0xec, 0x78, 0x69, 0x9d, 0x7e, 0x4d, 0x06, 0x3b, + 0x9b, 0x78, 0x78, 0x10 +}; + +/* + Bag Attributes +friendlyName: uranusLeaf +localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23 +Key Attributes: + */ + +#if TARGET_OS_IPHONE +/* we use _k1 on iPhone */ +static const uint8_t _k1[] = { + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6, + 0x7e, 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, + 0x35, 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, + 0xa8, 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, + 0x80, 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, + 0x93, 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, + 0xd7, 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, + 0xfb, 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, + 0xac, 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, + 0x2a, 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, + 0xc3, 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, + 0x78, 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, + 0x9b, 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, + 0xf6, 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, + 0xe7, 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, + 0xdc, 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, + 0xaa, 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, + 0xe2, 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, + 0x4f, 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, + 0x04, 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, + 0xb2, 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, + 0x71, 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, + 0x44, 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, + 0x48, 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, + 0x4b, 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, + 0x47, 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, + 0x08, 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, + 0x32, 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, + 0x26, 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, + 0x23, 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, + 0xd4, 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, + 0x9e, 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, + 0xf8, 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x01, 0x00, 0x4d, 0x27, 0xf2, + 0x40, 0xc8, 0x3f, 0x5c, 0x87, 0x3c, 0xd9, 0xde, + 0xa6, 0xa5, 0x93, 0xea, 0xbd, 0x36, 0xf8, 0xd9, + 0xad, 0xc7, 0xda, 0x07, 0x7a, 0xec, 0x31, 0x02, + 0x41, 0x09, 0x3a, 0x34, 0x32, 0x82, 0x0b, 0x5b, + 0x7b, 0xe6, 0xa4, 0x2a, 0xe7, 0x14, 0xef, 0x43, + 0x36, 0x61, 0xbe, 0x20, 0x4b, 0x82, 0x43, 0x63, + 0x98, 0x80, 0x82, 0x19, 0x61, 0x71, 0x99, 0xaa, + 0xf8, 0x59, 0xfd, 0xde, 0xa0, 0x03, 0xa8, 0xab, + 0x9a, 0xec, 0x28, 0xac, 0x63, 0x79, 0x75, 0x84, + 0x03, 0xac, 0x45, 0x5e, 0x04, 0x15, 0xb3, 0x47, + 0xa2, 0x8f, 0x28, 0xb0, 0x72, 0xd0, 0x06, 0x02, + 0xaf, 0x1e, 0x0a, 0x0a, 0xe9, 0x11, 0x35, 0x4a, + 0x04, 0x42, 0xb5, 0x0f, 0xd2, 0xcf, 0x4d, 0xdf, + 0xdb, 0xef, 0x58, 0xbd, 0xf3, 0xa5, 0x3b, 0x11, + 0x3f, 0xc5, 0x47, 0x81, 0x85, 0xad, 0xd7, 0x1f, + 0x58, 0x06, 0x42, 0xdc, 0x37, 0x3c, 0xdb, 0x98, + 0x33, 0xa1, 0xc6, 0x80, 0x07, 0xe0, 0x2b, 0xc5, + 0xf5, 0x60, 0x35, 0x6a, 0xa2, 0x06, 0x40, 0x4a, + 0xac, 0x64, 0x02, 0x58, 0x4d, 0x07, 0xe3, 0x69, + 0xd7, 0xe0, 0x8f, 0xb5, 0xf4, 0xbc, 0xfa, 0xab, + 0x1a, 0xb0, 0xfa, 0x29, 0xf8, 0xca, 0xde, 0x78, + 0xf0, 0x89, 0xe2, 0xf9, 0xb7, 0x68, 0x5b, 0x0e, + 0xdc, 0x4e, 0x8a, 0x56, 0x8d, 0x33, 0x20, 0x2e, + 0xed, 0x2e, 0xab, 0x6f, 0xba, 0x77, 0xef, 0xe6, + 0x12, 0x62, 0x49, 0x9e, 0x87, 0x76, 0x1c, 0x1e, + 0xf4, 0x0e, 0x9e, 0x78, 0x98, 0x91, 0x1a, 0xe3, + 0xb4, 0x51, 0x4b, 0x8c, 0x2f, 0x08, 0x97, 0x8f, + 0xf9, 0x68, 0x61, 0x40, 0xcd, 0xb6, 0x10, 0xb4, + 0xfb, 0x75, 0xb4, 0x20, 0xc1, 0x5a, 0xda, 0x64, + 0xfd, 0x51, 0x06, 0x85, 0x9a, 0x9e, 0x5d, 0x82, + 0x14, 0xd4, 0x41, 0x4e, 0x75, 0x10, 0xb5, 0x7b, + 0xd0, 0x4c, 0xd1, 0x00, 0x01, 0x02, 0x81, 0x81, + 0x00, 0xcf, 0x8e, 0x68, 0x04, 0x67, 0x09, 0xa9, + 0x6e, 0xff, 0x11, 0x8c, 0xe5, 0xe4, 0x16, 0xdd, + 0xb6, 0xa6, 0x55, 0xca, 0x4b, 0x0b, 0xbb, 0xb7, + 0xf5, 0xe5, 0x73, 0xf3, 0x24, 0x84, 0x29, 0xb2, + 0xc3, 0xbc, 0x7f, 0x2b, 0x4a, 0xc7, 0xdf, 0x46, + 0x8e, 0xe1, 0x35, 0x69, 0x1b, 0x8e, 0x9f, 0x6b, + 0x4d, 0xf3, 0x65, 0xae, 0x3d, 0x87, 0x2b, 0xc9, + 0xf0, 0x8c, 0xf2, 0x88, 0x2f, 0x1b, 0x79, 0x80, + 0xd2, 0xb2, 0x64, 0x0a, 0xcc, 0x66, 0x69, 0x4c, + 0xa1, 0x85, 0xc4, 0x6a, 0x94, 0x46, 0x70, 0x69, + 0xbc, 0x8c, 0x1c, 0x62, 0x65, 0x4d, 0x68, 0xcc, + 0xe3, 0x3c, 0x6c, 0xe7, 0xd1, 0x09, 0xed, 0xdd, + 0x42, 0x10, 0x11, 0x6b, 0xdd, 0x7c, 0xe3, 0xe1, + 0x3b, 0x3b, 0x0d, 0x01, 0x6d, 0xca, 0x2f, 0x4b, + 0x45, 0x5e, 0x76, 0x5d, 0x5c, 0x6f, 0x53, 0xa4, + 0x38, 0x74, 0x75, 0x94, 0x2c, 0xda, 0xf8, 0xa6, + 0x01, 0x02, 0x81, 0x81, 0x00, 0xcd, 0x5f, 0x9d, + 0x6c, 0x94, 0xf6, 0x44, 0x37, 0x72, 0xfe, 0xcf, + 0xbe, 0x82, 0x96, 0x24, 0x22, 0x12, 0x07, 0x6f, + 0xd1, 0x57, 0x7b, 0xc7, 0x63, 0x20, 0xf5, 0x93, + 0x79, 0x70, 0x0b, 0xe4, 0x38, 0x19, 0x62, 0x7b, + 0x89, 0x3e, 0x45, 0xdf, 0xd6, 0xae, 0x9d, 0x0d, + 0xa8, 0x76, 0xc1, 0xbd, 0x04, 0x2b, 0xaa, 0x30, + 0x6a, 0xac, 0x65, 0x91, 0x61, 0xf0, 0xf8, 0x5d, + 0xa3, 0x53, 0xa4, 0xfb, 0x99, 0xac, 0x46, 0x7a, + 0x12, 0x4b, 0xf7, 0xa7, 0x48, 0x41, 0x61, 0x48, + 0x26, 0x5c, 0x68, 0x2f, 0x73, 0x91, 0xe4, 0x74, + 0xcd, 0xc9, 0x8b, 0xe7, 0x26, 0xe4, 0x35, 0xde, + 0x32, 0x6b, 0x24, 0x49, 0xf2, 0x04, 0x67, 0x3d, + 0x31, 0x8f, 0x22, 0xe5, 0x49, 0xae, 0x49, 0x94, + 0xb3, 0x45, 0x2b, 0xed, 0x6f, 0x9c, 0xc7, 0x80, + 0xf0, 0x42, 0xd5, 0x8f, 0x27, 0xd6, 0xd6, 0x49, + 0xf2, 0x16, 0xcc, 0x4b, 0x39, 0x02, 0x81, 0x81, + 0x00, 0xbb, 0xb7, 0xd7, 0x59, 0xcb, 0xfb, 0x10, + 0x13, 0xc4, 0x7b, 0x92, 0x0c, 0x45, 0xcb, 0x6c, + 0x81, 0x0a, 0x55, 0x63, 0x1d, 0x96, 0xa2, 0x13, + 0xd2, 0x40, 0xd1, 0x2a, 0xa1, 0xe7, 0x2a, 0x73, + 0x74, 0xd6, 0x61, 0xc9, 0xbc, 0xdb, 0xa2, 0x93, + 0x85, 0x1c, 0x28, 0x9b, 0x44, 0x82, 0x2c, 0xaa, + 0xf7, 0x18, 0x60, 0xe9, 0x42, 0xda, 0xa2, 0xff, + 0x04, 0x21, 0xe6, 0x24, 0xc7, 0x3e, 0x39, 0x19, + 0x0a, 0xf6, 0xae, 0xc6, 0x99, 0x71, 0x32, 0x61, + 0x4d, 0x60, 0xd7, 0x71, 0x71, 0x63, 0x77, 0xbe, + 0x19, 0xfa, 0x3a, 0x9d, 0xbf, 0x73, 0x50, 0x8a, + 0xa6, 0x26, 0x7b, 0x74, 0xfa, 0x39, 0xd9, 0xb9, + 0x18, 0x4b, 0xc2, 0x05, 0xe5, 0x8f, 0x53, 0xe6, + 0xdc, 0x14, 0x1f, 0x42, 0x20, 0x93, 0x11, 0x4d, + 0x29, 0x93, 0x32, 0xc8, 0x63, 0x96, 0x88, 0x76, + 0x69, 0x5c, 0xe3, 0x0e, 0xbd, 0xb6, 0xd9, 0xd6, + 0x01, 0x02, 0x81, 0x80, 0x62, 0xa2, 0xed, 0x84, + 0xdc, 0xf6, 0x7a, 0x44, 0xf7, 0x62, 0x12, 0x7c, + 0xb9, 0x53, 0x4a, 0xff, 0x62, 0x11, 0x58, 0x4e, + 0xfe, 0xe9, 0x60, 0x15, 0xe8, 0x1a, 0x8a, 0x3d, + 0xe4, 0xe6, 0x91, 0x31, 0xb0, 0x5f, 0x70, 0x5d, + 0xb6, 0x1e, 0xf1, 0x26, 0xb6, 0xae, 0x8f, 0x84, + 0xbd, 0xa4, 0xc7, 0x17, 0x5d, 0xb1, 0x5b, 0x97, + 0xa0, 0x3d, 0x17, 0xda, 0x26, 0x55, 0xe3, 0x03, + 0x32, 0x85, 0x26, 0xa1, 0xe3, 0xef, 0xe5, 0x69, + 0x2c, 0x3b, 0x41, 0x88, 0x9e, 0x7e, 0x0e, 0x9c, + 0xfd, 0xfc, 0xbb, 0xed, 0x91, 0xc0, 0x5b, 0xa9, + 0x0a, 0x87, 0xba, 0xf9, 0x1e, 0xda, 0x10, 0x61, + 0xbe, 0xbb, 0xab, 0x18, 0x25, 0xad, 0x3f, 0xe2, + 0xb1, 0x90, 0x5c, 0xf7, 0x4a, 0x51, 0xe4, 0xad, + 0x45, 0x27, 0x97, 0xdd, 0xe7, 0x3a, 0x9a, 0x5e, + 0xca, 0x7a, 0xaf, 0x4a, 0xbf, 0x10, 0x24, 0x6b, + 0xb5, 0x2f, 0x61, 0x61, 0x02, 0x81, 0x81, 0x00, + 0x85, 0x7c, 0x78, 0xa5, 0x11, 0xdf, 0xc3, 0x6a, + 0x38, 0x48, 0xfa, 0x7e, 0x48, 0xf0, 0x5a, 0x58, + 0xe2, 0xc5, 0x83, 0x4e, 0x38, 0x3f, 0x4a, 0x2b, + 0x07, 0x57, 0x31, 0xe7, 0xbe, 0x50, 0xb1, 0xbb, + 0x24, 0xf3, 0x3d, 0x8b, 0x53, 0xb7, 0xd1, 0x47, + 0x72, 0x5e, 0xd5, 0xd6, 0x4c, 0xce, 0x2c, 0x46, + 0x61, 0x9a, 0xaa, 0xc3, 0x0e, 0xd4, 0x23, 0x2c, + 0xdd, 0xf5, 0xb7, 0xad, 0x38, 0x52, 0x17, 0xc4, + 0x16, 0xbb, 0xda, 0x1c, 0x61, 0xb1, 0xca, 0x8d, + 0xb2, 0xa0, 0xbe, 0x4f, 0x3d, 0x19, 0x0e, 0xe0, + 0x0e, 0x52, 0xad, 0xf3, 0xaf, 0xd9, 0xcc, 0x78, + 0xc2, 0xb1, 0x5e, 0x05, 0x5e, 0xf2, 0x27, 0x84, + 0x15, 0xe4, 0x8f, 0xca, 0xc5, 0x92, 0x43, 0xe0, + 0x24, 0x8d, 0xf2, 0x5d, 0x55, 0xcc, 0x9d, 0x2f, + 0xa9, 0xf6, 0x9b, 0x67, 0x6a, 0x87, 0x74, 0x36, + 0x34, 0x7c, 0xd4, 0x9d, 0xff, 0xad, 0xee, 0x69 +}; +#else + /* don’t use _k1 */ +#endif + +__unused static const uint8_t _k1_digest[] = { + 0x46, 0xE0, 0x8A, 0x05, 0x63, 0x4D, 0x17, 0x3F, + 0xCA, 0xA4, 0xAA, 0xB6, 0x5A, 0xDA, 0xCF, 0xBA, + 0x84, 0x22, 0x7C, 0x23 +}; + +/* Create and identity and try to retrieve it. */ +-(void) testClientAuth41 +{ + SecCertificateRef cert = NULL, cert2 = NULL; + SecKeyRef privKey = NULL; + SecIdentityRef identity = NULL; + CFArrayRef trust_chain = NULL; + SSLContextRef ctx = NULL; + + XCTAssertNotEqual(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), + NULL, "create certificate"); + XCTAssertNotEqual(cert2 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), + NULL, "create certificate2"); +#if TARGET_OS_IPHONE + privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1), + kSecKeyEncodingPkcs1); +#else + privKey = NULL; /* TODO */ +#endif + XCTAssertNotEqual(privKey, NULL, "create private key"); + + XCTAssert(identity = SecIdentityCreate(kCFAllocatorDefault, cert, privKey), "SecIdentityCreate"); + CFReleaseSafe(cert); + CFReleaseSafe(privKey); + const void *values[] = { identity, cert2 }; + XCTAssert(trust_chain = CFArrayCreate(kCFAllocatorDefault, values, + array_size(values), &kCFTypeArrayCallBacks), "CFArrayCreate"); + CFReleaseSafe(identity); + CFReleaseSafe(cert2); + + XCTAssertEqual(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1"); + XCTAssertEqual(CFGetRetainCount(identity), 1, "identity rc = 1"); + XCTAssertEqual(CFGetRetainCount(cert), 1, "cert rc = 1"); + XCTAssertEqual(CFGetRetainCount(cert2), 1, "cert2 rc = 1"); + XCTAssertEqual(CFGetRetainCount(privKey), 1, "privKey rc = 1"); + + XCTAssert(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + require(ctx, errOut); + XCTAssertEqual(errSecSuccess, SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate"); + CFReleaseSafe(ctx); + + XCTAssertEqual(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1"); + XCTAssertEqual(CFGetRetainCount(identity), 1, "identity rc = 1"); + XCTAssertEqual(CFGetRetainCount(cert), 1, "cert rc = 1"); + XCTAssertEqual(CFGetRetainCount(cert2), 1, "cert2 rc = 1"); + XCTAssertEqual(CFGetRetainCount(privKey), 1, "privKey rc = 1"); + + XCTAssert(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLCreateContext"); + require(ctx, errOut); + XCTAssertEqual(errSecSuccess, SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate"); + CFReleaseSafe(ctx); + + XCTAssertEqual(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1"); + XCTAssertEqual(CFGetRetainCount(identity), 1, "identity rc = 1"); + XCTAssertEqual(CFGetRetainCount(cert), 1, "cert rc = 1"); + XCTAssertEqual(CFGetRetainCount(cert2), 1, "cert2 rc = 1"); + XCTAssertEqual(CFGetRetainCount(privKey), 1, "privKey rc = 1"); + + XCTAssert(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLCreateContext"); + require(ctx, errOut); + XCTAssertEqual(errSecSuccess,SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate"); + XCTAssertEqual(errSecSuccess,SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate"); + CFReleaseSafe(ctx); + + XCTAssertEqual(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1"); + XCTAssertEqual(CFGetRetainCount(identity), 1, "identity rc = 1"); + XCTAssertEqual(CFGetRetainCount(cert), 1, "cert rc = 1"); + XCTAssertEqual(CFGetRetainCount(cert2), 1, "cert2 rc = 1"); + XCTAssertEqual(CFGetRetainCount(privKey), 1, "privKey rc = 1"); + +errOut: + CFReleaseNull(trust_chain); +} +@end diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+crashes.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+crashes.m new file mode 100644 index 00000000..a2db3afd --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+crashes.m @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2012-2015 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@ + */ + + +#include +#import "STLegacyTests.h" +#include +#include +#include +#include +#include + +#include + +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#include "ssl-utils.h" + +@implementation STLegacyTests (crashes) + +typedef struct { + SSLContextRef st; + bool is_server; + int comm; + CFArrayRef certs; + int test; +} ssl_test_handle; + + +#pragma mark - +#pragma mark SecureTransport support + +#if 0 +static void hexdump(const char *s, const uint8_t *bytes, size_t len) { + size_t ix; + printf("socket %s(%p, %lu)\n", s, bytes, len); + for (ix = 0; ix < len; ++ix) { + if (!(ix % 16)) + printf("\n"); + printf("%02X ", bytes[ix]); + } + printf("\n"); +} +#else +#define hexdump(string, bytes, len) +#endif + +static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length) +{ + int conn = ((const ssl_test_handle *)h)->comm; + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + hexdump("write", ptr, len); + ret = write((int)conn, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static int changepad=0; + +static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length) +{ + const ssl_test_handle *handle=h; + int conn = handle->comm; + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + + do { + ssize_t ret; + do { + ret = read((int)conn, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + if(len!=0) + printf("Something went wrong here... len=%d\n", (int)len); + + *length = *length - len; + + ptr=data; + + /* change pad in the data */ + if(changepad==1) { + changepad=0; + ptr[31]=ptr[31]^0x08^0xff; // expected padding was 8, changing it to 0xff to trigger integer underflow. + } + + /* We are reading the server cert */ + if((ptr[0]==0x0b) && (handle->test==3)) { +#if 1 // cert length for TARGET_OS_IPHONE + size_t expected_len = 631; +#else + size_t expected_len = 500; +#endif + if(*length!=expected_len) { + fprintf(stderr, "Expected cert length %ld, got %ld... test might fail\n", + (long)expected_len, (long)*length); + } + ptr[0x16] = 0x4; // version = 4 certificate should cause error, but not crash . + } + + /* We are reading a data application header */ + if(*length==5 && ptr[0]==0x17) { + switch(handle->test) { + case 0: + ptr[4]=32; // reduce the size to 2 blocks and trigger integer underflow. + break; + case 1: + ptr[4]=48; // reduce the size to 3 blocks and triggering integer underflow in the padding. + break; + case 2: + changepad=1; + break; + default: + break; + } + } + + + return errSecSuccess; +} + + + +static void *securetransport_ssl_thread(void *arg) +{ + OSStatus ortn; + ssl_test_handle * ssl = (ssl_test_handle *)arg; + SSLContextRef ctx = ssl->st; + bool got_server_auth = false; + + //uint64_t start = mach_absolute_time(); + do { + ortn = SSLHandshake(ctx); + + if (ortn == errSSLServerAuthCompleted) + { + require_string(!got_server_auth, out, "second server auth"); + got_server_auth = true; + } + } while (ortn == errSSLWouldBlock + || ortn == errSSLServerAuthCompleted); + + require_noerr_quiet(ortn, out); + + unsigned char ibuf[8], obuf[8]; + size_t len; + if (ssl->is_server) { + require_action_quiet(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf), out, ortn = -1); + require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out); + require_action_quiet(len == sizeof(obuf), out, ortn = -1); + } else { + require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out); + require_action_quiet(len == sizeof(ibuf), out, ortn = -1); + } + +out: + SSLClose(ctx); + CFRelease(ctx); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + +static ssl_test_handle * +ssl_test_handle_create(bool server, int comm, CFArrayRef certs) +{ + ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType); + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out); + + if (server) + require_noerr(SSLSetCertificate(ctx, certs), out); + + require_noerr(SSLSetSessionOption(ctx, + kSSLSessionOptionBreakOnServerAuth, true), out); + + /* Tell SecureTransport to not check certs itself: it will break out of the + handshake to let us take care of it instead. */ + require_noerr(SSLSetEnableCertVerify(ctx, false), out); + + handle->is_server = server; + handle->comm = comm; + handle->certs = certs; + handle->st = ctx; + + return handle; + +out: + if (handle) free(handle); + if (ctx) CFRelease(ctx); + return NULL; +} + +-(void)testCrashes +{ + pthread_t client_thread, server_thread; + CFArrayRef server_certs = server_chain(); + XCTAssert(server_certs, "got server certs"); + + int i; + + for(i=0; i<4; i++) + { + int sp[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno); + fcntl(sp[0], F_SETNOSIGPIPE, 1); + fcntl(sp[1], F_SETNOSIGPIPE, 1); + + ssl_test_handle *server, *client; + + server = ssl_test_handle_create(true /*server*/, sp[0], server_certs); + client = ssl_test_handle_create(false/*client*/, sp[1], NULL); + + server->test=i; + client->test=i; + + require(client, out); + require(server, out); + + SSLCipherSuite cipher = TLS_RSA_WITH_AES_128_CBC_SHA256; + require_noerr(SSLSetEnabledCiphers(client->st, &cipher, 1), out); + + pthread_create(&client_thread, NULL, securetransport_ssl_thread, client); + pthread_create(&server_thread, NULL, securetransport_ssl_thread, server); + + intptr_t server_err, client_err; + pthread_join(client_thread, (void*)&client_err); + pthread_join(server_thread, (void*)&server_err); + + XCTAssert(server_err==((i==3)?errSSLPeerCertUnknown:0), "Server error = %zu (i=%d)", server_err, i); + /* tests 0/1 should cause errSSLClosedAbort, 2 should cause errSSLBadRecordMac, 3 should cause errSSLXCertChainInvalid */ + XCTAssert(client_err==((i==3)?errSSLXCertChainInvalid:(i==2)?errSSLBadRecordMac:errSSLClosedAbort), "Client error = %zu (i=%d)", client_err, i); + +out: + free(client); + free(server); + + } + CFReleaseNull(server_certs); +} + +@end diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+dhe.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+dhe.m new file mode 100644 index 00000000..7e41a080 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+dhe.m @@ -0,0 +1,400 @@ + +#include +#include +#include +#include +#include + +#include + +#include +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#include "ssl-utils.h" +#import "STLegacyTests.h" + +@implementation STLegacyTests (dhe) + +/* + SSL DHE tests: + + Test both the client and server side. + + Test Goal: + - Make sure that handshake fail when dh param size is too small. + + Behavior to verify: + - handshake pass or fail + +*/ + + +static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = write((int)conn, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = read((int)conn, ptr, len); + } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } else { + printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno); + return -errno; + } + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +typedef struct { + SSLContextRef st; + int comm; + unsigned dhe_size; +} ssl_client_handle; + +static ssl_client_handle * +ssl_client_handle_create(int comm, CFArrayRef trustedCA, unsigned dhe_size) +{ + ssl_client_handle *handle = calloc(1, sizeof(ssl_client_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType); + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + static const char *peer_domain_name = "localhost"; + require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name, + strlen(peer_domain_name)), out); + + require_noerr(SSLSetTrustedRoots(ctx, trustedCA, true), out); + + require_noerr(SSLSetDHEEnabled(ctx, true), out); + + if(dhe_size) + require_noerr(SSLSetMinimumDHGroupSize(ctx, dhe_size), out); + + handle->comm = comm; + handle->st = ctx; + handle->dhe_size = dhe_size; + + return handle; + +out: + if (ctx) + CFRelease(ctx); + if (handle) + free(handle); + + return NULL; +} + +static void +ssl_client_handle_destroy(ssl_client_handle *handle) +{ + if(handle) { + SSLClose(handle->st); + CFRelease(handle->st); + free(handle); + } +} + +static void *securetransport_ssl_client_thread(void *arg) +{ + OSStatus ortn; + ssl_client_handle * ssl = (ssl_client_handle *)arg; + SSLContextRef ctx = ssl->st; + SSLSessionState ssl_state; + + pthread_setname_np("client thread"); + + require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); + require_action(ssl_state==kSSLIdle, out, ortn = -1); + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLWouldBlock) { + require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock"); + } + } while (ortn == errSSLWouldBlock); + +out: + SSLClose(ssl->st); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + +typedef struct { + SSLContextRef st; + int comm; + CFArrayRef certs; + +} ssl_server_handle; + +static ssl_server_handle * +ssl_server_handle_create(int comm, CFArrayRef certs, const void *dhParams, size_t dhParamsLen) +{ + ssl_server_handle *handle = calloc(1, sizeof(ssl_server_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType); + SSLCipherSuite cipher = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256; + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + + require_noerr(SSLSetCertificate(ctx, certs), out); + + require_noerr(SSLSetEnabledCiphers(ctx, &cipher, 1), out); + + if(dhParams) + require_noerr(SSLSetDiffieHellmanParams(ctx, dhParams, dhParamsLen), out); + + handle->comm = comm; + handle->certs = certs; + handle->st = ctx; + + return handle; + +out: + if (ctx) + CFRelease(ctx); + if (handle) + free(handle); + + return NULL; +} + +static void +ssl_server_handle_destroy(ssl_server_handle *handle) +{ + if(handle) { + SSLClose(handle->st); + CFRelease(handle->st); + free(handle); + } +} + +static void *securetransport_ssl_server_thread(void *arg) +{ + OSStatus ortn; + ssl_server_handle * ssl = (ssl_server_handle *)arg; + SSLContextRef ctx = ssl->st; + SSLSessionState ssl_state; + + pthread_setname_np("server thread"); + + require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); + require_action(ssl_state==kSSLIdle, out, ortn = -1); + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLWouldBlock) { + require_action(ssl_state==kSSLHandshake, out, ortn = -1); + } + } while (ortn == errSSLWouldBlock); + + require_noerr_quiet(ortn, out); + + require_action(ssl_state==kSSLConnected, out, ortn = -1); + +out: + SSLClose(ssl->st); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + + +static +unsigned client_dhe_sizes[] = { + 0, // default, don't set. + 256, // will resolve to 512. + 512, + 768, + 1024, + 2048, + 4096, // will resolve to 2048. +}; + + +static const unsigned n_client_dhe_sizes = sizeof(client_dhe_sizes)/sizeof(client_dhe_sizes[0]); + +static uint8_t dh_parameters_256_data[] = { + 0x30, 0x26, 0x02, 0x21, 0x00, 0xd8, 0x23, 0xeb, 0xcb, 0x41, 0xd0, 0x3a, + 0xc4, 0x9a, 0x2a, 0x2a, 0x4f, 0x35, 0xf7, 0x4f, 0xd9, 0xc5, 0x2e, 0xf8, + 0x44, 0xa7, 0x74, 0xe3, 0x84, 0x98, 0x9f, 0xad, 0x58, 0xd5, 0x15, 0xb4, + 0xf3, 0x02, 0x01, 0x02 +}; + +static uint8_t dh_parameters_512_data[] = { + 0x30, 0x46, 0x02, 0x41, 0x00, 0x85, 0xcd, 0xc1, 0x7e, 0x26, 0xeb, 0x37, + 0x84, 0x13, 0xd0, 0x3b, 0x07, 0xc1, 0x57, 0x7d, 0xf3, 0x55, 0x8d, 0xa0, + 0xc4, 0xa5, 0x03, 0xc4, 0x2c, 0xc6, 0xd5, 0xa6, 0x31, 0xcb, 0x68, 0xdf, + 0x5d, 0x96, 0x20, 0x1a, 0x15, 0x57, 0x49, 0x7d, 0xd7, 0x51, 0x65, 0x6e, + 0x37, 0xa8, 0xe3, 0xe9, 0xe1, 0x59, 0x2e, 0xd4, 0x57, 0x4a, 0xf0, 0xcb, + 0x0e, 0x85, 0x07, 0xdd, 0x35, 0xa7, 0xe3, 0xc6, 0xbb, 0x02, 0x01, 0x02 +}; + +static uint8_t dh_parameters_768_data[] = { + 0x30, 0x66, 0x02, 0x61, 0x00, 0xe1, 0xa2, 0x50, 0xab, 0xb0, 0xdc, 0xef, + 0xe1, 0x2f, 0xd9, 0xde, 0x59, 0x86, 0x24, 0x43, 0x3b, 0xf3, 0x40, 0x9d, + 0x02, 0xcc, 0xe2, 0x70, 0x63, 0x46, 0x8d, 0x0f, 0xf3, 0x8a, 0xc6, 0xa0, + 0x1d, 0x7b, 0x30, 0x83, 0x10, 0x48, 0x40, 0x28, 0xa4, 0x3e, 0xbe, 0x4d, + 0xb6, 0xea, 0x90, 0x02, 0xae, 0x25, 0x93, 0xc0, 0xe8, 0x36, 0x5c, 0xc8, + 0xc8, 0x0b, 0x04, 0xd5, 0x05, 0xac, 0x67, 0x24, 0x4b, 0xa9, 0x42, 0x5a, + 0x03, 0x65, 0x4d, 0xd0, 0xc0, 0xbd, 0x78, 0x32, 0xd0, 0x8c, 0x0a, 0xf4, + 0xbf, 0xd1, 0x61, 0x86, 0x13, 0x13, 0x3b, 0x83, 0xce, 0xbf, 0x3b, 0xbc, + 0x8f, 0xf9, 0x4e, 0x50, 0xe3, 0x02, 0x01, 0x02 +}; + +static uint8_t dh_parameters_1024_data[] = { + 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0xd5, 0x06, 0x69, 0xc6, 0xd4, + 0x98, 0x2b, 0xe3, 0x49, 0xe2, 0xa1, 0x9b, 0x82, 0xaf, 0x3f, 0xaa, 0xc3, + 0x86, 0x2a, 0x7a, 0xfa, 0x62, 0x12, 0x33, 0x45, 0x9f, 0x34, 0x57, 0xc6, + 0x6c, 0x88, 0x81, 0xa6, 0x5d, 0xa3, 0x43, 0xe5, 0x4d, 0x87, 0x4f, 0x69, + 0x3d, 0x2b, 0xc8, 0x18, 0xb6, 0xd7, 0x29, 0x53, 0x94, 0x0d, 0x73, 0x9b, + 0x08, 0x22, 0x73, 0x84, 0x7b, 0x5a, 0x03, 0x2e, 0xfc, 0x10, 0x9b, 0x35, + 0xc6, 0xa1, 0xca, 0x36, 0xd0, 0xcc, 0x3e, 0xa2, 0x04, 0x3a, 0x8a, 0xe8, + 0x87, 0xe8, 0x60, 0x72, 0xee, 0x99, 0xf3, 0x04, 0x0a, 0xd8, 0x1a, 0xe6, + 0xfc, 0xbc, 0xe1, 0xc5, 0x9d, 0x3a, 0xca, 0xf9, 0xfd, 0xbf, 0x58, 0xd3, + 0x4d, 0xde, 0x8b, 0x4a, 0xb5, 0x37, 0x1e, 0x6d, 0xf4, 0x22, 0x0f, 0xb7, + 0x48, 0x0a, 0xda, 0x82, 0x40, 0xc9, 0x55, 0x20, 0x01, 0x3b, 0x35, 0xb2, + 0x94, 0x68, 0xab, 0x02, 0x01, 0x02 +}; + + +static +struct { + const void *dhParams; + size_t dhParamsLen; +} server_dhe_params[] = { + {dh_parameters_256_data, sizeof(dh_parameters_256_data)}, + {dh_parameters_512_data, sizeof(dh_parameters_512_data)}, + {dh_parameters_768_data, sizeof(dh_parameters_768_data)}, + {dh_parameters_1024_data, sizeof(dh_parameters_1024_data)}, + {NULL, 0}, // default is a 2048 +}; + +static const unsigned n_server_dhe_params = sizeof(server_dhe_params)/sizeof(server_dhe_params[0]); + +static +int expected_client_error[n_server_dhe_params][n_client_dhe_sizes] = { +//Client: +// (default) +// 1024, 512, 512, 768, 1024, 2048, 2048 // Server: + { -9850, -9850, -9850, -9850, -9850, -9850, -9850}, // 256 + { -9850, 0, 0, -9850, -9850, -9850, -9850}, // 512 + { -9850, 0, 0, 0, -9850, -9850, -9850}, // 768 + { 0, 0, 0, 0, 0, -9850, -9850}, // 1024 + { 0, 0, 0, 0, 0, 0, 0}, // default(2048) +}; + +-(void)testDHE +{ + pthread_t client_thread, server_thread; + CFArrayRef server_certs = server_chain(); + CFArrayRef trusted_ca = trusted_roots(); + + XCTAssert(server_certs, "got server certs"); + XCTAssert(trusted_ca, "got trusted roots"); + + int i, j; + + for (i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include /* SSLSetOption */ +#include + +#include +#include +#include +#include +#include +#include + + +#import "STLegacyTests.h" + +@implementation STLegacyTests (falsestart) + +typedef struct { + uint32_t session_id; + bool is_session_resume; + SSLContextRef st; + bool is_server; + bool client_side_auth; + bool dh_anonymous; + int comm; + CFArrayRef certs; +} ssl_test_handle; + + + +#if 0 +static void hexdump(const uint8_t *bytes, size_t len) { + size_t ix; + printf("socket write(%p, %lu)\n", bytes, len); + for (ix = 0; ix < len; ++ix) { + if (!(ix % 16)) + printf("\n"); + printf("%02X ", bytes[ix]); + } + printf("\n"); +} +#else +#define hexdump(bytes, len) +#endif + +static int SocketConnect(const char *hostName, int port) +{ + struct sockaddr_in addr; + struct in_addr host; + int sock; + int err; + struct hostent *ent; + + if (hostName[0] >= '0' && hostName[0] <= '9') { + host.s_addr = inet_addr(hostName); + } else { + ent = gethostbyname(hostName); + if(ent == NULL) { + printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno)); + return -2; + } + memcpy(&host, ent->h_addr, sizeof(struct in_addr)); + } + + sock = socket(AF_INET, SOCK_STREAM, 0); + addr.sin_addr = host; + addr.sin_port = htons((u_short)port); + + addr.sin_family = AF_INET; + err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)); + + if(err!=0) + { + perror("connect failed"); + return -1; + } + + /* make non blocking */ + fcntl(sock, F_SETFL, O_NONBLOCK); + + return sock; +} + +static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + hexdump(ptr, len); + ret = write((int)conn, ptr, len); + if (ret < 0) + perror("send"); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static +OSStatus SocketRead( + SSLConnectionRef connection, + void *data, + size_t *dataLength) +{ + int fd = (int)connection; + ssize_t len; + + len = read(fd, data, *dataLength); + + if(len<0) { + int theErr = errno; + switch(theErr) { + case EAGAIN: + //printf("SocketRead: EAGAIN\n"); + *dataLength=0; + /* nonblocking, no data */ + return errSSLWouldBlock; + default: + perror("SocketRead"); + return -36; + } + } + + if(len<(ssize_t)*dataLength) { + *dataLength=len; + return errSSLWouldBlock; + } + + return errSecSuccess; +} + +static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot, Boolean false_start) +{ + SSLContextRef ctx = NULL; + + require_noerr(SSLNewContext(false, &ctx), out); + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out); + + require_noerr(SSLSetSessionOption(ctx, + kSSLSessionOptionBreakOnServerAuth, true), out); + + require_noerr(SSLSetSessionOption(ctx, + kSSLSessionOptionFalseStart, false_start), out); + + require_noerr(SSLSetProtocolVersionMax(ctx, maxprot), out); + + return ctx; +out: + if (ctx) + SSLDisposeContext(ctx); + return NULL; +} + +const char request[]="GET / HTTP/1.1\n\n"; +char reply[2048]; + +static OSStatus securetransport(ssl_test_handle * ssl) +{ + OSStatus ortn; + SSLContextRef ctx = ssl->st; + SecTrustRef trust = NULL; + bool got_server_auth = false, got_client_cert_req = false; + + ortn = SSLHandshake(ctx); + + require_action_quiet(ortn==errSSLWouldBlock, out, printf("SSLHandshake failed with err %ld\n", (long)ortn)); + + size_t sent, received; + const char *r=request; + size_t l=sizeof(request); + + do { + + ortn = SSLWrite(ctx, r, l, &sent); + + if(ortn == errSSLWouldBlock) { + r+=sent; + l-=sent; + } + + if (ortn == errSSLServerAuthCompleted) + { + require_string(!got_server_auth, out, "second server auth"); + require_string(!got_client_cert_req, out, "got client cert req before server auth"); + got_server_auth = true; + require_string(!trust, out, "Got errSSLServerAuthCompleted twice?"); + /* verify peer cert chain */ + require_noerr(SSLCopyPeerTrust(ctx, &trust), out); + SecTrustResultType trust_result = 0; + /* this won't verify without setting up a trusted anchor */ + require_noerr(SecTrustEvaluate(trust, &trust_result), out); + } + } while(ortn == errSSLWouldBlock || ortn == errSSLServerAuthCompleted); + + //fprintf(stderr, "\nHTTP Request Sent\n"); + + require_noerr_action_quiet(ortn, out, printf("SSLWrite failed with err %ld\n", (long)ortn)); + + require_string(got_server_auth, out, "never got server auth"); + + do { + ortn = SSLRead(ctx, reply, sizeof(reply)-1, &received); + //fprintf(stderr, "r"); usleep(1000); + } while(ortn == errSSLWouldBlock); + + //fprintf(stderr, "\n"); + + require_noerr_action_quiet(ortn, out, printf("SSLRead failed with err %ld\n", (long)ortn)); + + reply[received]=0; + + //fprintf(stderr, "HTTP reply:\n"); + //fprintf(stderr, "%s\n",reply); + +out: + SSLClose(ctx); + SSLDisposeContext(ctx); + if (trust) CFRelease(trust); + + return ortn; +} + +static ssl_test_handle * +ssl_test_handle_create(int comm, SSLProtocol maxprot, Boolean false_start) +{ + ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle)); + if (handle) { + handle->comm = comm; + handle->st = make_ssl_ref(comm, maxprot, false_start); + } + return handle; +} + +static +struct s_server { + char *host; + int port; + SSLProtocol maxprot; +} servers[] = { + /* Good tls 1.2 servers */ + {"encrypted.google.com", 443, kTLSProtocol12 }, + {"www.amazon.com",443, kTLSProtocol12 }, + //{"www.mikestoolbox.org",443, kTLSProtocol12 }, +}; + +#define NSERVERS (int)(sizeof(servers)/sizeof(servers[0])) +#define NLOOPS 1 +#define CONNECT_TRIES 3 + +-(void)testFalseStart +{ + int p; + int fs; + + for(p=0; p +#include +#import "STLegacyTests.h" + +@implementation STLegacyTests (dhe) + +static +OSStatus r(SSLConnectionRef connection, void *data, size_t *dataLength) { + return errSSLWouldBlock; +} + +static +OSStatus w(SSLConnectionRef connection, const void *data, size_t *dataLength) { + return errSSLWouldBlock; +} + +//Testing Trivial SecureTransport example crashes on Cab, where it worked on Zin +-(void) testNoConn +{ + OSStatus ortn; + SSLContextRef ctx; + ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); + SSLSetIOFuncs(ctx, r, w); + ortn = SSLHandshake(ctx); + + XCTAssertEqual(ortn, errSSLWouldBlock, "SSLHandshake unexpected return\n"); + + CFRelease(ctx); +} + + +@end + diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+renegotiate.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+renegotiate.m new file mode 100644 index 00000000..0d7e2ad9 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+renegotiate.m @@ -0,0 +1,465 @@ + +#include +#include +#include +#include +#include + +#include + +#include +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#include "ssl-utils.h" +#import "STLegacyTests.h" + +@implementation STLegacyTests (renegotiation) + +/* + SSL Renegotiation tests: + + Test both the client and server side. + + Test Goal: + - Make sure that renegotiation works on both client and server. + + Behavior to verify: + - handshake pass or fail + +*/ + + +static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = write((int)conn, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = read((int)conn, ptr, len); + } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } else { + printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno); + return -errno; + } + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +typedef struct { + SSLContextRef st; + int comm; + unsigned dhe_size; + bool renegotiate; +} ssl_client_handle; + +static ssl_client_handle * +ssl_client_handle_create(int comm, bool renegotiate) +{ + ssl_client_handle *handle = calloc(1, sizeof(ssl_client_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType); + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + static const char *peer_domain_name = "localhost"; + require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name, + strlen(peer_domain_name)), out); + + require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, TRUE), out); + + require_noerr(SSLSetAllowsAnyRoot(ctx, TRUE), out); + + + handle->comm = comm; + handle->st = ctx; + handle->renegotiate = renegotiate; + + return handle; + +out: + if (ctx) + CFRelease(ctx); + if (handle) + free(handle); + + return NULL; +} + +static void +ssl_client_handle_destroy(ssl_client_handle *handle) +{ + if(handle) { + SSLClose(handle->st); + CFRelease(handle->st); + free(handle); + } +} + +static void *securetransport_ssl_client_thread(void *arg) +{ + OSStatus ortn; + ssl_client_handle * ssl = (ssl_client_handle *)arg; + SSLContextRef ctx = ssl->st; + SSLSessionState ssl_state; + bool peer_auth_received = false; + + pthread_setname_np("client thread"); + + require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); + require_action(ssl_state==kSSLIdle, out, ortn = -1); + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLPeerAuthCompleted) { + require_action(!peer_auth_received, out, ortn = -1); + peer_auth_received = true; + } + if (ortn == errSSLWouldBlock) { + require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock"); + } + } while (ortn == errSSLWouldBlock || ortn == errSSLPeerAuthCompleted); + + require_noerr(ortn, out); + require_action(ssl_state==kSSLConnected, out, ortn = -1); + require_action(peer_auth_received, out, ortn = -1); + + if(ssl->renegotiate) { + // Renegotiate then write + require_noerr(SSLReHandshake(ctx), out); + + peer_auth_received = false; + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + if (ortn == errSSLPeerAuthCompleted) { + require_action(!peer_auth_received, out, ortn = -1); + peer_auth_received = true; + } + if (ortn == errSSLWouldBlock) { + require_action(ssl_state==kSSLHandshake, out, ortn = -1); + } + } while (ortn == errSSLWouldBlock || ortn == errSSLPeerAuthCompleted); + + require_noerr(ortn, out); + require_action(ssl_state==kSSLConnected, out, ortn = -1); + require_action(peer_auth_received, out, ortn = -1); + + unsigned char obuf[100]; + + size_t len = sizeof(obuf); + size_t olen; + unsigned char *p = obuf; + + require_action(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, len, p), out, ortn = -1); + + while (len) { + require_noerr(ortn = SSLWrite(ctx, p, len, &olen), out); + len -= olen; + p += olen; + } + } else { + // just read. + unsigned char ibuf[100]; + + peer_auth_received = false; + + size_t len = sizeof(ibuf); + size_t olen; + unsigned char *p = ibuf; + while (len) { + ortn = SSLRead(ctx, p, len, &olen); + + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLPeerAuthCompleted) { + require_action(!peer_auth_received, out, ortn = -1); + peer_auth_received = true; + } else { + require_noerr(ortn, out); + } + + /* If we get data, we should have renegotiated */ + if(olen) { + require_noerr(ortn, out); + require_action(ssl_state==kSSLConnected, out, ortn = -1); + require_action(peer_auth_received, out, ortn = -1); + } + + len -= olen; + p += olen; + } + } + +out: + SSLClose(ssl->st); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + +typedef struct { + SSLContextRef st; + int comm; + CFArrayRef certs; + bool renegotiate; +} ssl_server_handle; + +static ssl_server_handle * +ssl_server_handle_create(int comm, CFArrayRef certs, bool renegotiate) +{ + ssl_server_handle *handle = calloc(1, sizeof(ssl_server_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType); + SSLCipherSuite cipher = TLS_RSA_WITH_AES_256_CBC_SHA256; + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + + require_noerr(SSLSetCertificate(ctx, certs), out); + + require_noerr(SSLSetEnabledCiphers(ctx, &cipher, 1), out); + + require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnClientHello, TRUE), out); + require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionAllowRenegotiation, TRUE), out); + + handle->comm = comm; + handle->certs = certs; + handle->st = ctx; + handle->renegotiate = renegotiate; + + return handle; + +out: + if (ctx) + CFRelease(ctx); + if (handle) + free(handle); + + return NULL; +} + +static void +ssl_server_handle_destroy(ssl_server_handle *handle) +{ + if(handle) { + SSLClose(handle->st); + CFRelease(handle->st); + free(handle); + } +} + +static void *securetransport_ssl_server_thread(void *arg) +{ + OSStatus ortn; + ssl_server_handle * ssl = (ssl_server_handle *)arg; + SSLContextRef ctx = ssl->st; + SSLSessionState ssl_state; + bool client_hello_received = false; + + pthread_setname_np("server thread"); + + require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); + require_action(ssl_state==kSSLIdle, out, ortn = -1); + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + if (ortn == errSSLClientHelloReceived) { + require_action(!client_hello_received, out, ortn = -1); + client_hello_received = true; + } + if (ortn == errSSLWouldBlock) { + require_action(ssl_state==kSSLHandshake, out, ortn = -1); + } + } while (ortn == errSSLWouldBlock || ortn == errSSLClientHelloReceived); + + require_noerr(ortn, out); + require_action(ssl_state==kSSLConnected, out, ortn = -1); + require_action(client_hello_received, out, ortn = -1); + + if(ssl->renegotiate) { + // Renegotiate then write + require_noerr(SSLReHandshake(ctx), out); + + client_hello_received = false; + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + if (ortn == errSSLClientHelloReceived) { + require_action(!client_hello_received, out, ortn = -1); + client_hello_received = true; + } + if (ortn == errSSLWouldBlock) { + require_action(ssl_state==kSSLHandshake, out, ortn = -1); + } + } while (ortn == errSSLWouldBlock || ortn == errSSLClientHelloReceived); + + require_noerr(ortn, out); + require_action(ssl_state==kSSLConnected, out, ortn = -1); + require_action(client_hello_received, out, ortn = -1); + + unsigned char obuf[100]; + + size_t len = sizeof(obuf); + size_t olen; + unsigned char *p = obuf; + + require_action(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, len, p), out, ortn = -1); + + while (len) { + require_noerr(ortn = SSLWrite(ctx, p, len, &olen), out); + len -= olen; + p += olen; + } + } else { + // just read + unsigned char ibuf[100]; + + client_hello_received = false; + + size_t len = sizeof(ibuf); + size_t olen; + unsigned char *p = ibuf; + while (len) { + ortn = SSLRead(ctx, p, len, &olen); + + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLClientHelloReceived) { + require_action(!client_hello_received, out, ortn = -1); + client_hello_received = true; + } else { + require_noerr(ortn, out); + } + + /* If we get data, we should have renegotiated */ + if(olen) { + require_noerr(ortn, out); + require_action(ssl_state==kSSLConnected, out, ortn = -1); + require_action(client_hello_received, out, ortn = -1); + } + + len -= olen; + p += olen; + } + } + +out: + SSLClose(ssl->st); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + +-(void) test_renego: (bool) client_renego +{ + pthread_t client_thread, server_thread; + CFArrayRef server_certs = server_chain(); + + XCTAssert(server_certs, "renego: got server certs"); + + + int sp[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno); + fcntl(sp[0], F_SETNOSIGPIPE, 1); + fcntl(sp[1], F_SETNOSIGPIPE, 1); + + ssl_client_handle *client; + client = ssl_client_handle_create(sp[0], client_renego); + XCTAssert(client!=NULL, "renego: could not create client handle"); + + + ssl_server_handle *server; + server = ssl_server_handle_create(sp[1], server_certs, !client_renego); + XCTAssert(server!=NULL, "renego: could not create server handle"); + + pthread_create(&client_thread, NULL, securetransport_ssl_client_thread, client); + pthread_create(&server_thread, NULL, securetransport_ssl_server_thread, server); + + intptr_t server_err, client_err; + + pthread_join(client_thread, (void*)&client_err); + pthread_join(server_thread, (void*)&server_err); + + XCTAssert(client_err==0, "renego: unexpected error %ld (client)", client_err); + XCTAssert(server_err==0, "renego: unexpected error %ld (server)", server_err); + + ssl_server_handle_destroy(server); + ssl_client_handle_destroy(client); + + + CFReleaseSafe(server_certs); +} + + +-(void) testRenegotiation +{ + + [self test_renego:false]; // server side trigger renego. + [self test_renego:true]; // client side trigger renego. + +} +@end + diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessioncache.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessioncache.m new file mode 100644 index 00000000..5d83e3c3 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessioncache.m @@ -0,0 +1,415 @@ + +#include +#include +#include +#include +#include + +#include + +#include +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#include "ssl-utils.h" +#import "STLegacyTests.h" + +@implementation STLegacyTests (sessioncache) + +/* + SSL Session Cache tests: + + Test both the client and server side. + + Test Goal: + - Make sure that resumption fails after session cache TTL. + + Behavior to verify: + - handshake pass or fail + +*/ + + +static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = write((int)conn, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = read((int)conn, ptr, len); + } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } else { + printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno); + return -errno; + } + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +typedef struct { + SSLContextRef st; + int comm; + unsigned dhe_size; +} ssl_client_handle; + +static ssl_client_handle * +ssl_client_handle_create(int comm, bool anyRoot, CFArrayRef trustedCA, bool trustedCAOnly, CFArrayRef trustedLeafs, uint32_t cache_ttl, uintptr_t peerID) +{ + ssl_client_handle *handle = calloc(1, sizeof(ssl_client_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType); + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + static const char *peer_domain_name = "localhost"; + require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name, + strlen(peer_domain_name)), out); + + require_noerr(SSLSetAllowsAnyRoot(ctx, anyRoot), out); + require_noerr(SSLSetTrustedRoots(ctx, trustedCA, trustedCAOnly), out); +#if !TARGET_OS_IPHONE + require_noerr(SSLSetTrustedLeafCertificates(ctx, trustedLeafs), out); +#endif + + require_noerr(SSLSetSessionCacheTimeout(ctx, cache_ttl), out); + + require_noerr(SSLSetPeerID(ctx, &peerID, sizeof(peerID)), out); + + handle->comm = comm; + handle->st = ctx; + + return handle; + +out: + if (ctx) + CFRelease(ctx); + if (handle) + free(handle); + + return NULL; +} + +static void +ssl_client_handle_destroy(ssl_client_handle *handle) +{ + if(handle) { + SSLClose(handle->st); + CFRelease(handle->st); + free(handle); + } +} + +static void *securetransport_ssl_client_thread(void *arg) +{ + OSStatus ortn; + ssl_client_handle * ssl = (ssl_client_handle *)arg; + SSLContextRef ctx = ssl->st; + SSLSessionState ssl_state; + + pthread_setname_np("client thread"); + + require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); + require_action(ssl_state==kSSLIdle, out, ortn = -1); + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLWouldBlock) { + require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock"); + } + } while (ortn == errSSLWouldBlock); + +out: + SSLClose(ssl->st); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + +typedef struct { + SSLContextRef st; + int comm; + CFArrayRef certs; + +} ssl_server_handle; + +static ssl_server_handle * +ssl_server_handle_create(int comm, CFArrayRef certs, uint32_t cache_ttl) +{ + ssl_server_handle *handle = calloc(1, sizeof(ssl_server_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType); + SSLCipherSuite cipher = TLS_RSA_WITH_AES_256_CBC_SHA256; + uintptr_t peerID = 0xdeadbeef; + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + + require_noerr(SSLSetCertificate(ctx, certs), out); + + require_noerr(SSLSetEnabledCiphers(ctx, &cipher, 1), out); + + require_noerr(SSLSetSessionCacheTimeout(ctx, cache_ttl), out); + + require_noerr(SSLSetPeerID(ctx, &peerID, sizeof(peerID)), out); + + handle->comm = comm; + handle->certs = certs; + handle->st = ctx; + + return handle; + +out: + if (ctx) + CFRelease(ctx); + if (handle) + free(handle); + + return NULL; +} + +static void +ssl_server_handle_destroy(ssl_server_handle *handle) +{ + if(handle) { + SSLClose(handle->st); + CFRelease(handle->st); + free(handle); + } +} + +static void *securetransport_ssl_server_thread(void *arg) +{ + OSStatus ortn; + ssl_server_handle * ssl = (ssl_server_handle *)arg; + SSLContextRef ctx = ssl->st; + SSLSessionState ssl_state; + + pthread_setname_np("server thread"); + + require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); + require_action(ssl_state==kSSLIdle, out, ortn = -1); + + do { + ortn = SSLHandshake(ctx); + require_noerr(SSLGetSessionState(ctx,&ssl_state), out); + + if (ortn == errSSLWouldBlock) { + require_action(ssl_state==kSSLHandshake, out, ortn = -1); + } + } while (ortn == errSSLWouldBlock); + + require_noerr_quiet(ortn, out); + + require_action(ssl_state==kSSLConnected, out, ortn = -1); + +out: + SSLClose(ssl->st); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + + +-(void)cache_ttl_test +{ + pthread_t client_thread, server_thread; + CFArrayRef server_certs = server_chain(); + CFArrayRef trusted_ca = trusted_roots(); + + XCTAssert(server_certs, "ttl: got server certs"); + XCTAssert(trusted_ca, "ttl: got trusted roots"); + + int i, j, k; + + for (i=0; i<2; i++) { // client cache TTL + for (j=0; j<2; j++) { // Server cache TTL + for (k=0; k<2; k++) { + ssl_client_handle *client = NULL; + ssl_server_handle *server = NULL; + + int sp[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno); + fcntl(sp[0], F_SETNOSIGPIPE, 1); + fcntl(sp[1], F_SETNOSIGPIPE, 1); + + client = ssl_client_handle_create(sp[0], false, trusted_ca, true, NULL, i, (i<<8)|(j+1)); + XCTAssert(client!=NULL, "ttl: could not create client handle (%d:%d:%d)", i, j, k); + require(client, errOut); + + server = ssl_server_handle_create(sp[1], server_certs, j); + XCTAssert(server!=NULL, "ttl: could not create server handle (%d:%d:%d)", i, j, k); + require(server, errOut); + pthread_create(&client_thread, NULL, securetransport_ssl_client_thread, client); + pthread_create(&server_thread, NULL, securetransport_ssl_server_thread, server); + + intptr_t server_err, client_err; + + pthread_join(client_thread, (void*)&client_err); + pthread_join(server_thread, (void*)&server_err); + + Boolean resumed; + unsigned char sessionID[32]; + size_t sessionIDLength = sizeof(sessionID); + + XCTAssertEqual(client_err, 0, "ttl: unexpected error %ld (client %d:%d:%d)", client_err, i, j, k); + XCTAssertEqual(server_err, 0, "ttl: unexpected error %ld (server %d:%d:%d)", server_err, i, j, k); + XCTAssertEqual(errSecSuccess, SSLGetResumableSessionInfo(client->st, &resumed, sessionID, &sessionIDLength), "SSLGetResumableSessionInfo"); + + XCTAssertEqual((bool)resumed, (bool)(k && (!i) && (!j)), "ttl: Unexpected resumption state=%d (%d:%d:%d)", resumed, i, j, k); + + errOut: + ssl_server_handle_destroy(server); + ssl_client_handle_destroy(client); + + /* Sleep two seconds so that Session cache TTL can expire */ + sleep(2); + } + } + } + + CFReleaseSafe(server_certs); + CFReleaseSafe(trusted_ca); +} + +-(void) cache_trust_test +{ + pthread_t client_thread, server_thread; + CFArrayRef server_certs = server_chain(); + CFArrayRef trusted_ca = trusted_roots(); + CFMutableArrayRef trusted_ca2 = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, trusted_ca); + CFArrayAppendArray(trusted_ca2, trusted_ca, CFRangeMake(0, CFArrayGetCount(trusted_ca))); + + XCTAssert(server_certs, "trust: got server certs"); + XCTAssert(trusted_ca, "trust: got trusted roots"); + XCTAssert(trusted_ca2, "trust: got trusted roots extra"); + + int any, ca, caonly, leaf, k; + + // Test cache and trust options: + + + for (any=0; any<2; any++) // any root ? + for (ca=0; ca<2; ca++) // trustedCA ? + for (caonly=0; caonly<2; caonly++) // leaf> +#if TARGET_OS_IPHONE + { + leaf = 0; +#else + for (leaf=0; leaf<2; leaf++) + { +#endif + // attempt initial connection, then resumed connection, but all with same peer id (0xdeadbeef) + for (k=0; k<2; k++) { + ssl_client_handle *client = NULL; + ssl_server_handle *server = NULL; + + int sp[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno); + fcntl(sp[0], F_SETNOSIGPIPE, 1); + fcntl(sp[1], F_SETNOSIGPIPE, 1); + + client = ssl_client_handle_create(sp[0], any, ca?trusted_ca:trusted_ca2, caonly, leaf?NULL:trusted_ca, 300, 0xdeadbeef); + XCTAssert(client!=NULL, "trust: could not create client handle (%d:%d:%d:%d:%d)", any, ca, caonly, leaf, k); + require(client, errOut); + + server = ssl_server_handle_create(sp[1], server_certs, 300); + XCTAssert(server!=NULL, "trust: could not create server handle (%d:%d:%d:%d:%d)", any, ca, caonly, leaf, k); + require(server, errOut); + + pthread_create(&client_thread, NULL, securetransport_ssl_client_thread, client); + pthread_create(&server_thread, NULL, securetransport_ssl_server_thread, server); + + intptr_t server_err, client_err; + + pthread_join(client_thread, (void*)&client_err); + pthread_join(server_thread, (void*)&server_err); + + Boolean resumed; + unsigned char sessionID[32]; + size_t sessionIDLength = sizeof(sessionID); + + XCTAssertEqual(client_err, 0, "trust: unexpected error %ld (client %d:%d:%d:%d:%d)", client_err, any, ca, caonly, leaf, k); + XCTAssertEqual(server_err, 0, "trust: unexpected error %ld (server %d:%d:%d:%d:%d)", server_err, any, ca, caonly, leaf, k); + XCTAssertEqual(errSecSuccess, SSLGetResumableSessionInfo(client->st, &resumed, sessionID, &sessionIDLength), "SSLGetResumableSessionInfo"); + + XCTAssertEqual((bool)resumed, (bool)(k), "trust: Unexpected resumption state=%d (%d:%d:%d:%d:%d)", resumed, any, ca, caonly, leaf, k); + + errOut: + ssl_server_handle_destroy(server); + ssl_client_handle_destroy(client); + + } + } + + CFReleaseSafe(server_certs); + CFReleaseSafe(trusted_ca); +} + +-(void) testSessionCache +{ + + [self cache_ttl_test]; + + [self cache_trust_test]; + +} +@end + diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessionstate.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessionstate.m new file mode 100644 index 00000000..3c60b055 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessionstate.m @@ -0,0 +1,492 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#include "ssl-utils.h" + +#include +#include +#include + +#include + +#import "STLegacyTests.h" + +@implementation STLegacyTests (sessionstate) + +#define test_printf(x...) + +/* extern struct ccrng_state *ccDRBGGetRngState(); */ +#include +#define CCRNGSTATE ccDRBGGetRngState() + +struct RecQueueItem { + STAILQ_ENTRY(RecQueueItem) next; /* link to next queued entry or NULL */ + tls_buffer record; + size_t offset; /* byte reads from this one */ +}; + +typedef struct { + SSLContextRef st; + tls_stream_parser_t parser; + tls_record_t record; + tls_handshake_t hdsk; + STAILQ_HEAD(, RecQueueItem) rec_queue; // coretls server queue packet in this queue + int ready_count; +} ssl_test_handle; + + +static +int tls_buffer_alloc(tls_buffer *buf, size_t length) +{ + buf->data = malloc(length); + if(!buf->data) return -ENOMEM; + buf->length = length; + return 0; +} + +static +int tls_buffer_free(tls_buffer *buf) +{ + free(buf->data); + buf->data = NULL; + buf->length = 0; + return 0; +} + +#pragma mark - +#pragma mark SecureTransport support + +#if 0 +static void hexdump(const char *s, const uint8_t *bytes, size_t len) { + size_t ix; + printf("socket %s(%p, %lu)\n", s, bytes, len); + for (ix = 0; ix < len; ++ix) { + if (!(ix % 16)) + printf("\n"); + printf("%02X ", bytes[ix]); + } + printf("\n"); +} +#else +#define hexdump(string, bytes, len) +#endif + +static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length) +{ + ssl_test_handle *handle =(ssl_test_handle *)h; + + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + tls_buffer buffer; + buffer.data = ptr; + buffer.length = len; + return tls_stream_parser_parse(handle->parser, buffer); +} + +static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length) +{ + ssl_test_handle *handle =(ssl_test_handle *)h; + + test_printf("%s: %p requesting len=%zd\n", __FUNCTION__, h, *length); + + struct RecQueueItem *item = STAILQ_FIRST(&handle->rec_queue); + + if(item==NULL) { + test_printf("%s: %p no data available\n", __FUNCTION__, h); + return errSSLWouldBlock; + } + + size_t avail = item->record.length - item->offset; + + test_printf("%s: %p %zd bytes available in %p\n", __FUNCTION__, h, avail, item); + + if(avail > *length) { + memcpy(data, item->record.data+item->offset, *length); + item->offset += *length; + } else { + memcpy(data, item->record.data+item->offset, avail); + *length = avail; + STAILQ_REMOVE_HEAD(&handle->rec_queue, next); + tls_buffer_free(&item->record); + free(item); + } + + test_printf("%s: %p %zd bytes read\n", __FUNCTION__, h, *length); + + + return 0; +} + +static int process(tls_stream_parser_ctx_t ctx, tls_buffer record) +{ + ssl_test_handle *h = (ssl_test_handle *)ctx; + tls_buffer decrypted; + uint8_t ct; + int err; + + test_printf("%s: %p processing %zd bytes\n", __FUNCTION__, ctx, record.length); + + + decrypted.length = tls_record_decrypted_size(h->record, record.length); + decrypted.data = malloc(decrypted.length); + + require_action(decrypted.data, errOut, err=-ENOMEM); + require_noerr((err=tls_record_decrypt(h->record, record, &decrypted, &ct)), errOut); + + test_printf("%s: %p decrypted %zd bytes, ct=%d\n", __FUNCTION__, ctx, decrypted.length, ct); + + err=tls_handshake_process(h->hdsk, decrypted, ct); + + test_printf("%s: %p processed, err=%d\n", __FUNCTION__, ctx, err); + +errOut: + free(decrypted.data); + return err; +} + +static int +tls_handshake_write_callback(tls_handshake_ctx_t ctx, const tls_buffer data, uint8_t content_type) +{ + int err = 0; + ssl_test_handle *handle = (ssl_test_handle *)ctx; + + test_printf("%s: %p writing data ct=%d, len=%zd\n", __FUNCTION__, ctx, content_type, data.length); + + struct RecQueueItem *item = malloc(sizeof(struct RecQueueItem)); + require_action(item, errOut, err=-ENOMEM); + + err=tls_buffer_alloc(&item->record, tls_record_encrypted_size(handle->record, content_type, data.length)); + require_noerr(err, errOut); + + err=tls_record_encrypt(handle->record, data, content_type, &item->record); + require_noerr(err, errOut); + + item->offset = 0; + + test_printf("%s: %p queing %zd encrypted bytes, item=%p\n", __FUNCTION__, ctx, item->record.length, item); + + STAILQ_INSERT_TAIL(&handle->rec_queue, item, next); + + return 0; + +errOut: + if(item) { + tls_buffer_free(&item->record); + free(item); + } + return err; +} + + +static int +tls_handshake_message_callback(tls_handshake_ctx_t ctx, tls_handshake_message_t event) +{ + ssl_test_handle __unused *handle = (ssl_test_handle *)ctx; + + test_printf("%s: %p event = %d\n", __FUNCTION__, handle, event); + + int err = 0; + + return err; +} + + + +static uint8_t appdata[] = "appdata"; + +tls_buffer appdata_buffer = { + .data = appdata, + .length = sizeof(appdata), +}; + + +static void +tls_handshake_ready_callback(tls_handshake_ctx_t ctx, bool write, bool ready) +{ + ssl_test_handle *handle = (ssl_test_handle *)ctx; + + test_printf("%s: %p %s ready=%d\n", __FUNCTION__, handle, write?"write":"read", ready); + + if(ready) { + if(write) { + if(handle->ready_count == 0) { + tls_handshake_request_renegotiation(handle->hdsk); + } else { + tls_handshake_write_callback(ctx, appdata_buffer, tls_record_type_AppData); + } + handle->ready_count++;; + } + } +} + +static int +tls_handshake_set_retransmit_timer_callback(tls_handshake_ctx_t ctx, int attempt) +{ + ssl_test_handle __unused *handle = (ssl_test_handle *)ctx; + + test_printf("%s: %p attempt = %d\n", __FUNCTION__, handle, attempt); + + return -1; +} + +static +int mySSLRecordInitPendingCiphersFunc(tls_handshake_ctx_t ref, + uint16_t selectedCipher, + bool server, + tls_buffer key) +{ + ssl_test_handle *handle = (ssl_test_handle *)ref; + + test_printf("%s: %p, cipher=%04x, server=%d\n", __FUNCTION__, ref, selectedCipher, server); + return tls_record_init_pending_ciphers(handle->record, selectedCipher, server, key); +} + +static +int mySSLRecordAdvanceWriteCipherFunc(tls_handshake_ctx_t ref) +{ + ssl_test_handle *handle = (ssl_test_handle *)ref; + test_printf("%s: %p\n", __FUNCTION__, ref); + return tls_record_advance_write_cipher(handle->record); +} + +static +int mySSLRecordRollbackWriteCipherFunc(tls_handshake_ctx_t ref) +{ + ssl_test_handle *handle = (ssl_test_handle *)ref; + test_printf("%s: %p\n", __FUNCTION__, ref); + return tls_record_rollback_write_cipher(handle->record); +} + +static +int mySSLRecordAdvanceReadCipherFunc(tls_handshake_ctx_t ref) +{ + ssl_test_handle *handle = (ssl_test_handle *)ref; + test_printf("%s: %p\n", __FUNCTION__, ref); + return tls_record_advance_read_cipher(handle->record); +} + +static +int mySSLRecordSetProtocolVersionFunc(tls_handshake_ctx_t ref, + tls_protocol_version protocolVersion) +{ + ssl_test_handle *handle = (ssl_test_handle *)ref; + test_printf("%s: %p, version=%04x\n", __FUNCTION__, ref, protocolVersion); + return tls_record_set_protocol_version(handle->record, protocolVersion); +} + + +static int +tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx, tls_buffer sessionKey, tls_buffer sessionData) +{ + ssl_test_handle __unused *handle = (ssl_test_handle *)ctx; + + test_printf("%s: %p\n", __FUNCTION__, handle); + + return -1; +} + +static int +tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx, tls_buffer sessionKey, tls_buffer *sessionData) +{ + ssl_test_handle __unused *handle = (ssl_test_handle *)ctx; + + test_printf("%s: %p\n", __FUNCTION__, handle); + + return -1; +} + +static int +tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx, tls_buffer sessionKey) +{ + ssl_test_handle __unused *handle = (ssl_test_handle *)ctx; + + test_printf("%s: %p\n", __FUNCTION__, handle); + + return -1; +} + +static int +tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx) +{ + ssl_test_handle __unused *handle = (ssl_test_handle *)ctx; + + test_printf("%s: %p\n", __FUNCTION__, handle); + + return -1; +} + +/* TLS callbacks */ +tls_handshake_callbacks_t myTLS_handshake_callbacks = { + .write = tls_handshake_write_callback, + .message = tls_handshake_message_callback, + .ready = tls_handshake_ready_callback, + .set_retransmit_timer = tls_handshake_set_retransmit_timer_callback, + .init_pending_cipher = mySSLRecordInitPendingCiphersFunc, + .advance_write_cipher = mySSLRecordAdvanceWriteCipherFunc, + .rollback_write_cipher = mySSLRecordRollbackWriteCipherFunc, + .advance_read_cipher = mySSLRecordAdvanceReadCipherFunc, + .set_protocol_version = mySSLRecordSetProtocolVersionFunc, + .load_session_data = tls_handshake_load_session_data_callback, + .save_session_data = tls_handshake_save_session_data_callback, + .delete_session_data = tls_handshake_delete_session_data_callback, + .delete_all_sessions = tls_handshake_delete_all_sessions_callback, +}; + + +static void +ssl_test_handle_destroy(ssl_test_handle *handle) +{ + if(handle) { + if(handle->parser) tls_stream_parser_destroy(handle->parser); + if(handle->record) tls_record_destroy(handle->record); + if(handle->hdsk) tls_handshake_destroy(handle->hdsk); + if(handle->st) CFRelease(handle->st); + free(handle); + } +} + +static uint16_t ciphers[] = { + TLS_PSK_WITH_AES_128_CBC_SHA, +}; +static int nciphers = sizeof(ciphers)/sizeof(ciphers[0]); + +static SSLCipherSuite ciphersuites[] = { + TLS_PSK_WITH_AES_128_CBC_SHA, +}; +static int nciphersuites = sizeof(ciphersuites)/sizeof(ciphersuites[0]); + + + +static uint8_t shared_secret[] = "secret"; + +tls_buffer psk_secret = { + .data = shared_secret, + .length = sizeof(shared_secret), +}; + +static ssl_test_handle * +ssl_test_handle_create(bool server) +{ + ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType); + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out); + require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true), out); + require_noerr(SSLSetEnabledCiphers(ctx, ciphersuites, nciphersuites), out); + require_noerr(SSLSetPSKSharedSecret(ctx, shared_secret, sizeof(shared_secret)), out); + + handle->st = ctx; + handle->parser = tls_stream_parser_create(handle, process); + handle->record = tls_record_create(false, CCRNGSTATE); + handle->hdsk = tls_handshake_create(false, true); // server. + + require_noerr(tls_handshake_set_ciphersuites(handle->hdsk, ciphers, nciphers), out); + require_noerr(tls_handshake_set_callbacks(handle->hdsk, &myTLS_handshake_callbacks, handle), out); + require_noerr(tls_handshake_set_psk_secret(handle->hdsk, &psk_secret), out); + require_noerr(tls_handshake_set_renegotiation(handle->hdsk, true), out); + + // Initialize the record queue + STAILQ_INIT(&handle->rec_queue); + + return handle; + +out: + if (handle) free(handle); + if (ctx) CFRelease(ctx); + return NULL; +} + +-(void)testSessionState +{ + OSStatus ortn; + + ssl_test_handle *client; + SSLSessionState state; + + client = ssl_test_handle_create(false); + + require_action(client, out, ortn = -1); + + ortn = SSLGetSessionState(client->st, &state); + require_noerr(ortn, out); + XCTAssertEqual(state, kSSLIdle, "State should be Idle"); + + do { + ortn = SSLHandshake(client->st); + test_printf("SSLHandshake returned err=%d\n", (int)ortn); + + require_noerr(SSLGetSessionState(client->st, &state), out); + + if (ortn == errSSLPeerAuthCompleted || ortn == errSSLWouldBlock) + { + require_action(state==kSSLHandshake, out, ortn = -1); + } + + } while(ortn==errSSLWouldBlock || + ortn==errSSLPeerAuthCompleted); + + + XCTAssertEqual(ortn, 0, "Unexpected SSLHandshake exit code"); + XCTAssertEqual(state, kSSLConnected, "State should be Connected"); + + uint8_t buffer[128]; + size_t available = 0; + + test_printf("Initial handshake done\n"); + + do { + ortn = SSLRead(client->st, buffer, sizeof(buffer), &available); + test_printf("SSLRead returned err=%d, avail=%zd\n", (int)ortn, available); + require_noerr(SSLGetSessionState(client->st, &state), out); + + if (ortn == errSSLPeerAuthCompleted) + { + require_action(state==kSSLHandshake, out, ortn = -1); + } + + } while(available==0); + + XCTAssertEqual(ortn, 0, "Unexpected SSLRead exit code"); + XCTAssertEqual(state, kSSLConnected, "State should be Connected"); + + +out: + XCTAssertEqual(ortn, 0, "Final result is non zero"); + ssl_test_handle_destroy(client); + +} + +@end diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sni.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sni.m new file mode 100644 index 00000000..5a55ea82 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sni.m @@ -0,0 +1,267 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#include "ssl-utils.h" +#import "STLegacyTests.h" + +@implementation STLegacyTests (sni) + +typedef struct { + SSLContextRef handle; + uint32_t session_id; + bool is_server; + int comm; +} ssl_test_handle; + + +#pragma mark - +#pragma mark SecureTransport support + +#if 0 +static void hexdump(const uint8_t *bytes, size_t len) { + size_t ix; + printf("socket write(%p, %lu)\n", bytes, len); + for (ix = 0; ix < len; ++ix) { + if (!(ix % 16)) + printf("\n"); + printf("%02X ", bytes[ix]); + } + printf("\n"); +} +#else +#define hexdump(bytes, len) +#endif + + +static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + hexdump(ptr, len); + ret = write((int)h, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = read((int)h, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } else { + printf("read error(%d): ret=%zd, errno=%d\n", (int)h, ret, errno); + return -errno; + } + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static char peername[] = "localhost"; + +static void *securetransport_server_thread(void *arg) +{ + OSStatus ortn; + ssl_test_handle * ssl = (ssl_test_handle *)arg; + SSLContextRef ctx = ssl->handle; + CFArrayRef server_certs = server_chain(); + + do { + ortn = SSLHandshake(ctx); + } while (ortn == errSSLWouldBlock); + + ok(ortn==errSSLClientHelloReceived, "Unexpected Handshake exit code"); + + if (ortn == errSSLClientHelloReceived) { + char *sni = NULL; + size_t length = 0; + SSLCopyRequestedPeerNameLength(ctx, &length); + if (length > 0) { + sni = malloc(length); + SSLCopyRequestedPeerName(ctx, sni, &length); + } + + SSLProtocol version = 0; + require_noerr(SSLGetProtocolVersionMax(ctx, &version), out); + if (version == kSSLProtocol3) { + ok(sni==NULL, "Unexpected SNI"); + } else { + ok(sni!=NULL && + length == sizeof(peername) && + (memcmp(sni, peername, sizeof(peername))==0), + "SNI does not match"); + } + require_noerr(SSLSetCertificate(ctx, server_certs), out); + free(sni); + } + +out: + SSLClose(ctx); + SSLDisposeContext(ctx); + close(ssl->comm); + CFReleaseSafe(server_certs); + + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + +static void *securetransport_client_thread(void *arg) +{ + OSStatus ortn; + ssl_test_handle * ssl = (ssl_test_handle *)arg; + SSLContextRef ctx = ssl->handle; + + do { + ortn = SSLHandshake(ctx); + } while (ortn == errSSLWouldBlock || ortn != errSSLClosedGraceful); + + SSLClose(ctx); + SSLDisposeContext(ctx); + close(ssl->comm); + + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + +static SSLCipherSuite ciphers[] = { + TLS_RSA_WITH_AES_128_CBC_SHA, +}; + +static ssl_test_handle * +ssl_test_handle_create(uint32_t session_id, bool server, int comm) +{ + ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType); + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + + if (server) + require_noerr(SSLSetSessionOption(ctx, + kSSLSessionOptionBreakOnClientHello, true), out); + else + require_noerr(SSLSetSessionOption(ctx, + kSSLSessionOptionBreakOnServerAuth, true), out); + + /* Tell SecureTransport to not check certs itself: it will break out of the + handshake to let us take care of it instead. */ + require_noerr(SSLSetEnableCertVerify(ctx, false), out); + + handle->handle = ctx; + handle->is_server = server; + handle->session_id = session_id; + handle->comm = comm; + + return handle; + +out: + if (handle) free(handle); + if (ctx) CFRelease(ctx); + return NULL; +} + +static SSLProtocol versions[] = { + kSSLProtocol3, + kTLSProtocol1, + kTLSProtocol11, + kTLSProtocol12, +}; +static int nversions = sizeof(versions)/sizeof(versions[0]); + +-(void)testSNI +{ + int j; + pthread_t client_thread, server_thread; + + for(j=0; jhandle, &session_id, sizeof(session_id)), out); + require_noerr(SSLSetPeerID(client->handle, &session_id, sizeof(session_id)), out); + + /* set fixed cipher on client and server */ + require_noerr(SSLSetEnabledCiphers(client->handle, &ciphers[0], 1), out); + require_noerr(SSLSetEnabledCiphers(server->handle, &ciphers[0], 1), out); + + require_noerr(SSLSetProtocolVersionMax(client->handle, versions[j]), out); + require_noerr(SSLSetPeerDomainName(client->handle, peername, sizeof(peername)), out); + + require_noerr(SSLSetProtocolVersionMax(server->handle, versions[j]), out); + + pthread_create(&client_thread, NULL, securetransport_client_thread, client); + pthread_create(&server_thread, NULL, securetransport_server_thread, server); + + intptr_t server_err, client_err; + pthread_join(client_thread, (void*)&client_err); + pthread_join(server_thread, (void*)&server_err); + + out: + free(client); + free(server); + + } +} + +@end diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+split.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+split.m new file mode 100644 index 00000000..52aaca2c --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+split.m @@ -0,0 +1,339 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE +#include +#endif + +#include "ssl-utils.h" + +#include +#import "STLegacyTests.h" + +@implementation STLegacyTests (split) + +typedef struct { + SSLContextRef st; + bool is_server; + int comm; + CFArrayRef certs; + int write_counter; + tls_stream_parser_t parser; + size_t write_size; +} ssl_test_handle; + + +#pragma mark - +#pragma mark SecureTransport support + +#if 0 +static void hexdump(const char *s, const uint8_t *bytes, size_t len) { + size_t ix; + printf("socket %s(%p, %lu)\n", s, bytes, len); + for (ix = 0; ix < len; ++ix) { + if (!(ix % 16)) + printf("\n"); + printf("%02X ", bytes[ix]); + } + printf("\n"); +} +#else +#define hexdump(string, bytes, len) +#endif + +static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length) +{ + ssl_test_handle *handle =(ssl_test_handle *)h; + int conn = handle->comm; + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + if(handle->is_server) { + //printf("SocketWrite: server write len=%zd\n", len); + + tls_buffer buffer; + buffer.data = ptr; + buffer.length = len; + tls_stream_parser_parse(handle->parser, buffer); + } + + do { + ssize_t ret; + do { + hexdump("write", ptr, len); + ret = write((int)conn, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length) +{ + const ssl_test_handle *handle=h; + int conn = handle->comm; + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + + do { + ssize_t ret; + do { + ret = read((int)conn, ptr, len); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + if(len!=0) + printf("Something went wrong here... len=%d\n", (int)len); + + *length = *length - len; + return errSecSuccess; +} + +static int process(tls_stream_parser_ctx_t ctx, tls_buffer record) +{ + ssl_test_handle *handle = (ssl_test_handle *)ctx; + + // printf("processing record len=%zd, type=%d\n", record.length, record.data[0]); + if(record.data[0]==tls_record_type_AppData) { + handle->write_counter++; + // printf("record count = %d\n", handle->write_counter); + } + + return 0; +} + + +static void *securetransport_ssl_thread(void *arg) +{ + OSStatus ortn; + ssl_test_handle * ssl = (ssl_test_handle *)arg; + SSLContextRef ctx = ssl->st; + bool got_server_auth = false; + + //uint64_t start = mach_absolute_time(); + do { + ortn = SSLHandshake(ctx); + + if (ortn == errSSLServerAuthCompleted) + { + require_string(!got_server_auth, out, "second server auth"); + got_server_auth = true; + } + } while (ortn == errSSLWouldBlock + || ortn == errSSLServerAuthCompleted); + + require_noerr_action_quiet(ortn, out, + fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn)); + + unsigned char ibuf[90000], obuf[45000]; + + if (ssl->is_server) { + size_t len; + require_action(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, ssl->write_size, obuf), out, ortn = -1); + require_noerr(ortn = SSLWrite(ctx, obuf, ssl->write_size, &len), out); + require_action(len == ssl->write_size, out, ortn = -1); + require_noerr(ortn = SSLWrite(ctx, obuf, ssl->write_size, &len), out); + require_action(len == ssl->write_size, out, ortn = -1); + } else { + size_t len = ssl->write_size*2; + size_t olen; + unsigned char *p = ibuf; + while (len) { + require_noerr(ortn = SSLRead(ctx, p, len, &olen), out); + len -= olen; + p += olen; + } + } + +out: + SSLClose(ctx); + CFRelease(ctx); + close(ssl->comm); + pthread_exit((void *)(intptr_t)ortn); + return NULL; +} + +static void +ssl_test_handle_destroy(ssl_test_handle *handle) +{ + if(handle) { + if(handle->parser) tls_stream_parser_destroy(handle->parser); + free(handle); + } +} + +static ssl_test_handle * +ssl_test_handle_create(bool server, int comm, CFArrayRef certs) +{ + ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle)); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType); + + require(handle, out); + require(ctx, out); + + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out); + + if (server) + require_noerr(SSLSetCertificate(ctx, certs), out); + + require_noerr(SSLSetSessionOption(ctx, + kSSLSessionOptionBreakOnServerAuth, true), out); + + /* Tell SecureTransport to not check certs itself: it will break out of the + handshake to let us take care of it instead. */ + require_noerr(SSLSetEnableCertVerify(ctx, false), out); + + handle->is_server = server; + handle->comm = comm; + handle->certs = certs; + handle->st = ctx; + handle->write_counter = 0; + handle->parser = tls_stream_parser_create(handle, process); + + return handle; + +out: + if (handle) free(handle); + if (ctx) CFRelease(ctx); + return NULL; +} + +static SSLCipherSuite ciphers[] = { + TLS_RSA_WITH_AES_128_CBC_SHA, +}; +static int nciphers = sizeof(ciphers)/sizeof(ciphers[0]); + +static SSLProtocol versions[] = { + kSSLProtocol3, + kTLSProtocol1, + kTLSProtocol11, + kTLSProtocol12, +}; +static int nversions = sizeof(versions)/sizeof(versions[0]); + +// { write size, expected count when nosplit, expected count when split } +static size_t wsizes[][3] = { + { 1, 2, 2 }, + { 2, 2, 3 }, + { 3, 2, 3 }, + { 4, 2, 3 }, + { 16384, 2, 3 }, + { 16385, 4, 4 }, + { 16386, 4, 5 }, + { 16387, 4, 5 }, + { 16388, 4, 5 }, + { 32768, 4, 5 }, + { 32769, 6, 6 }, + { 32770, 6, 7 }, + { 32771, 6, 7 }, + { 32772, 6, 7 }, +}; +static int nwsizes = sizeof(wsizes)/sizeof(wsizes[0]); + +-(void) testSplit +{ + pthread_t client_thread, server_thread; + CFArrayRef server_certs = server_chain(); + XCTAssert(server_certs, "got server certs"); + + int i,j,k,s; + + for(i=0; iwrite_size = wsizes[k][0]; + client->write_size = wsizes[k][0]; + + require(client, out); + require(server, out); + + require_noerr(SSLSetProtocolVersionMin(server->st, kSSLProtocol3), out); // We need this server to do SSL3. + require_noerr(SSLSetProtocolVersionMax(client->st, versions[j]), out); + require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i], 1), out); + if(s) { + // s=0: default (should be enabled) + // s=1: explicit enable + // s=2: expliciti disable + require_noerr(SSLSetSessionOption(server->st, kSSLSessionOptionSendOneByteRecord, (s==1)?true:false), out); + } + // printf("**** Test Case: i=%d, j=%d, k=%d (%zd), s=%d ****\n", i, j, k, wsizes[k][0], s); + + pthread_create(&client_thread, NULL, securetransport_ssl_thread, client); + pthread_create(&server_thread, NULL, securetransport_ssl_thread, server); + + intptr_t server_err, client_err; + pthread_join(client_thread, (void*)&client_err); + pthread_join(server_thread, (void*)&server_err); + + XCTAssert(!server_err, "Server error = %ld", server_err); + XCTAssert(!client_err, "Client error = %ld", client_err); + + /* one byte split is expected only for AES when using TLS 1.0 or lower, and when not disabled */ + bool expected_split = (i==0) && (s!=2) && (versions[j]<=kTLSProtocol1); + int expected_count = (int)(expected_split ? wsizes[k][2]: wsizes[k][1]); + + XCTAssertEqual(server->write_counter, expected_count, "wrong number of data records"); + + // fprintf(stderr, "Server write counter = %d, expected %d\n", server->write_counter, expected_count); + +out: + ssl_test_handle_destroy(client); + ssl_test_handle_destroy(server); + + } + CFReleaseNull(server_certs); +} + +@end diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sslciphers.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sslciphers.m new file mode 100644 index 00000000..b41ae22c --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sslciphers.m @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2012,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@ + */ + + +#include +#include +#include +#include + +#include "ssl-utils.h" + + +#include "cipherSpecs.h" +#import "STLegacyTests.h" + +@implementation STLegacyTests (sslciphers) + +static int test_GetSupportedCiphers(SSLContextRef ssl, bool server) +{ + size_t max_ciphers = 0; + int fail=1; + SSLCipherSuite *ciphers = NULL; + + require_noerr(SSLGetNumberSupportedCiphers(ssl, &max_ciphers), out); + + size_t size = max_ciphers * sizeof (SSLCipherSuite); + ciphers = (SSLCipherSuite *) malloc(size); + + require_string(ciphers, out, "out of memory"); + memset(ciphers, 0xff, size); + + size_t num_ciphers = max_ciphers; + require_noerr(SSLGetSupportedCiphers(ssl, ciphers, &num_ciphers), out); + + for (size_t i = 0; i < num_ciphers; i++) { + require(ciphers[i]!=(SSLCipherSuite)(-1), out); + } + + /* Success! */ + fail=0; + +out: + if(ciphers) free(ciphers); + return fail; +} + + +static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length) +{ + return errSSLWouldBlock; +} + +static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) +{ + return errSSLWouldBlock; +} + + + +static const SSLCipherSuite legacy_ciphersuites[] = { + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_RSA_WITH_AES_256_GCM_SHA384, + TLS_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + SSL_RSA_WITH_3DES_EDE_CBC_SHA, +}; + +const SSLCipherSuite legacy_DHE_ciphersuites[] = { + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_RSA_WITH_AES_256_GCM_SHA384, + TLS_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + SSL_RSA_WITH_3DES_EDE_CBC_SHA, +}; + + + +const SSLCipherSuite standard_ciphersuites[] = { + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_RSA_WITH_AES_256_GCM_SHA384, + TLS_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, +}; + +const SSLCipherSuite default_ciphersuites[] = { + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_RSA_WITH_AES_256_GCM_SHA384, + TLS_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + SSL_RSA_WITH_3DES_EDE_CBC_SHA, +}; + +const SSLCipherSuite ATSv1_ciphersuites[] = { + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, +}; + +const SSLCipherSuite ATSv1_noPFS_ciphersuites[] = { + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + + TLS_RSA_WITH_AES_256_GCM_SHA384, + TLS_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, +}; + +const SSLCipherSuite TLSv1_RC4_fallback_ciphersuites[] = { + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + SSL_RSA_WITH_3DES_EDE_CBC_SHA, +}; + +const SSLCipherSuite TLSv1_fallback_ciphersuites[] = { + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + SSL_RSA_WITH_3DES_EDE_CBC_SHA, +}; + +const SSLCipherSuite anonymous_ciphersuites[] = { + TLS_ECDH_anon_WITH_AES_256_CBC_SHA, + TLS_ECDH_anon_WITH_AES_128_CBC_SHA, + TLS_DH_anon_WITH_AES_256_CBC_SHA256, + TLS_DH_anon_WITH_AES_256_CBC_SHA, + TLS_DH_anon_WITH_AES_128_CBC_SHA256, + TLS_DH_anon_WITH_AES_128_CBC_SHA +}; + + +static int test_GetEnabledCiphers(SSLContextRef ssl, unsigned expected_num_ciphers, const SSLCipherSuite *expected_ciphers) +{ + size_t num_ciphers; + size_t size; + int fail=1; + SSLCipherSuite *ciphers = NULL; + + require_noerr(SSLSetIOFuncs(ssl, &SocketRead, &SocketWrite), out); + require_noerr(SSLSetConnection(ssl, NULL), out); + + require_noerr(SSLGetNumberEnabledCiphers(ssl, &num_ciphers), out); + require_string(num_ciphers==expected_num_ciphers, out, "wrong ciphersuites number"); + + size = num_ciphers * sizeof (SSLCipherSuite); + ciphers = (SSLCipherSuite *) malloc(size); + require_string(ciphers, out, "out of memory"); + memset(ciphers, 0xff, size); + + require_noerr(SSLGetEnabledCiphers(ssl, ciphers, &num_ciphers), out); + require_string(memcmp(ciphers, expected_ciphers, size)==0, out, "wrong ciphersuites"); + + free(ciphers); + ciphers = NULL; + + require(SSLHandshake(ssl) == errSSLWouldBlock, out); + + require_noerr(SSLGetNumberEnabledCiphers(ssl, &num_ciphers), out); + require_string(num_ciphers==expected_num_ciphers, out, "wrong ciphersuites number"); + + size = num_ciphers * sizeof (SSLCipherSuite); + ciphers = (SSLCipherSuite *) malloc(size); + require_string(ciphers, out, "out of memory"); + memset(ciphers, 0xff, size); + + require_noerr(SSLGetEnabledCiphers(ssl, ciphers, &num_ciphers), out); + require_string(memcmp(ciphers, expected_ciphers, size)==0, out, "wrong ciphersuites"); + + /* Success! */ + fail=0; + +out: + free(ciphers); + return fail; +} + +static int test_SetEnabledCiphers(SSLContextRef ssl) +{ + int fail=1; + size_t num_enabled; + + /* This should not fail as long as we have one valid cipher in this table */ + SSLCipherSuite ciphers[] = { + SSL_RSA_WITH_RC2_CBC_MD5, /* unsupported */ + TLS_RSA_WITH_NULL_SHA, /* supported by not enabled by default */ + TLS_RSA_WITH_AES_128_CBC_SHA, /* Supported and enabled by default */ + }; + + require_noerr(SSLSetEnabledCiphers(ssl, ciphers, sizeof(ciphers)/sizeof(SSLCipherSuite)), out); + require_noerr(SSLGetNumberEnabledCiphers(ssl, &num_enabled), out); + + require(num_enabled==2, out); /* 2 ciphers in the above table are supported */ + + /* Success! */ + fail=0; + +out: + return fail; +} + + +- (void)test_dhe: (SSLProtocolSide) side dhe_enabled: (bool) dhe_enabled +{ + SSLContextRef ssl = NULL; + bool server = (side == kSSLServerSide); + + ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType); + XCTAssert(ssl != NULL, "test_dhe: SSLCreateContext(1) failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled"); + require(ssl, out); + + XCTAssertEqual(noErr, SSLSetDHEEnabled(ssl, dhe_enabled),"test_dhe: SSLSetDHEEnabled failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled"); + + unsigned num = (dhe_enabled?sizeof(legacy_DHE_ciphersuites):sizeof(legacy_ciphersuites))/sizeof(SSLCipherSuite); + const SSLCipherSuite *ciphers = dhe_enabled?legacy_DHE_ciphersuites:legacy_ciphersuites; + /* The order of this tests does matter, be careful when adding tests */ + XCTAssert(!test_GetSupportedCiphers(ssl, server), "test_dhe: GetSupportedCiphers test failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled"); + XCTAssert(!test_GetEnabledCiphers(ssl, num, ciphers), "test_dhe: GetEnabledCiphers test failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled"); + + CFRelease(ssl); ssl=NULL; + + ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType); + XCTAssert(ssl, "test_dhe: SSLCreateContext(2) failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled"); + require(ssl, out); + + XCTAssert(!test_SetEnabledCiphers(ssl), "test_dhe: SetEnabledCiphers test failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled"); + +out: + if(ssl) CFRelease(ssl); +} + +-(void) test_config: (SSLProtocolSide) side config: (CFStringRef) config num: (unsigned) num cipherList: (const SSLCipherSuite*) ciphers +{ + SSLContextRef ssl = NULL; + bool server = (side == kSSLServerSide); + + ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType); + XCTAssert(ssl, "test_config: SSLCreateContext(1) failed (%s,%@)", server?"server":"client", config); + require(ssl, out); + + XCTAssertEqual(errSecSuccess, SSLSetSessionConfig(ssl, config), "test_config: SSLSetSessionConfig failed (%s,%@)", server?"server":"client", config); + + /* The order of this tests does matter, be careful when adding tests */ + XCTAssert(!test_GetSupportedCiphers(ssl, server), "test_config: GetSupportedCiphers test failed (%s,%@)", server?"server":"client", config); + XCTAssert(!test_GetEnabledCiphers(ssl, num, ciphers), "test_config: GetEnabledCiphers test failed (%s,%@)", server?"server":"client", config); + + CFRelease(ssl); ssl=NULL; + + ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType); + XCTAssert(ssl, "test_config: SSLCreateContext(2) failed (%s,%@)", server?"server":"client", config); + require(ssl, out); + + XCTAssert(!test_SetEnabledCiphers(ssl), "test_config: SetEnabledCiphers test failed (%s,%@)", server?"server":"client", config); + +out: + if(ssl) CFRelease(ssl); +} + +-(void) test_default: (SSLProtocolSide) side +{ + SSLContextRef ssl = NULL; + bool server = (side == kSSLServerSide); + + ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType); + XCTAssert(ssl!=NULL, "test_config: SSLCreateContext(1) failed (%s)", server?"server":"client"); + require(ssl, out); + + /* The order of this tests does matter, be careful when adding tests */ + XCTAssert(!test_GetSupportedCiphers(ssl, server), "test_default: GetSupportedCiphers test failed (%s)", server?"server":"client"); + XCTAssert(!test_GetEnabledCiphers(ssl, sizeof(default_ciphersuites)/sizeof(SSLCipherSuite), default_ciphersuites), "test_default: GetEnabledCiphers test failed (%s)", server?"server":"client"); + + CFRelease(ssl); ssl=NULL; + + ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType); + XCTAssert(ssl, "test_default: SSLCreateContext(2) failed (%s)", server?"server":"client"); + require(ssl, out); + + XCTAssert(!test_SetEnabledCiphers(ssl), "test_config: SetEnabledCiphers test failed (%s)", server?"server":"client"); + +out: + if(ssl) CFRelease(ssl); +} + + + + +-(void) testSSLCiphers +{ + [self test_dhe:kSSLClientSide dhe_enabled:true]; + [self test_dhe:kSSLServerSide dhe_enabled:true]; + [self test_dhe:kSSLClientSide dhe_enabled:false]; + [self test_dhe:kSSLServerSide dhe_enabled:false]; + + [self test_default:kSSLClientSide]; + [self test_default:kSSLServerSide]; + +#define TEST_CONFIG(x, y) do { \ + [self test_config:kSSLClientSide config:x num:sizeof(y)/sizeof(SSLCipherSuite) cipherList:y]; \ + [self test_config:kSSLServerSide config:x num:sizeof(y)/sizeof(SSLCipherSuite) cipherList:y]; \ +} while(0) + + TEST_CONFIG(kSSLSessionConfig_ATSv1, ATSv1_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_ATSv1_noPFS, ATSv1_noPFS_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_legacy, legacy_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_legacy_DHE, legacy_DHE_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_standard, standard_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_RC4_fallback, legacy_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_TLSv1_fallback, default_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_TLSv1_RC4_fallback, legacy_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_default, default_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_anonymous, anonymous_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_3DES_fallback, default_ciphersuites); + TEST_CONFIG(kSSLSessionConfig_TLSv1_3DES_fallback, default_ciphersuites); + +} + +@end + diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+tls12.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+tls12.m new file mode 100644 index 00000000..9a2b321d --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+tls12.m @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2011-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@ + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include /* SSLSetOption */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "STLegacyTests.h" + +@implementation STLegacyTests (tls12) + +struct s_server { + char *host; + int port; + SSLProtocol maxprot; +}; + +typedef struct { + struct s_server *server; + uint32_t session_id; + bool is_session_resume; + SSLContextRef st; + bool client_side_auth; + bool dh_anonymous; + int comm; + CFArrayRef certs; +} ssl_test_handle; + + + +#if 0 +static void hexdump(const uint8_t *bytes, size_t len) { + size_t ix; + printf("socket write(%p, %lu)\n", bytes, len); + for (ix = 0; ix < len; ++ix) { + if (!(ix % 16)) + printf("\n"); + printf("%02X ", bytes[ix]); + } + printf("\n"); +} +#else +#define hexdump(bytes, len) +#endif + +static int SocketConnect(const char *hostName, int port) +{ + struct sockaddr_in addr; + struct in_addr host; + int sock; + int err; + struct hostent *ent; + + if (hostName[0] >= '0' && hostName[0] <= '9') { + host.s_addr = inet_addr(hostName); + } else { + ent = gethostbyname(hostName); + if(ent == NULL) { + printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno)); + return -2; + } + memcpy(&host, ent->h_addr, sizeof(struct in_addr)); + } + + sock = socket(AF_INET, SOCK_STREAM, 0); + addr.sin_addr = host; + addr.sin_port = htons((u_short)port); + + addr.sin_family = AF_INET; + err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)); + + if(err!=0) + { + perror("connect failed"); + return -1; + } + + return sock; +} + + +static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + hexdump(ptr, len); + ret = write((int)conn, ptr, len); + if (ret < 0) + perror("send"); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) +{ + size_t len = *length; + uint8_t *ptr = (uint8_t *)data; + + do { + ssize_t ret; + do { + ret = read((int)conn, ptr, len); + if (ret < 0) + perror("send"); + } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); + if (ret > 0) { + len -= ret; + ptr += ret; + } + else + return -36; + } while (len > 0); + + *length = *length - len; + return errSecSuccess; +} + +static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot, const char *peerName) +{ + SSLContextRef ctx = NULL; + + require_noerr(SSLNewContext(false, &ctx), out); + require_noerr(SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); + require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out); + + require_noerr(SSLSetSessionOption(ctx, + kSSLSessionOptionBreakOnServerAuth, true), out); + + require_noerr(SSLSetProtocolVersionMax(ctx, maxprot), out); + + require_noerr(SSLSetPeerDomainName(ctx, peerName, strlen(peerName)), out); + /* Tell SecureTransport to not check certs itself: it will break out of the + handshake to let us take care of it instead. */ + require_noerr(SSLSetEnableCertVerify(ctx, false), out); + + return ctx; +out: + if (ctx) + SSLDisposeContext(ctx); + return NULL; +} + +static OSStatus securetransport(ssl_test_handle * ssl) +{ + OSStatus ortn; + SSLContextRef ctx = ssl->st; + SecTrustRef trust = NULL; + bool got_server_auth = false, got_client_cert_req = false; + + //uint64_t start = mach_absolute_time(); + do { + ortn = SSLHandshake(ctx); + + if (ortn == errSSLServerAuthCompleted) + { + require_string(!got_server_auth, out, "second server auth"); + require_string(!got_client_cert_req, out, "got client cert req before server auth"); + got_server_auth = true; + require_string(!trust, out, "Got errSSLServerAuthCompleted twice?"); + /* verify peer cert chain */ + require_noerr(SSLCopyPeerTrust(ctx, &trust), out); + SecTrustResultType trust_result = 0; + /* this won't verify without setting up a trusted anchor */ + require_noerr(SecTrustEvaluate(trust, &trust_result), out); + require((trust_result == kSecTrustResultUnspecified), out); + + } + } while (ortn == errSSLWouldBlock + || ortn == errSSLServerAuthCompleted); + require_noerr_action_quiet(ortn, out, + fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn)); + + require_string(got_server_auth, out, "never got server auth"); + + //uint64_t elapsed = mach_absolute_time() - start; + //fprintf(stderr, "setr elapsed: %lld\n", elapsed); + + /* + SSLProtocol proto = kSSLProtocolUnknown; + require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */ + + SSLCipherSuite cipherSuite; + require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out); + //fprintf(stderr, "st negotiated %02x\n", cipherSuite); + + +out: + SSLClose(ctx); + SSLDisposeContext(ctx); + if (trust) CFRelease(trust); + + return ortn; +} + + + +#define CONNECT_TRIES 3 + +-(ssl_test_handle*)ssl_test_handle_create:(struct s_server *)server +{ + int comm = -1; + + for(int try = 0; comm<0 && tryhost, server->port); + } + + if(comm<0) { + XCTFail("connect failed with err=%d - %s:%d", comm, server->host, server->port); + return NULL; + } + + ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle)); + if (handle) { + handle->comm = comm; + handle->st = make_ssl_ref(comm, server->maxprot, server->host); + handle->server = server; + } + return handle; +} + +static void +ssl_test_handle_destroy(ssl_test_handle *handle) +{ + close(handle->comm); + free(handle); +} + + +struct s_server servers[] = { +#if !TARGET_OS_IPHONE //This test run on AppleWifi on iPhone, so we can't connect to internal servers. + {"nod.apple.com", 636, kTLSProtocol12 }, // This one has only the server eku, not the client one. +#endif + {"gsa.apple.com", 443, kTLSProtocol12 }, // This one has only the server eku, not the client one. + /* Good tls 1.2 servers */ + {"sslanalyzer.comodoca.com", 443, kTLSProtocol12 }, // This one has a stapled OCSP response with SCTs. + {"encrypted.google.com", 443, kTLSProtocol12 }, + {"www.amazon.com",443, kTLSProtocol12 }, + //{"www.mikestoolbox.org",443, kTLSProtocol12 }, + /* servers with issues */ + // This server went offline as of May 2016 -- {"vpp.visa.co.uk", 443, kTLSProtocol12 }, // Doesnt like SSL 3.0 in initial record layer version + {"imap.softbank.jp",993, kTLSProtocol12 }, // softbank imap server, there are multiple servers behind this, one of them is not able to handle downgrading to TLS 1.2 properly (126.240.66.17). + {"mobile.charter.net",993, kTLSProtocol12 }, // Support 1.2 but fail to negotiate properly + {"mybill.vodafone.com.au", 443, kTLSProtocol1 }, /* 2056 bit server key */ +}; + +#define NSERVERS (int)(sizeof(servers)/sizeof(servers[0])) +#define NLOOPS 1 + +-(void)testTls12 +{ + int p; + OSStatus r; + + for(p=0; p + + + + com.apple.keystore.access-keychain-keys + + restore-keychain + + migrate-keychain + + modify-anchor-certificates + + application-identifier + com.apple.security.regressions + keychain-access-groups + + com.apple.security.regressions + lockdown-identities + apple + + + diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests.h b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests.h new file mode 100644 index 00000000..dfd3be36 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests.h @@ -0,0 +1,20 @@ +// +// STLegacyTests.h +// Security +// +// + +#ifndef STLegacyTests_h +#define STLegacyTests_h + +#import +#include +#import +#define SKIP switch(0) default + +@interface STLegacyTests : XCTestCase + +@end + + +#endif /* STLegacyTests_h */ diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests.m new file mode 100644 index 00000000..6031702b --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests.m @@ -0,0 +1,11 @@ +// +// STLegacyTests.m +// Security +// +// + +#import "STLegacyTests.h" + +@implementation STLegacyTests + +@end diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransportTests.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransportTests.m new file mode 100644 index 00000000..33c16693 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransportTests.m @@ -0,0 +1,15 @@ +// +// SecureTransportTests.m +// SecureTransportTests +// +// + +#import + +@interface SecureTransportTests : XCTestCase + +@end + +@implementation SecureTransportTests + +@end diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransport_iosTests.plist b/OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransport_iosTests.plist new file mode 100644 index 00000000..ef1755a2 --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransport_iosTests.plist @@ -0,0 +1,21 @@ + + + + + Project + Security + Tests + + + TestName + SecureTransportTests + WorkingDirectory + /AppleInternal/XCTests/com.apple.security/ + Command + + BATS_XCTEST_CMD -NSTreatUnknownArgumentsAsOpen NO -ApplePersistenceIgnoreState YES -XCTest Self SecureTransport_ios_tests.xctest + + + + + diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransport_macosTests.plist b/OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransport_macosTests.plist new file mode 100644 index 00000000..64a927ab --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/SecureTransport_macosTests.plist @@ -0,0 +1,21 @@ + + + + + Project + Security + Tests + + + TestName + SecureTransportTests + WorkingDirectory + /AppleInternal/XCTests/com.apple.security/ + Command + + BATS_XCTEST_CMD -NSTreatUnknownArgumentsAsOpen NO -ApplePersistenceIgnoreState YES -XCTest Self SecureTransport_macos_tests.xctest + + + + + diff --git a/OSX/libsecurity_ssl/regressions/ssl-46-SSLGetSupportedCiphers.c b/OSX/libsecurity_ssl/regressions/ssl-46-SSLGetSupportedCiphers.c index ef0ef929..cfa62384 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-46-SSLGetSupportedCiphers.c +++ b/OSX/libsecurity_ssl/regressions/ssl-46-SSLGetSupportedCiphers.c @@ -97,10 +97,6 @@ static const SSLCipherSuite legacy_ciphersuites[] = { TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS_ECDHE_RSA_WITH_RC4_128_SHA, - SSL_RSA_WITH_RC4_128_SHA, - SSL_RSA_WITH_RC4_128_MD5, }; const SSLCipherSuite legacy_DHE_ciphersuites[] = { @@ -132,10 +128,6 @@ const SSLCipherSuite legacy_DHE_ciphersuites[] = { TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS_ECDHE_RSA_WITH_RC4_128_SHA, - SSL_RSA_WITH_RC4_128_SHA, - SSL_RSA_WITH_RC4_128_MD5, }; @@ -238,10 +230,6 @@ const SSLCipherSuite TLSv1_RC4_fallback_ciphersuites[] = { TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS_ECDHE_RSA_WITH_RC4_128_SHA, - SSL_RSA_WITH_RC4_128_SHA, - SSL_RSA_WITH_RC4_128_MD5, }; const SSLCipherSuite TLSv1_fallback_ciphersuites[] = { diff --git a/OSX/libsecurity_ssl/regressions/ssl-utils.c b/OSX/libsecurity_ssl/regressions/ssl-utils.c index 869256fc..5875b2b1 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-utils.c +++ b/OSX/libsecurity_ssl/regressions/ssl-utils.c @@ -151,8 +151,6 @@ const char *ciphersuite_name(SSLCipherSuite cs) /* Server provided RSA certificate for key exchange. */ C(TLS_RSA_WITH_NULL_MD5) C(TLS_RSA_WITH_NULL_SHA) - C(TLS_RSA_WITH_RC4_128_MD5) - C(TLS_RSA_WITH_RC4_128_SHA) C(TLS_RSA_WITH_3DES_EDE_CBC_SHA) C(TLS_RSA_WITH_AES_128_CBC_SHA) C(TLS_RSA_WITH_AES_256_CBC_SHA) @@ -183,7 +181,6 @@ const char *ciphersuite_name(SSLCipherSuite cs) C(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256) /* Completely anonymous Diffie-Hellman */ - C(TLS_DH_anon_WITH_RC4_128_MD5) C(TLS_DH_anon_WITH_3DES_EDE_CBC_SHA) C(TLS_DH_anon_WITH_AES_128_CBC_SHA) C(TLS_DH_anon_WITH_AES_256_CBC_SHA) @@ -207,27 +204,22 @@ const char *ciphersuite_name(SSLCipherSuite cs) /* ECDSA addenda, RFC 4492 */ C(TLS_ECDH_ECDSA_WITH_NULL_SHA) - C(TLS_ECDH_ECDSA_WITH_RC4_128_SHA) C(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA) C(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA) C(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA) C(TLS_ECDHE_ECDSA_WITH_NULL_SHA) - C(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA) C(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA) C(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA) C(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA) C(TLS_ECDH_RSA_WITH_NULL_SHA) - C(TLS_ECDH_RSA_WITH_RC4_128_SHA) C(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA) C(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA) C(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA) C(TLS_ECDHE_RSA_WITH_NULL_SHA) - C(TLS_ECDHE_RSA_WITH_RC4_128_SHA) C(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA) C(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) C(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) C(TLS_ECDH_anon_WITH_NULL_SHA) - C(TLS_ECDH_anon_WITH_RC4_128_SHA) C(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA) C(TLS_ECDH_anon_WITH_AES_128_CBC_SHA) C(TLS_ECDH_anon_WITH_AES_256_CBC_SHA) @@ -267,7 +259,6 @@ const char *ciphersuite_name(SSLCipherSuite cs) C(SSL_RSA_WITH_3DES_EDE_CBC_MD5) C(SSL_NO_SUCH_CIPHERSUITE) - C(SSL_RSA_EXPORT_WITH_RC4_40_MD5) C(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5) C(SSL_RSA_WITH_IDEA_CBC_SHA) C(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA) @@ -280,7 +271,6 @@ const char *ciphersuite_name(SSLCipherSuite cs) C(SSL_DHE_DSS_WITH_DES_CBC_SHA) C(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA) C(SSL_DHE_RSA_WITH_DES_CBC_SHA) - C(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5) C(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA) C(SSL_DH_anon_WITH_DES_CBC_SHA) C(SSL_FORTEZZA_DMS_WITH_NULL_SHA) @@ -291,7 +281,6 @@ const char *ciphersuite_name(SSLCipherSuite cs) C(TLS_PSK_WITH_AES_128_CBC_SHA256) C(TLS_PSK_WITH_AES_256_CBC_SHA) C(TLS_PSK_WITH_AES_128_CBC_SHA) - C(TLS_PSK_WITH_RC4_128_SHA) C(TLS_PSK_WITH_3DES_EDE_CBC_SHA) C(TLS_PSK_WITH_NULL_SHA384) C(TLS_PSK_WITH_NULL_SHA256) diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-ECC.der b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-ECC.der index 48305bd9bbec6ed35164b9cfc1e23badef4a2981..6fa15c839d27a5cd8e4813cc6f39c91c8c22f429 100644 GIT binary patch delta 316 zcmaFL^qpDHpo#G_5YJq|%*4pVB&;J4?a;GX-sXh)x`cgo%CDs=rx|duacH%9oU>(N zW|}CYBV%D;YGh_$Xk=<^93{bTWMFD)U}|U%5tx`Vx4yB*ps~|{hmAQ@R+y3TKMRuq zg8?6i#}DEG4PjkiAPnNGvhaY+)@Ea5Wo2h(G!Ov^3bODTa5r)0TQWaJl@7|4P| z`B=nQL?#MzTHR}Tme=4@`!eU7SeHuOo^1y5AZcY52?MbP5v{&EqMuS_GgB-Z zwKuuh`k@Ee`OF>+2ChsBrq6TafBA6jpZ#*}{fUO#H-&M|V3+?K|Mz2IpR-xe(l1Pk n3_B}QeK)HLrhISJEC^~%nSAz2??S(SY4M9h1Y-^sDn9FR+xp!fB{J}vnPXr80loToWA^i{3ZFXL%*+&4>O FCIBR-GTQ(E diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-ECC.pem b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-ECC.pem index 78d42799..f392376a 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-ECC.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-ECC.pem @@ -1,10 +1,54 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 2c:10:5b:40:8c:b3:1f:3c:c8:37:ae:60:be:7e:23:eb:1a:79:96 + Signature Algorithm: ecdsa-with-SHA256 + Issuer: CN=SecurityTest CA Cert (ECC) + Validity + Not Before: May 26 01:25:33 2018 GMT + Not After : May 17 01:25:33 2055 GMT + Subject: OU=SecurityTests Client Cert (ECC), CN=localhost + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:10:73:9e:25:d4:2a:14:b0:ed:6c:a7:cd:5b:f5: + f2:34:36:4e:1f:52:30:53:b4:c6:8c:19:72:35:d5: + 7d:8a:7a:87:50:d5:72:c2:ec:a6:ee:00:ef:a3:e8: + c5:7a:ec:c5:53:6f:20:6f:74:a1:11:d4:69:d0:68: + 5d:1b:04:c3:01 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Alternative Name: + DNS:localhost + X509v3 Subject Key Identifier: + 91:13:09:3A:DE:84:E6:6E:80:4C:7D:E9:6C:F6:16:8A:24:7E:BC:B6 + X509v3 Authority Key Identifier: + keyid:2A:8E:DC:15:F2:1D:69:64:39:77:8F:EE:F4:6D:3F:34:D9:85:F0:8C + + Signature Algorithm: ecdsa-with-SHA256 + 30:45:02:20:35:e7:6c:1f:fa:4c:0a:bf:9b:e9:ad:df:91:31: + b7:b2:56:09:98:07:1f:f3:5f:fd:f1:71:8e:43:36:52:a5:f4: + 02:21:00:b9:78:65:4d:b3:25:11:64:f7:85:29:70:52:85:64: + 93:cd:d4:8d:a1:4e:fe:66:de:d3:35:cd:e4:90:e8:2e:7f -----BEGIN CERTIFICATE----- -MIIBYTCCAQegAwIBAgICA+wwCQYHKoZIzj0EATAlMSMwIQYDVQQDExpTZWN1cml0 -eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xNTAzMjMwNzEwMjZaGA8yMDU1MDMxMzA3 -MTAyNlowPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0cyBDbGllbnQgQ2VydCAoRUND -KTESMBAGA1UEAxMJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE -EHOeJdQqFLDtbKfNW/XyNDZOH1IwU7TGjBlyNdV9inqHUNVywuym7gDvo+jFeuzF -U28gb3ShEdRp0GhdGwTDAaMNMAswCQYDVR0TBAIwADAJBgcqhkjOPQQBA0kAMEYC -IQDxZsr1M+IXVJmDSGxlX/pKFDUdNWme4hRc8Heo26YRogIhAN9Jw2fsAbq/Fgl1 -df8sSk5DlkOAjnqtL3YMhkG+miiZ +MIIB8zCCAZmgAwIBAgITLBBbQIyzHzzIN65gvn4j6xp5ljAKBggqhkjOPQQDAjAl +MSMwIQYDVQQDExpTZWN1cml0eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xODA1MjYw +MTI1MzNaGA8yMDU1MDUxNzAxMjUzM1owPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0 +cyBDbGllbnQgQ2VydCAoRUNDKTESMBAGA1UEAxMJbG9jYWxob3N0MFkwEwYHKoZI +zj0CAQYIKoZIzj0DAQcDQgAEEHOeJdQqFLDtbKfNW/XyNDZOH1IwU7TGjBlyNdV9 +inqHUNVywuym7gDvo+jFeuzFU28gb3ShEdRp0GhdGwTDAaOBjDCBiTAMBgNVHRMB +Af8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAUBgNV +HREEDTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFJETCTrehOZugEx96Wz2Fookfry2 +MB8GA1UdIwQYMBaAFCqO3BXyHWlkOXeP7vRtPzTZhfCMMAoGCCqGSM49BAMCA0gA +MEUCIDXnbB/6TAq/m+mt35Ext7JWCZgHH/Nf/fFxjkM2UqX0AiEAuXhlTbMlEWT3 +hSlwUoVkk83UjaFO/mbe0zXN5JDoLn8= -----END CERTIFICATE----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-RSA.der b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-RSA.der index 2098e570a9432c87ea47b4c673bb7b2992678768..c511994a54a2860fb9a6e1b050a865f1b415dd5e 100644 GIT binary patch delta 486 zcmZ3^vXIrlpowX&K@(%^0%j&gCMFSvof1y}?mt(ZbMDvm3opVRU%jj_&48DUQ>)FR z?K>|cBlko(JsArFQzJ72LnA|D%P0wcBLh=Y15-nDh`_{*x%H(6#RfcV%%QTvjEw(T zm<$*U_&_{<5RZkKiM_!<7{pg);W6N1(lCdwC;bsclne`xdvNA9? zF)}iEKFi@!;6JmdmP2^mSHYumQ#X9vp}4u@-i#gFUFJ9P7(9s!GyajIu-Y}LZ>{HZ z4=btpJ%_i>u|D=c;I-|>`j_*ZV$^rB%GFNXD1BczyPU6bshd)2l5Hk``nR}^vWuS| zx}a3b`1ORR;i99*yczzgT#Cy*_n_Xw?yWb|jr)AxxmO=t=`%5@bF+u#f(V|c0;hda ztlQnrm;}hB*z`_}^>pO+>1POkeEt8Q?UGz^Q@+oAWHBfAQNa1X75)o?Owxbv;9_55 zW|(%PXu^e!=?iz}iEiDL*;^g^^KM#D{i8hwyylvHwVv0${Cs)z=Z*=B5|axTwLZF? T$$QcCleW*9$^-2T*9{v1>8!hu delta 363 zcmZ3;x|~JMpovM@pox)t0W%XL6B85jYXe?3POUbNw(q=*jI0w4^khs8jE#&9%nc2U z%%UXtjSNhI0)|k5iB)s!c@4M?IN6v(WrbOo3>Z+fvobI@F)}g)J({nq^lfeVlFs|b z@Av(j62Ct+g{jo)>ED8EEnD9W{cooArH4x{GmG_Kte}0td#Fs{g$}J zCy(E}|E}<8fY7C%?EZXp;=!%a*5?_L8FyzX==EJ+SFzUMaDDs3t!i7@=Q@61Z1T}9 zs9lg+?c%L=eA9lF^LB00k%mWp9%BmPxbQvg-l>|bHEBlfj&`T(Zdq)*;B@xmAx8l6 Cq>yz0 diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-RSA.pem b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-RSA.pem index 66725b2a..500ec9b2 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-RSA.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC.Cert.CA-RSA.pem @@ -1,14 +1,67 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + b9:18:42:fe:df:e7:25:9c:ce:fa:d7:d0:e8:56:e3:d5:d3:20:96 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=SecurityTest CA Cert (RSA) + Validity + Not Before: May 26 01:21:39 2018 GMT + Not After : May 17 01:21:39 2055 GMT + Subject: OU=SecurityTests Client Cert (ECC), CN=localhost + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:10:73:9e:25:d4:2a:14:b0:ed:6c:a7:cd:5b:f5: + f2:34:36:4e:1f:52:30:53:b4:c6:8c:19:72:35:d5: + 7d:8a:7a:87:50:d5:72:c2:ec:a6:ee:00:ef:a3:e8: + c5:7a:ec:c5:53:6f:20:6f:74:a1:11:d4:69:d0:68: + 5d:1b:04:c3:01 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: critical + Digital Signature + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Subject Key Identifier: + 91:13:09:3A:DE:84:E6:6E:80:4C:7D:E9:6C:F6:16:8A:24:7E:BC:B6 + X509v3 Authority Key Identifier: + keyid:5D:A7:1B:3B:57:D2:0E:08:1E:AA:47:CF:03:34:68:BE:53:00:D9:64 + + Signature Algorithm: sha256WithRSAEncryption + 49:e6:6c:0a:20:0f:cc:a2:7d:08:13:ae:f5:11:c5:9d:65:b0: + f1:b8:21:b3:88:de:98:b8:b7:44:9f:81:0c:30:e4:5e:56:33: + f8:6c:20:ab:45:62:8e:ad:49:e7:48:3a:1a:9f:8c:c3:b5:9c: + 3b:c6:ff:50:eb:3d:b1:7f:e9:9e:42:5c:27:ba:05:1e:7d:91: + b1:1b:df:13:6b:77:0e:79:a5:46:22:65:62:3d:69:0f:67:f6: + 5e:b1:1d:a3:e7:c2:d0:22:75:01:f5:c8:49:31:a2:c5:c6:4b: + 00:fd:24:d2:5e:6d:ce:e0:38:3e:ed:4b:02:d8:df:0e:f7:0b: + ab:c1:a9:4c:91:62:89:b3:48:39:a0:58:0c:e5:10:cb:4c:64: + 3b:87:46:cc:34:50:1e:64:3c:8d:91:5d:49:41:0b:4c:8f:00: + 57:e3:d7:ff:fc:b7:19:0a:5e:94:f7:9d:e2:38:9c:6d:e2:50: + cf:fd:78:4f:a0:52:34:67:fb:b8:0a:07:a4:36:31:66:d8:72: + 90:d0:b1:67:a1:b9:6e:15:b5:b2:69:8d:7b:5d:f9:dd:66:52: + 7f:e2:bc:30:0d:37:29:8e:7d:49:d6:f4:f9:e9:c5:f9:b8:90: + a2:61:63:71:a2:85:e2:db:69:d1:35:f2:2b:4c:cc:79:c0:87: + 00:d7:31:81 -----BEGIN CERTIFICATE----- -MIICIzCCAQugAwIBAgICA+swDQYJKoZIhvcNAQEFBQAwJTEjMCEGA1UEAxMaU2Vj -dXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTUwMzIzMDcxMDI2WhgPMjA1NTAz -MTMwNzEwMjZaMD4xKDAmBgNVBAsTH1NlY3VyaXR5VGVzdHMgQ2xpZW50IENlcnQg -KEVDQykxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49AwEH -A0IABBBzniXUKhSw7WynzVv18jQ2Th9SMFO0xowZcjXVfYp6h1DVcsLspu4A76Po -xXrsxVNvIG90oRHUadBoXRsEwwGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEF -BQADggEBAFLinyMi9q13pInfx9+O+ZRfv2VkAnU65f1wayo9TbCP7JaOZ1cZpjZd -T6MvYt14erzZWQdywze4YBR6D0JRNztUCEdpv1CZIRtqwEJ+o2hHT5j/0OvKdjYk -UTKwR+6NNbU6MwXsNpFw+o8nk0mxvhXpudSEE2see62nXBaIDN8+GvrI1Inmd7sa -MPwlnQy7K6QWPvc6OLAMpnUO1n+0XqPJx9nf7nHFUBLS+QdPDn4XU4VbO88AYwG7 -aiAujteueK0ww3+H4bUmtQedQfABgkwtcH2gZXtESybHsr/PPoYbWTHE+cYCUgjQ -92beynxqrGYyR0E+y37aOLbQQs3xwkE= +MIICnTCCAYWgAwIBAgIUALkYQv7f5yWczvrX0OhW49XTIJYwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAxMaU2VjdXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTgw +NTI2MDEyMTM5WhgPMjA1NTA1MTcwMTIxMzlaMD4xKDAmBgNVBAsTH1NlY3VyaXR5 +VGVzdHMgQ2xpZW50IENlcnQgKEVDQykxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABBBzniXUKhSw7WynzVv18jQ2Th9SMFO0xowZ +cjXVfYp6h1DVcsLspu4A76PoxXrsxVNvIG90oRHUadBoXRsEwwGjdTBzMAwGA1Ud +EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMB0G +A1UdDgQWBBSREwk63oTmboBMfels9haKJH68tjAfBgNVHSMEGDAWgBRdpxs7V9IO +CB6qR88DNGi+UwDZZDANBgkqhkiG9w0BAQsFAAOCAQEASeZsCiAPzKJ9CBOu9RHF +nWWw8bghs4jemLi3RJ+BDDDkXlYz+Gwgq0Vijq1J50g6Gp+Mw7WcO8b/UOs9sX/p +nkJcJ7oFHn2RsRvfE2t3DnmlRiJlYj1pD2f2XrEdo+fC0CJ1AfXISTGixcZLAP0k +0l5tzuA4Pu1LAtjfDvcLq8GpTJFiibNIOaBYDOUQy0xkO4dGzDRQHmQ8jZFdSUEL +TI8AV+PX//y3GQpelPed4jicbeJQz/14T6BSNGf7uAoHpDYxZthykNCxZ6G5bhW1 +smmNe1353WZSf+K8MA03KY59Sdb0+enF+biQomFjcaKF4ttp0TXyK0zMecCHANcx +gQ== -----END CERTIFICATE----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC_Cert_CA-ECC.h b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC_Cert_CA-ECC.h index 2e728533..6c06a96f 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC_Cert_CA-ECC.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC_Cert_CA-ECC.h @@ -1,33 +1,45 @@ unsigned char ClientECC_Cert_CA_ECC_der[] = { - 0x30, 0x82, 0x01, 0x61, 0x30, 0x82, 0x01, 0x07, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x03, 0xec, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, - 0xce, 0x3d, 0x04, 0x01, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, - 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, - 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, - 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31, 0x33, 0x30, 0x37, - 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, - 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, - 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, - 0x10, 0x73, 0x9e, 0x25, 0xd4, 0x2a, 0x14, 0xb0, 0xed, 0x6c, 0xa7, 0xcd, - 0x5b, 0xf5, 0xf2, 0x34, 0x36, 0x4e, 0x1f, 0x52, 0x30, 0x53, 0xb4, 0xc6, - 0x8c, 0x19, 0x72, 0x35, 0xd5, 0x7d, 0x8a, 0x7a, 0x87, 0x50, 0xd5, 0x72, - 0xc2, 0xec, 0xa6, 0xee, 0x00, 0xef, 0xa3, 0xe8, 0xc5, 0x7a, 0xec, 0xc5, - 0x53, 0x6f, 0x20, 0x6f, 0x74, 0xa1, 0x11, 0xd4, 0x69, 0xd0, 0x68, 0x5d, - 0x1b, 0x04, 0xc3, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x09, 0x06, 0x07, 0x2a, - 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, - 0x21, 0x00, 0xf1, 0x66, 0xca, 0xf5, 0x33, 0xe2, 0x17, 0x54, 0x99, 0x83, - 0x48, 0x6c, 0x65, 0x5f, 0xfa, 0x4a, 0x14, 0x35, 0x1d, 0x35, 0x69, 0x9e, - 0xe2, 0x14, 0x5c, 0xf0, 0x77, 0xa8, 0xdb, 0xa6, 0x11, 0xa2, 0x02, 0x21, - 0x00, 0xdf, 0x49, 0xc3, 0x67, 0xec, 0x01, 0xba, 0xbf, 0x16, 0x09, 0x75, - 0x75, 0xff, 0x2c, 0x4a, 0x4e, 0x43, 0x96, 0x43, 0x80, 0x8e, 0x7a, 0xad, - 0x2f, 0x76, 0x0c, 0x86, 0x41, 0xbe, 0x9a, 0x28, 0x99 + 0x30, 0x82, 0x01, 0xf3, 0x30, 0x82, 0x01, 0x99, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x13, 0x2c, 0x10, 0x5b, 0x40, 0x8c, 0xb3, 0x1f, 0x3c, 0xc8, + 0x37, 0xae, 0x60, 0xbe, 0x7e, 0x23, 0xeb, 0x1a, 0x79, 0x96, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x25, + 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, + 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, 0x32, 0x36, 0x30, + 0x31, 0x32, 0x35, 0x33, 0x33, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, + 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x35, 0x33, 0x33, 0x5a, 0x30, + 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, + 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, + 0x6f, 0x73, 0x74, 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, 0x10, 0x73, 0x9e, 0x25, 0xd4, 0x2a, + 0x14, 0xb0, 0xed, 0x6c, 0xa7, 0xcd, 0x5b, 0xf5, 0xf2, 0x34, 0x36, 0x4e, + 0x1f, 0x52, 0x30, 0x53, 0xb4, 0xc6, 0x8c, 0x19, 0x72, 0x35, 0xd5, 0x7d, + 0x8a, 0x7a, 0x87, 0x50, 0xd5, 0x72, 0xc2, 0xec, 0xa6, 0xee, 0x00, 0xef, + 0xa3, 0xe8, 0xc5, 0x7a, 0xec, 0xc5, 0x53, 0x6f, 0x20, 0x6f, 0x74, 0xa1, + 0x11, 0xd4, 0x69, 0xd0, 0x68, 0x5d, 0x1b, 0x04, 0xc3, 0x01, 0xa3, 0x81, + 0x8c, 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13, + 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14, 0x06, 0x03, 0x55, + 0x1d, 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x91, 0x13, 0x09, 0x3a, 0xde, 0x84, 0xe6, 0x6e, + 0x80, 0x4c, 0x7d, 0xe9, 0x6c, 0xf6, 0x16, 0x8a, 0x24, 0x7e, 0xbc, 0xb6, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0x2a, 0x8e, 0xdc, 0x15, 0xf2, 0x1d, 0x69, 0x64, 0x39, 0x77, 0x8f, + 0xee, 0xf4, 0x6d, 0x3f, 0x34, 0xd9, 0x85, 0xf0, 0x8c, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, + 0x30, 0x45, 0x02, 0x20, 0x35, 0xe7, 0x6c, 0x1f, 0xfa, 0x4c, 0x0a, 0xbf, + 0x9b, 0xe9, 0xad, 0xdf, 0x91, 0x31, 0xb7, 0xb2, 0x56, 0x09, 0x98, 0x07, + 0x1f, 0xf3, 0x5f, 0xfd, 0xf1, 0x71, 0x8e, 0x43, 0x36, 0x52, 0xa5, 0xf4, + 0x02, 0x21, 0x00, 0xb9, 0x78, 0x65, 0x4d, 0xb3, 0x25, 0x11, 0x64, 0xf7, + 0x85, 0x29, 0x70, 0x52, 0x85, 0x64, 0x93, 0xcd, 0xd4, 0x8d, 0xa1, 0x4e, + 0xfe, 0x66, 0xde, 0xd3, 0x35, 0xcd, 0xe4, 0x90, 0xe8, 0x2e, 0x7f }; -unsigned int ClientECC_Cert_CA_ECC_der_len = 357; +unsigned int ClientECC_Cert_CA_ECC_der_len = 503; diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC_Cert_CA-RSA.h b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC_Cert_CA-RSA.h index 8f8df572..deda18d4 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ClientECC_Cert_CA-RSA.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/ClientECC_Cert_CA-RSA.h @@ -1,49 +1,60 @@ unsigned char ClientECC_Cert_CA_RSA_der[] = { - 0x30, 0x82, 0x02, 0x23, 0x30, 0x82, 0x01, 0x0b, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x03, 0xeb, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, - 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, - 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, - 0x20, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, - 0x30, 0x32, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, - 0x31, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, - 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, - 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, - 0x28, 0x45, 0x43, 0x43, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 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, 0x10, 0x73, 0x9e, 0x25, 0xd4, 0x2a, 0x14, 0xb0, - 0xed, 0x6c, 0xa7, 0xcd, 0x5b, 0xf5, 0xf2, 0x34, 0x36, 0x4e, 0x1f, 0x52, - 0x30, 0x53, 0xb4, 0xc6, 0x8c, 0x19, 0x72, 0x35, 0xd5, 0x7d, 0x8a, 0x7a, - 0x87, 0x50, 0xd5, 0x72, 0xc2, 0xec, 0xa6, 0xee, 0x00, 0xef, 0xa3, 0xe8, - 0xc5, 0x7a, 0xec, 0xc5, 0x53, 0x6f, 0x20, 0x6f, 0x74, 0xa1, 0x11, 0xd4, - 0x69, 0xd0, 0x68, 0x5d, 0x1b, 0x04, 0xc3, 0x01, 0xa3, 0x0d, 0x30, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x52, 0xe2, 0x9f, 0x23, 0x22, - 0xf6, 0xad, 0x77, 0xa4, 0x89, 0xdf, 0xc7, 0xdf, 0x8e, 0xf9, 0x94, 0x5f, - 0xbf, 0x65, 0x64, 0x02, 0x75, 0x3a, 0xe5, 0xfd, 0x70, 0x6b, 0x2a, 0x3d, - 0x4d, 0xb0, 0x8f, 0xec, 0x96, 0x8e, 0x67, 0x57, 0x19, 0xa6, 0x36, 0x5d, - 0x4f, 0xa3, 0x2f, 0x62, 0xdd, 0x78, 0x7a, 0xbc, 0xd9, 0x59, 0x07, 0x72, - 0xc3, 0x37, 0xb8, 0x60, 0x14, 0x7a, 0x0f, 0x42, 0x51, 0x37, 0x3b, 0x54, - 0x08, 0x47, 0x69, 0xbf, 0x50, 0x99, 0x21, 0x1b, 0x6a, 0xc0, 0x42, 0x7e, - 0xa3, 0x68, 0x47, 0x4f, 0x98, 0xff, 0xd0, 0xeb, 0xca, 0x76, 0x36, 0x24, - 0x51, 0x32, 0xb0, 0x47, 0xee, 0x8d, 0x35, 0xb5, 0x3a, 0x33, 0x05, 0xec, - 0x36, 0x91, 0x70, 0xfa, 0x8f, 0x27, 0x93, 0x49, 0xb1, 0xbe, 0x15, 0xe9, - 0xb9, 0xd4, 0x84, 0x13, 0x6b, 0x1e, 0x7b, 0xad, 0xa7, 0x5c, 0x16, 0x88, - 0x0c, 0xdf, 0x3e, 0x1a, 0xfa, 0xc8, 0xd4, 0x89, 0xe6, 0x77, 0xbb, 0x1a, - 0x30, 0xfc, 0x25, 0x9d, 0x0c, 0xbb, 0x2b, 0xa4, 0x16, 0x3e, 0xf7, 0x3a, - 0x38, 0xb0, 0x0c, 0xa6, 0x75, 0x0e, 0xd6, 0x7f, 0xb4, 0x5e, 0xa3, 0xc9, - 0xc7, 0xd9, 0xdf, 0xee, 0x71, 0xc5, 0x50, 0x12, 0xd2, 0xf9, 0x07, 0x4f, - 0x0e, 0x7e, 0x17, 0x53, 0x85, 0x5b, 0x3b, 0xcf, 0x00, 0x63, 0x01, 0xbb, - 0x6a, 0x20, 0x2e, 0x8e, 0xd7, 0xae, 0x78, 0xad, 0x30, 0xc3, 0x7f, 0x87, - 0xe1, 0xb5, 0x26, 0xb5, 0x07, 0x9d, 0x41, 0xf0, 0x01, 0x82, 0x4c, 0x2d, - 0x70, 0x7d, 0xa0, 0x65, 0x7b, 0x44, 0x4b, 0x26, 0xc7, 0xb2, 0xbf, 0xcf, - 0x3e, 0x86, 0x1b, 0x59, 0x31, 0xc4, 0xf9, 0xc6, 0x02, 0x52, 0x08, 0xd0, - 0xf7, 0x66, 0xde, 0xca, 0x7c, 0x6a, 0xac, 0x66, 0x32, 0x47, 0x41, 0x3e, - 0xcb, 0x7e, 0xda, 0x38, 0xb6, 0xd0, 0x42, 0xcd, 0xf1, 0xc2, 0x41 + 0x30, 0x82, 0x02, 0x9d, 0x30, 0x82, 0x01, 0x85, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x00, 0xb9, 0x18, 0x42, 0xfe, 0xdf, 0xe7, 0x25, 0x9c, + 0xce, 0xfa, 0xd7, 0xd0, 0xe8, 0x56, 0xe3, 0xd5, 0xd3, 0x20, 0x96, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, + 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, + 0x35, 0x32, 0x36, 0x30, 0x31, 0x32, 0x31, 0x33, 0x39, 0x5a, 0x18, 0x0f, + 0x32, 0x30, 0x35, 0x35, 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x31, + 0x33, 0x39, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, 0x10, 0x73, + 0x9e, 0x25, 0xd4, 0x2a, 0x14, 0xb0, 0xed, 0x6c, 0xa7, 0xcd, 0x5b, 0xf5, + 0xf2, 0x34, 0x36, 0x4e, 0x1f, 0x52, 0x30, 0x53, 0xb4, 0xc6, 0x8c, 0x19, + 0x72, 0x35, 0xd5, 0x7d, 0x8a, 0x7a, 0x87, 0x50, 0xd5, 0x72, 0xc2, 0xec, + 0xa6, 0xee, 0x00, 0xef, 0xa3, 0xe8, 0xc5, 0x7a, 0xec, 0xc5, 0x53, 0x6f, + 0x20, 0x6f, 0x74, 0xa1, 0x11, 0xd4, 0x69, 0xd0, 0x68, 0x5d, 0x1b, 0x04, + 0xc3, 0x01, 0xa3, 0x75, 0x30, 0x73, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x91, 0x13, 0x09, 0x3a, + 0xde, 0x84, 0xe6, 0x6e, 0x80, 0x4c, 0x7d, 0xe9, 0x6c, 0xf6, 0x16, 0x8a, + 0x24, 0x7e, 0xbc, 0xb6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0x5d, 0xa7, 0x1b, 0x3b, 0x57, 0xd2, 0x0e, + 0x08, 0x1e, 0xaa, 0x47, 0xcf, 0x03, 0x34, 0x68, 0xbe, 0x53, 0x00, 0xd9, + 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x49, 0xe6, 0x6c, + 0x0a, 0x20, 0x0f, 0xcc, 0xa2, 0x7d, 0x08, 0x13, 0xae, 0xf5, 0x11, 0xc5, + 0x9d, 0x65, 0xb0, 0xf1, 0xb8, 0x21, 0xb3, 0x88, 0xde, 0x98, 0xb8, 0xb7, + 0x44, 0x9f, 0x81, 0x0c, 0x30, 0xe4, 0x5e, 0x56, 0x33, 0xf8, 0x6c, 0x20, + 0xab, 0x45, 0x62, 0x8e, 0xad, 0x49, 0xe7, 0x48, 0x3a, 0x1a, 0x9f, 0x8c, + 0xc3, 0xb5, 0x9c, 0x3b, 0xc6, 0xff, 0x50, 0xeb, 0x3d, 0xb1, 0x7f, 0xe9, + 0x9e, 0x42, 0x5c, 0x27, 0xba, 0x05, 0x1e, 0x7d, 0x91, 0xb1, 0x1b, 0xdf, + 0x13, 0x6b, 0x77, 0x0e, 0x79, 0xa5, 0x46, 0x22, 0x65, 0x62, 0x3d, 0x69, + 0x0f, 0x67, 0xf6, 0x5e, 0xb1, 0x1d, 0xa3, 0xe7, 0xc2, 0xd0, 0x22, 0x75, + 0x01, 0xf5, 0xc8, 0x49, 0x31, 0xa2, 0xc5, 0xc6, 0x4b, 0x00, 0xfd, 0x24, + 0xd2, 0x5e, 0x6d, 0xce, 0xe0, 0x38, 0x3e, 0xed, 0x4b, 0x02, 0xd8, 0xdf, + 0x0e, 0xf7, 0x0b, 0xab, 0xc1, 0xa9, 0x4c, 0x91, 0x62, 0x89, 0xb3, 0x48, + 0x39, 0xa0, 0x58, 0x0c, 0xe5, 0x10, 0xcb, 0x4c, 0x64, 0x3b, 0x87, 0x46, + 0xcc, 0x34, 0x50, 0x1e, 0x64, 0x3c, 0x8d, 0x91, 0x5d, 0x49, 0x41, 0x0b, + 0x4c, 0x8f, 0x00, 0x57, 0xe3, 0xd7, 0xff, 0xfc, 0xb7, 0x19, 0x0a, 0x5e, + 0x94, 0xf7, 0x9d, 0xe2, 0x38, 0x9c, 0x6d, 0xe2, 0x50, 0xcf, 0xfd, 0x78, + 0x4f, 0xa0, 0x52, 0x34, 0x67, 0xfb, 0xb8, 0x0a, 0x07, 0xa4, 0x36, 0x31, + 0x66, 0xd8, 0x72, 0x90, 0xd0, 0xb1, 0x67, 0xa1, 0xb9, 0x6e, 0x15, 0xb5, + 0xb2, 0x69, 0x8d, 0x7b, 0x5d, 0xf9, 0xdd, 0x66, 0x52, 0x7f, 0xe2, 0xbc, + 0x30, 0x0d, 0x37, 0x29, 0x8e, 0x7d, 0x49, 0xd6, 0xf4, 0xf9, 0xe9, 0xc5, + 0xf9, 0xb8, 0x90, 0xa2, 0x61, 0x63, 0x71, 0xa2, 0x85, 0xe2, 0xdb, 0x69, + 0xd1, 0x35, 0xf2, 0x2b, 0x4c, 0xcc, 0x79, 0xc0, 0x87, 0x00, 0xd7, 0x31, + 0x81 }; -unsigned int ClientECC_Cert_CA_RSA_der_len = 551; +unsigned int ClientECC_Cert_CA_RSA_der_len = 673; diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Cert.CA-ECC.der b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Cert.CA-ECC.der index 83e0b56ba003f5d2cfc5b91dbfca0be1f410356e..d1efd8196cd092e4daaf141aa84ba22605215ba5 100644 GIT binary patch delta 638 zcmZ3*e27)gpowW85T`6)W@2Pw64nujcIeqGZ*#(YUBbRP<=0Y`(+#-TIJDY4&e^gs zGfkAy(X=oyH8L|WG%__Yh?3wpGB7nYFf}xX3K-ZKY8a@oF^95n^Gqz%tmom($xlwq z$;dA*F=%2`GT>$71e(?MotKf3k(GhDiIJZHD9**y#K_37e7c%#h34%Wf+sh9+h?}; z>Bl9T-?g9JziV@eh1NYKp9OZOwRYd_V&D0#AU9u~)BEn{j4P9)_dECmsIOh#Cu%1B zDcLU|^YE^3Nt>T%%4Ge}^y*=&f7~9?t8g^tVs6H!fLl^e1@C03O*-lraO~opx`plP zRlj*|{F=AbIP_Vun!}AM@9L1ZzOuH3YoD@t9!jvfDQ2XwCI5s=)Zxi2GbgR{%9tpt za4^G9DQV@2(vy=EpW7BWKAL~M8pz&h-@RUAbWHD|_=e(*-g)bI-2avf-ETddvSJ^B!_qzaz)jbCCAZcY52?MbP z5v{&EqMu|lQ!LB--+jroH@VsRp$9qsnLQW`T$vOZ4y~(YRV@0W^}lIR|MCsJa~_^w z(sQ!zjB4t>Gi6Qb`bJC&9!DpyO|+9T>JD4>>PY1MJ=b&q DZ?p5& delta 356 zcmX@ax{6uGpowuA5c@4)W@2PwVq$(}z{$q0)#h=|mW6Smo{pxefw7UXfw`f9ky(@k zzmb6{P{0r-U|?scVW7sw9LmBiJh54`UYIi{KRGccBfq%BpmDwdFB>P&q_*$8jEsz| z49tza3r&6<1hgJ$HSr0CbHt(K@+h%GYad-7oEN46K5pP0Q$ zceXE0mEPi(aXu|a@RND0;US5GXP?x{CO?i@G@1FD=;CO*D<^ktEzEz>>1np>$EhZ% zdav|jlhb)?PNn&}KcqdD3(ox5NV;Aq#Eo@h>`pt9W z*SxL9q0frd9Bx#3SBJdym9;Hg`;^V|P=eJ>F(ZX7`6pbW4o_y8Icc3&#za|#gBgBG zNh?p3o}8rk+_uQ^(fory^dE-`o&9j|_8RYJwVT#(|9klTfqm!nQl7xAQ9Si*LU!r> z)i!;;>kpPzPuXvAuBTw{$^~;@*_+3iE|AHYdv@iP4ZnofTmBcB_mF!t6EhwHxM5`2lr^>Y2j?;MuHA`U%P0F@Y&5%}XFR=-%S=tz-_EzQB7ND9N{4-~ zUZ>1S7M%5C?~~upqb6D|a4c)oJUgjw50iC$ti!+cLIJl3-K=d|Dj=c%<}F@fs&KD!TF*PfipnGnsIH78MQwZ0MHBNrt_zg}&%M9o5Mkul$s2TMP)z0mx`>{Yt6eQB!n z7PpM^X*q(Q%wr7?NgO=;q*gZham=F0%-2L0N84RFxoc}-{)di>mhbuI`+HJ#x6U#Q7oc7|%L;UE6C)$Tbbryf{ub5NBu=+JS$;cBxAqfL_nzQvKL~>@s zHdD)8nirq8NTgq@=Vud5I;9|K@MJ=`u7rUCCo@;wg`eB@3S`b>D0JwW<8o-pg@V7% zM*IEG96RMDw&?;l=e?a>sk>Sa3Qw6N&wKJgyy_K=50g&b>dAL_=4bA<#MOH8tvtp< zS06fh%o0;e%3Yi{v-;J!ZM$6d&Xo`eU2=Crdq_>r`^|rG9a{X$V6JhlLVQPu1aW;9U#GIP9kEd$aTq*A?H1ELE@jm_%GvC63y_z z+pJ6GeX^_z{^9rFKZ%!h3{kaO3OVJLHJ}`9 zoz1DVu=*3PIsX)%;R~|@0|5X50)hbmG#!x2w7+kfHI3huQ+aY`V@j}@kg2ZW#6)xB z0LbyfGeg3xDkKuk@pO<%@AazNpsi15?>!plgK(; zT+S)T;X&M$;qXB*NL+YNUmSH|0)c@5*9XgmzCp@MVdRSQ)aRBgH%ux-9ntdUZ*-9_%F}kXKdXEkyvo0)c@5 z$Axl5XQO<C$7+x8`(>+TkW FdEW4RNmu{? literal 607 zcmV-l0-*gcf&yCt0RRGlfdIfEDHCbC|GNck(eNo*qGDU?t2(46I2NKa4&>ma@doHA z@&ihBxre1?8?;7f&t_~9@;6;E!WhBLfy)Iq|%*SH%V4;IVz32L6^{#AEYj$_|L1D>@IbnE7RbD66nk1PRZ7r#j!`+l_ZV| zALA8;&d=X~bf(;!l%tzNN%ai=qpmPDU&-OUqQzU9OwX<~oXn(j%RH&2SatJoa`J)B z$Zud#Me6CDhC_heler?`ZUW4SW-$Um0P9z+3i2hW)m&)StG9+0#(U%=wHjZn^HK;*F0Fe~9BnM?5?s>1|zBRa3g04QbJPGq)y2aW)H@02C zgE-2d04hvB_HQZ_G0zeZLU2ni{4)WT6rp*@29%$x38WS4CArtRgjA)lhVD9D1QI| diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Key.pem b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Key.pem index e459119c..a3286410 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Key.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Key.pem @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICWwIBAAKBgQDAISkTabv/uwVt0fApWaJiW+urOqQmOBaiMw7k4KXxBugp8gNK -dbmHpWUbtEZoz2ZsEfI3XTHCGMHN5H0dY+NcopMD1hWjWz7Uybq1cW/oiUk2uvjK -ghpKZ8aTZw18ymdM32Vl2Vkd4ago9NvqmtzopDfbjSQ0UJohIuJA2qRD0QIDAQAB -AoGAEsbq4cfSpNKdXDdJVnE5Ko27QZfQlR+kLqP4z6uY7C51oCvT4IIS6MvkTsnW -m8WxR9yVJI4KH+MVhc7P34B0ptyblKObQ0n1DP6jrjA1X8nhvaLFW5pMz640nMyk -dMs8qaVYdfNwcvKBzshvYFFF6umdhkOA3ZO5IuBuAsyJZjECQQDrV60K8iWo1V0k -zzkY9/2VEAZbn44hnFs70rnOKTfJfxRIyoNqCNe2Lsg0lVtWO/7++IolxWBD7k8Y -WBP2IG89AkEA0P507CghrhTvcWnBBDEX3mEY2bF40sk8eHsk42IdIIEQ+ppF68zh -nDIkWTrRlx1eNo5ryDWoQpm7CVhdeQfwJQJAUffFk2xnZXh66pkqP+IP9l0QedUG -wfodZKauhHmirpGOVRQD1WijCRceMAJdP5nB5LhYFXO7Za2Y6teyjCUb2QJALqrD -HQCRFLgkB2Uf7nmv5L41uFaCrj61PAnzYLrF2j43tl3AgzjKoAAqUapqpp2uLex7 -cMdafRSqyRlsNdxp6QJAH9R89iqTolQ4y9H3FhKY8iv82vYLOcrv1VBmGso/CJSm -CG2uPS2L3l8BWnkqnO+nuu23r54WDOOx6lWQiyiT0g== +MIIEowIBAAKCAQEAp5cmPXgp29gRybL2vjaj5fGks+6Hzb+6s3Q4Kt4iTKA+yyq7 +3YoHufZwbW8nCUvd82jUk1u/QExQJ62njhU2G/JjTlBpw7r2YrPnaRxq+ClKjAbj +h1iNIMVc0W1oslDaGuUR3GomksVBUMbR3H6hhyd6+wzY+p61M1XmcyZA2HpLe1Tt +TR09ca3lBknCYDrZFjIgtG/IRFrDkwSZkq5KaJEdIMFoTiJiqch1yZIh5z1yQeKf +wfgv41USzfDB26xL5n2yrAv+4ffgP4mXdQxRtVoMBhI+Z497PI5Nr8F1e5S/OM6M +cL2poJ3qPzdeNaAcbJ3NqbSw+hOvOf8UnuELswIDAQABAoIBADQdkMq0v2+aNY3f +lVN5cmZjSrCZkKmu4cREc+MAyPHDM0PCukEeV2DA/h1J333IlfDHvLNGaKb6FEMC +gYRxnC38pl0ILJutXEk9YM0TBUC+tmvtCHxiUSDLvx1xRImPEwQiD/fXGr+xj6oq +6cADsP9yi4/eYussx3R7Vfqg/rFSdZRkpT5E7N5K+zIHAKnR5nNuSTWPS4iIGBXU +tQClgFPMLTh8htknERAr0d3BtM9b4khSPZ1rbG6bMoY3uni+DrWk01D9BSjY6CL3 +ZG6+vW/R2ExUuBF/7pH3DLPNEGSlSXPXwRJfH02TyDpcXM4pyOFB3JXh8EExSFx4 +T18cdWECgYEA1wfLhb5Bykth5Irz1Oy1mA20nbku9TPaMNkDMgRUeXG5vUxNx9Q4 +sbTz3HuHhATMYDSIux1hUZZDJJg1pIG7JRXJCIf2E6cAJloarQdV+0tUK1PiOdHT +HGy0mP49Hy9g2b30OkxIhasjxTwTuiz3A3p1Sbge7CUjkFdV4y1FAL8CgYEAx4Vy +RWejfMGba8sMIjLSlAWRGWr+Fb4BCvCDAHxhvif5lCCATAr/UbNmYp49B+OJ0iMz +iBhkTFzzxOP0FY6xZa0JkTJNAtJ7TmxMNClwcapLt55HE1REIeQHWGg8r0+ZKiat +PUOOmARPnUXOr7WSjJ9rhQCGxNe7fofPFIJ+fg0CgYAm4JDqgGiSs6hiUsEdCSMX +97plHdsgmBxl4oaSX3gKcQZc9FPHwlXxwz6n6Wmp89gjuLvT4M78mkdPcXmZYZ89 +aD/tm+9gxDvhsz7Jc98WzRrNrp/jRk1+ASVx192jKsS++XoTpEEkcbnI6kDC02hh +p51XE8P7fAd/DFtJ9KBaLwKBgQCIqEZUc1/vG0yw0CpHYjgJWqa/miDeE33zWDji +JE9uR0MSyhAWBZJLC22dLnTu6lKDs8if9tT72M6+lMOh4FJxKcvbv3Av9qquVE79 +i0SRFes2oRpdiuH/tIezbfHiwcpOrJ8LzzHjvVAqkJ24i80MtESYnHuyZ3DsgWi8 +y4SIIQKBgC1CmnmYij3H7S+rQC8mw/bHeY0EbHGSu2sv3lvm/1HAY9zQ5BKTTft+ +JxSYggMLBbfQerANvJ68+unOBRT64aonLY7S4/64dFCpnBai5HlTKrcy5K4yprpd +ht0cZrEYr8X+RLn75VpaHkVKi+w8fe3AAlOlsVzb9iWg6+4WhHne -----END RSA PRIVATE KEY----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Req.pem b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Req.pem index 4e63493e..883ee1ec 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Req.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA.Req.pem @@ -1,11 +1,16 @@ -----BEGIN CERTIFICATE REQUEST----- -MIIBfTCB5wIBADA+MSgwJgYDVQQLEx9TZWN1cml0eVRlc3RzIENsaWVudCBDZXJ0 -IChSU0EpMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0A -MIGJAoGBAMAhKRNpu/+7BW3R8ClZomJb66s6pCY4FqIzDuTgpfEG6CnyA0p1uYel -ZRu0RmjPZmwR8jddMcIYwc3kfR1j41yikwPWFaNbPtTJurVxb+iJSTa6+MqCGkpn -xpNnDXzKZ0zfZWXZWR3hqCj02+qa3OikN9uNJDRQmiEi4kDapEPRAgMBAAGgADAN -BgkqhkiG9w0BAQUFAAOBgQBic3QNIuqVwj46T21GEK82lXbTlM/dSKfxQrSnf3if -CCZ4Hdp/lT/xDGuB3HatPxR48kh6kns8YHID1T2eqZndiKc+KDjatARwmzmYAsi0 -E/oNAdYo7qnNhZnV++CzJQiqNsJZHotbnJcbNxVt03P/pGelVbhXENWnGzhlN0qz -Nw== +MIICgzCCAWsCAQAwPjEoMCYGA1UECwwfU2VjdXJpdHlUZXN0cyBDbGllbnQgQ2Vy +dCAoUlNBKTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAp5cmPXgp29gRybL2vjaj5fGks+6Hzb+6s3Q4Kt4iTKA+yyq7 +3YoHufZwbW8nCUvd82jUk1u/QExQJ62njhU2G/JjTlBpw7r2YrPnaRxq+ClKjAbj +h1iNIMVc0W1oslDaGuUR3GomksVBUMbR3H6hhyd6+wzY+p61M1XmcyZA2HpLe1Tt +TR09ca3lBknCYDrZFjIgtG/IRFrDkwSZkq5KaJEdIMFoTiJiqch1yZIh5z1yQeKf +wfgv41USzfDB26xL5n2yrAv+4ffgP4mXdQxRtVoMBhI+Z497PI5Nr8F1e5S/OM6M +cL2poJ3qPzdeNaAcbJ3NqbSw+hOvOf8UnuELswIDAQABoAAwDQYJKoZIhvcNAQEL +BQADggEBAF+sUbhhGM/GGG400QhMr+esqcEaXjuEjOD98LpORG2L750qyimb9bQo +A4dLmC79j2m0LgvQX5+91qg4XDes2T/X31Oj/p9sPYSQzxLz0mmlQuvZUzfzMdlT +w3PzyuGtN511GypID3mOpBhnd0GIAA2no16wDih9ioZbtoBxVI5pu+4x5JCvpxY0 +1p2CVwR1yUAv3VD36tdQrsRAB2L3j3QpOZegZQkSe/52g55sqwHsL4/7MVNol6et +OOvyGRRXhhDZjE6nRVGwd0jjivDV65Z+04mU2+VSKJfSR9diaK7S/6VJ1a1LMGwq +yARjlRT/+9YCgOpcG42vyDxjyk9qXX0= -----END CERTIFICATE REQUEST----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Cert_CA-ECC.h b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Cert_CA-ECC.h index c85dcb01..ee77715a 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Cert_CA-ECC.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Cert_CA-ECC.h @@ -1,39 +1,62 @@ unsigned char ClientRSA_Cert_CA_ECC_der[] = { - 0x30, 0x82, 0x01, 0xa6, 0x30, 0x82, 0x01, 0x4e, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x03, 0xea, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, - 0xce, 0x3d, 0x04, 0x01, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, - 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, - 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, - 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31, 0x33, 0x30, 0x37, - 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, - 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, - 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x81, 0x9f, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, - 0x81, 0x00, 0xc0, 0x21, 0x29, 0x13, 0x69, 0xbb, 0xff, 0xbb, 0x05, 0x6d, - 0xd1, 0xf0, 0x29, 0x59, 0xa2, 0x62, 0x5b, 0xeb, 0xab, 0x3a, 0xa4, 0x26, - 0x38, 0x16, 0xa2, 0x33, 0x0e, 0xe4, 0xe0, 0xa5, 0xf1, 0x06, 0xe8, 0x29, - 0xf2, 0x03, 0x4a, 0x75, 0xb9, 0x87, 0xa5, 0x65, 0x1b, 0xb4, 0x46, 0x68, - 0xcf, 0x66, 0x6c, 0x11, 0xf2, 0x37, 0x5d, 0x31, 0xc2, 0x18, 0xc1, 0xcd, - 0xe4, 0x7d, 0x1d, 0x63, 0xe3, 0x5c, 0xa2, 0x93, 0x03, 0xd6, 0x15, 0xa3, - 0x5b, 0x3e, 0xd4, 0xc9, 0xba, 0xb5, 0x71, 0x6f, 0xe8, 0x89, 0x49, 0x36, - 0xba, 0xf8, 0xca, 0x82, 0x1a, 0x4a, 0x67, 0xc6, 0x93, 0x67, 0x0d, 0x7c, - 0xca, 0x67, 0x4c, 0xdf, 0x65, 0x65, 0xd9, 0x59, 0x1d, 0xe1, 0xa8, 0x28, - 0xf4, 0xdb, 0xea, 0x9a, 0xdc, 0xe8, 0xa4, 0x37, 0xdb, 0x8d, 0x24, 0x34, - 0x50, 0x9a, 0x21, 0x22, 0xe2, 0x40, 0xda, 0xa4, 0x43, 0xd1, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, - 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, - 0x1e, 0xdd, 0x4d, 0xc6, 0xb8, 0xca, 0xc5, 0x9d, 0xdb, 0x88, 0x7b, 0xe8, - 0xb8, 0x9b, 0xef, 0x38, 0x19, 0x9e, 0x03, 0x4a, 0xaf, 0xd3, 0xec, 0x4a, - 0xf0, 0x95, 0x6b, 0xe3, 0xd7, 0x31, 0xe2, 0x17, 0x02, 0x20, 0x70, 0x16, - 0xe9, 0xd4, 0x78, 0xfc, 0xb6, 0x26, 0xd6, 0xb1, 0x9b, 0x37, 0x4d, 0x11, - 0x8e, 0x96, 0x13, 0x8d, 0x3d, 0xd2, 0xc5, 0x2d, 0x6b, 0x2a, 0x62, 0xe8, - 0xae, 0xeb, 0xb4, 0x98, 0x2b, 0xa8 + 0x30, 0x82, 0x02, 0xbe, 0x30, 0x82, 0x02, 0x64, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x13, 0x2c, 0x10, 0x5b, 0x40, 0x8c, 0xb3, 0x1f, 0x3c, 0xc8, + 0x37, 0xae, 0x60, 0xbe, 0x7e, 0x23, 0xeb, 0x1a, 0x79, 0x97, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x25, + 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, + 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, 0x32, 0x36, 0x30, + 0x31, 0x32, 0x35, 0x34, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, + 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x35, 0x34, 0x30, 0x5a, 0x30, + 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1f, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, + 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, + 0x6f, 0x73, 0x74, 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, + 0xa7, 0x97, 0x26, 0x3d, 0x78, 0x29, 0xdb, 0xd8, 0x11, 0xc9, 0xb2, 0xf6, + 0xbe, 0x36, 0xa3, 0xe5, 0xf1, 0xa4, 0xb3, 0xee, 0x87, 0xcd, 0xbf, 0xba, + 0xb3, 0x74, 0x38, 0x2a, 0xde, 0x22, 0x4c, 0xa0, 0x3e, 0xcb, 0x2a, 0xbb, + 0xdd, 0x8a, 0x07, 0xb9, 0xf6, 0x70, 0x6d, 0x6f, 0x27, 0x09, 0x4b, 0xdd, + 0xf3, 0x68, 0xd4, 0x93, 0x5b, 0xbf, 0x40, 0x4c, 0x50, 0x27, 0xad, 0xa7, + 0x8e, 0x15, 0x36, 0x1b, 0xf2, 0x63, 0x4e, 0x50, 0x69, 0xc3, 0xba, 0xf6, + 0x62, 0xb3, 0xe7, 0x69, 0x1c, 0x6a, 0xf8, 0x29, 0x4a, 0x8c, 0x06, 0xe3, + 0x87, 0x58, 0x8d, 0x20, 0xc5, 0x5c, 0xd1, 0x6d, 0x68, 0xb2, 0x50, 0xda, + 0x1a, 0xe5, 0x11, 0xdc, 0x6a, 0x26, 0x92, 0xc5, 0x41, 0x50, 0xc6, 0xd1, + 0xdc, 0x7e, 0xa1, 0x87, 0x27, 0x7a, 0xfb, 0x0c, 0xd8, 0xfa, 0x9e, 0xb5, + 0x33, 0x55, 0xe6, 0x73, 0x26, 0x40, 0xd8, 0x7a, 0x4b, 0x7b, 0x54, 0xed, + 0x4d, 0x1d, 0x3d, 0x71, 0xad, 0xe5, 0x06, 0x49, 0xc2, 0x60, 0x3a, 0xd9, + 0x16, 0x32, 0x20, 0xb4, 0x6f, 0xc8, 0x44, 0x5a, 0xc3, 0x93, 0x04, 0x99, + 0x92, 0xae, 0x4a, 0x68, 0x91, 0x1d, 0x20, 0xc1, 0x68, 0x4e, 0x22, 0x62, + 0xa9, 0xc8, 0x75, 0xc9, 0x92, 0x21, 0xe7, 0x3d, 0x72, 0x41, 0xe2, 0x9f, + 0xc1, 0xf8, 0x2f, 0xe3, 0x55, 0x12, 0xcd, 0xf0, 0xc1, 0xdb, 0xac, 0x4b, + 0xe6, 0x7d, 0xb2, 0xac, 0x0b, 0xfe, 0xe1, 0xf7, 0xe0, 0x3f, 0x89, 0x97, + 0x75, 0x0c, 0x51, 0xb5, 0x5a, 0x0c, 0x06, 0x12, 0x3e, 0x67, 0x8f, 0x7b, + 0x3c, 0x8e, 0x4d, 0xaf, 0xc1, 0x75, 0x7b, 0x94, 0xbf, 0x38, 0xce, 0x8c, + 0x70, 0xbd, 0xa9, 0xa0, 0x9d, 0xea, 0x3f, 0x37, 0x5e, 0x35, 0xa0, 0x1c, + 0x6c, 0x9d, 0xcd, 0xa9, 0xb4, 0xb0, 0xfa, 0x13, 0xaf, 0x39, 0xff, 0x14, + 0x9e, 0xe1, 0x0b, 0xb3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x8c, + 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d, + 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0xea, 0x37, 0xfa, 0xfd, 0x51, 0x69, 0x13, 0x98, 0xcf, + 0xa1, 0x47, 0x05, 0x8b, 0xa3, 0xfa, 0xc4, 0x7d, 0xd1, 0xab, 0x8c, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0x2a, 0x8e, 0xdc, 0x15, 0xf2, 0x1d, 0x69, 0x64, 0x39, 0x77, 0x8f, 0xee, + 0xf4, 0x6d, 0x3f, 0x34, 0xd9, 0x85, 0xf0, 0x8c, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x21, 0x00, 0xc2, 0xae, 0x7d, 0x05, 0x21, 0x72, 0xfc, 0x2a, + 0xff, 0x82, 0xa2, 0x8f, 0xa7, 0xb0, 0x8d, 0x9c, 0xe1, 0xcf, 0xa4, 0x8c, + 0xc9, 0x7e, 0xcc, 0x25, 0x65, 0xbe, 0xcc, 0x76, 0x82, 0x67, 0x2f, 0x32, + 0x02, 0x20, 0x48, 0xc5, 0x93, 0xad, 0x61, 0x3e, 0x32, 0x8b, 0x56, 0xa6, + 0xea, 0xc4, 0x59, 0xdf, 0x63, 0x9d, 0xea, 0xfa, 0x49, 0x01, 0xb5, 0x3a, + 0x2b, 0x17, 0x57, 0xa9, 0xc6, 0xe0, 0x57, 0xde, 0x45, 0x67 }; -unsigned int ClientRSA_Cert_CA_ECC_der_len = 426; +unsigned int ClientRSA_Cert_CA_ECC_der_len = 706; diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Cert_CA-RSA.h b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Cert_CA-RSA.h index b74be1fe..4f2eceae 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Cert_CA-RSA.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Cert_CA-RSA.h @@ -1,55 +1,76 @@ unsigned char ClientRSA_Cert_CA_RSA_der[] = { - 0x30, 0x82, 0x02, 0x6a, 0x30, 0x82, 0x01, 0x52, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x03, 0xe9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, - 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, - 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, - 0x20, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, - 0x30, 0x32, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, - 0x31, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, - 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, - 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, - 0x28, 0x52, 0x53, 0x41, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xc0, 0x21, 0x29, 0x13, 0x69, 0xbb, - 0xff, 0xbb, 0x05, 0x6d, 0xd1, 0xf0, 0x29, 0x59, 0xa2, 0x62, 0x5b, 0xeb, - 0xab, 0x3a, 0xa4, 0x26, 0x38, 0x16, 0xa2, 0x33, 0x0e, 0xe4, 0xe0, 0xa5, - 0xf1, 0x06, 0xe8, 0x29, 0xf2, 0x03, 0x4a, 0x75, 0xb9, 0x87, 0xa5, 0x65, - 0x1b, 0xb4, 0x46, 0x68, 0xcf, 0x66, 0x6c, 0x11, 0xf2, 0x37, 0x5d, 0x31, - 0xc2, 0x18, 0xc1, 0xcd, 0xe4, 0x7d, 0x1d, 0x63, 0xe3, 0x5c, 0xa2, 0x93, - 0x03, 0xd6, 0x15, 0xa3, 0x5b, 0x3e, 0xd4, 0xc9, 0xba, 0xb5, 0x71, 0x6f, - 0xe8, 0x89, 0x49, 0x36, 0xba, 0xf8, 0xca, 0x82, 0x1a, 0x4a, 0x67, 0xc6, - 0x93, 0x67, 0x0d, 0x7c, 0xca, 0x67, 0x4c, 0xdf, 0x65, 0x65, 0xd9, 0x59, - 0x1d, 0xe1, 0xa8, 0x28, 0xf4, 0xdb, 0xea, 0x9a, 0xdc, 0xe8, 0xa4, 0x37, - 0xdb, 0x8d, 0x24, 0x34, 0x50, 0x9a, 0x21, 0x22, 0xe2, 0x40, 0xda, 0xa4, - 0x43, 0xd1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x97, 0x4f, 0x15, 0x5e, 0x8f, 0x84, - 0x25, 0x85, 0x62, 0x09, 0x46, 0x8e, 0x1d, 0x0f, 0x3e, 0x29, 0x46, 0x87, - 0xc8, 0x95, 0xbd, 0xcf, 0x8e, 0x8f, 0x99, 0x9c, 0x16, 0x47, 0x6f, 0x43, - 0x07, 0x14, 0x19, 0x99, 0x80, 0xb6, 0x35, 0x39, 0xba, 0x29, 0xd1, 0xe5, - 0x84, 0x18, 0x67, 0xd6, 0x0f, 0x06, 0x15, 0x62, 0xca, 0x20, 0x19, 0x30, - 0xe4, 0x90, 0x57, 0x2d, 0x18, 0x30, 0x20, 0x09, 0x03, 0x0a, 0x7e, 0xd0, - 0xf9, 0xb6, 0xbd, 0x10, 0x69, 0x9e, 0x00, 0x71, 0x40, 0x8a, 0x9c, 0x44, - 0xc2, 0xa4, 0xd0, 0x70, 0xfd, 0x43, 0x32, 0xbf, 0x4f, 0xcc, 0xc6, 0xca, - 0x4a, 0x16, 0xb2, 0xd0, 0x0b, 0x09, 0xde, 0xb9, 0x8a, 0x65, 0xba, 0x85, - 0xc1, 0x13, 0x94, 0x92, 0x1f, 0x0d, 0xc9, 0xe0, 0x5f, 0x25, 0xd4, 0x28, - 0xf0, 0x92, 0xc9, 0xda, 0x8c, 0x6f, 0x40, 0xe6, 0x4e, 0x37, 0x46, 0xa4, - 0x45, 0x3b, 0x93, 0xda, 0x6e, 0x01, 0xc2, 0xd5, 0xe1, 0x41, 0x48, 0x9a, - 0x16, 0x26, 0x62, 0x6d, 0xa3, 0x6e, 0x99, 0x7b, 0xea, 0xce, 0xb6, 0xba, - 0x44, 0xbd, 0x9d, 0x18, 0x14, 0x55, 0xa4, 0xdd, 0xb0, 0x87, 0x54, 0x7c, - 0x6c, 0xef, 0x69, 0xee, 0x17, 0x6c, 0x74, 0x58, 0xf2, 0x46, 0x02, 0x6e, - 0xf0, 0xe7, 0x41, 0xea, 0x62, 0xdc, 0x11, 0x1a, 0xaa, 0x8e, 0x56, 0xb9, - 0x7b, 0x08, 0x00, 0x18, 0xed, 0x6b, 0xe9, 0x38, 0x29, 0xcc, 0xe1, 0x9c, - 0xbd, 0x61, 0x57, 0x96, 0xa2, 0x2b, 0xa5, 0x81, 0x09, 0xd3, 0x12, 0x77, - 0xb0, 0x3b, 0xd8, 0xb5, 0x83, 0xde, 0x9e, 0x41, 0xec, 0x3f, 0x2d, 0x99, - 0x65, 0x6a, 0x4e, 0x50, 0xca, 0xdb, 0xc2, 0x5a, 0xea, 0x11, 0xed, 0x61, - 0x16, 0x49, 0xa3, 0xd9, 0x06, 0x68, 0x23, 0x13, 0xc1, 0x26, 0xec, 0xb2, - 0xcf, 0x5d, 0xf9, 0x26, 0xc1, 0xaf, 0x67, 0x0c, 0x4b, 0xe6 + 0x30, 0x82, 0x03, 0x68, 0x30, 0x82, 0x02, 0x50, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x00, 0xb9, 0x18, 0x42, 0xfe, 0xdf, 0xe7, 0x25, 0x9c, + 0xce, 0xfa, 0xd7, 0xd0, 0xe8, 0x56, 0xe3, 0xd5, 0xd3, 0x20, 0x95, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, + 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, + 0x35, 0x32, 0x36, 0x30, 0x31, 0x31, 0x34, 0x34, 0x35, 0x5a, 0x18, 0x0f, + 0x32, 0x30, 0x35, 0x35, 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x31, 0x34, + 0x34, 0x35, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x0c, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, 0xa7, 0x97, 0x26, 0x3d, 0x78, 0x29, 0xdb, 0xd8, + 0x11, 0xc9, 0xb2, 0xf6, 0xbe, 0x36, 0xa3, 0xe5, 0xf1, 0xa4, 0xb3, 0xee, + 0x87, 0xcd, 0xbf, 0xba, 0xb3, 0x74, 0x38, 0x2a, 0xde, 0x22, 0x4c, 0xa0, + 0x3e, 0xcb, 0x2a, 0xbb, 0xdd, 0x8a, 0x07, 0xb9, 0xf6, 0x70, 0x6d, 0x6f, + 0x27, 0x09, 0x4b, 0xdd, 0xf3, 0x68, 0xd4, 0x93, 0x5b, 0xbf, 0x40, 0x4c, + 0x50, 0x27, 0xad, 0xa7, 0x8e, 0x15, 0x36, 0x1b, 0xf2, 0x63, 0x4e, 0x50, + 0x69, 0xc3, 0xba, 0xf6, 0x62, 0xb3, 0xe7, 0x69, 0x1c, 0x6a, 0xf8, 0x29, + 0x4a, 0x8c, 0x06, 0xe3, 0x87, 0x58, 0x8d, 0x20, 0xc5, 0x5c, 0xd1, 0x6d, + 0x68, 0xb2, 0x50, 0xda, 0x1a, 0xe5, 0x11, 0xdc, 0x6a, 0x26, 0x92, 0xc5, + 0x41, 0x50, 0xc6, 0xd1, 0xdc, 0x7e, 0xa1, 0x87, 0x27, 0x7a, 0xfb, 0x0c, + 0xd8, 0xfa, 0x9e, 0xb5, 0x33, 0x55, 0xe6, 0x73, 0x26, 0x40, 0xd8, 0x7a, + 0x4b, 0x7b, 0x54, 0xed, 0x4d, 0x1d, 0x3d, 0x71, 0xad, 0xe5, 0x06, 0x49, + 0xc2, 0x60, 0x3a, 0xd9, 0x16, 0x32, 0x20, 0xb4, 0x6f, 0xc8, 0x44, 0x5a, + 0xc3, 0x93, 0x04, 0x99, 0x92, 0xae, 0x4a, 0x68, 0x91, 0x1d, 0x20, 0xc1, + 0x68, 0x4e, 0x22, 0x62, 0xa9, 0xc8, 0x75, 0xc9, 0x92, 0x21, 0xe7, 0x3d, + 0x72, 0x41, 0xe2, 0x9f, 0xc1, 0xf8, 0x2f, 0xe3, 0x55, 0x12, 0xcd, 0xf0, + 0xc1, 0xdb, 0xac, 0x4b, 0xe6, 0x7d, 0xb2, 0xac, 0x0b, 0xfe, 0xe1, 0xf7, + 0xe0, 0x3f, 0x89, 0x97, 0x75, 0x0c, 0x51, 0xb5, 0x5a, 0x0c, 0x06, 0x12, + 0x3e, 0x67, 0x8f, 0x7b, 0x3c, 0x8e, 0x4d, 0xaf, 0xc1, 0x75, 0x7b, 0x94, + 0xbf, 0x38, 0xce, 0x8c, 0x70, 0xbd, 0xa9, 0xa0, 0x9d, 0xea, 0x3f, 0x37, + 0x5e, 0x35, 0xa0, 0x1c, 0x6c, 0x9d, 0xcd, 0xa9, 0xb4, 0xb0, 0xfa, 0x13, + 0xaf, 0x39, 0xff, 0x14, 0x9e, 0xe1, 0x0b, 0xb3, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x75, 0x30, 0x73, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, + 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xea, 0x37, 0xfa, 0xfd, 0x51, + 0x69, 0x13, 0x98, 0xcf, 0xa1, 0x47, 0x05, 0x8b, 0xa3, 0xfa, 0xc4, 0x7d, + 0xd1, 0xab, 0x8c, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x5d, 0xa7, 0x1b, 0x3b, 0x57, 0xd2, 0x0e, 0x08, + 0x1e, 0xaa, 0x47, 0xcf, 0x03, 0x34, 0x68, 0xbe, 0x53, 0x00, 0xd9, 0x64, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb2, 0x6a, 0x95, 0x8d, + 0xf8, 0x09, 0xc6, 0x27, 0x8a, 0xbb, 0x61, 0x8a, 0xa7, 0x93, 0x4d, 0xd1, + 0x81, 0x36, 0xd8, 0x2e, 0x33, 0x97, 0x71, 0x0a, 0x36, 0x26, 0x2d, 0x4f, + 0x3e, 0x4d, 0x89, 0x78, 0x67, 0xa6, 0xf8, 0x79, 0x40, 0xbe, 0xea, 0xeb, + 0x64, 0x9c, 0x63, 0x11, 0x9a, 0xf8, 0xbd, 0xe4, 0xfb, 0xe7, 0x5a, 0x91, + 0x39, 0xa0, 0x41, 0x76, 0x81, 0x29, 0xcd, 0x92, 0x7e, 0xbc, 0x02, 0x3b, + 0x5d, 0x40, 0xfe, 0xaf, 0x12, 0x50, 0xfb, 0x6e, 0x19, 0x49, 0x67, 0xf2, + 0x1c, 0x21, 0x8d, 0x4a, 0x06, 0x52, 0x0d, 0xfa, 0x81, 0xa9, 0x6d, 0x57, + 0xcf, 0xc8, 0xf0, 0x52, 0x99, 0x44, 0xa7, 0x37, 0xb2, 0x80, 0xc8, 0xa9, + 0x90, 0x60, 0x89, 0x35, 0x47, 0x1e, 0xf1, 0xed, 0x02, 0xc0, 0x68, 0x2b, + 0x27, 0x74, 0x17, 0xc8, 0x55, 0xb9, 0x02, 0x8c, 0xf4, 0x4d, 0xbc, 0x94, + 0x90, 0x0a, 0x45, 0x34, 0xf7, 0x43, 0x01, 0x3c, 0xb1, 0x4b, 0xd3, 0x59, + 0x6c, 0xcc, 0x64, 0x2e, 0xde, 0x8e, 0x14, 0xd0, 0xbc, 0xcb, 0x11, 0xd0, + 0x43, 0x95, 0x7d, 0x56, 0x5c, 0x51, 0x27, 0x6f, 0x4c, 0xbb, 0xc3, 0x3b, + 0x7d, 0xc9, 0x95, 0x09, 0x60, 0x5b, 0x05, 0x6a, 0x9c, 0x61, 0x16, 0xab, + 0x28, 0xd2, 0x09, 0xc3, 0x4a, 0x7d, 0xba, 0x3e, 0x52, 0xe9, 0xfa, 0x18, + 0xc1, 0x0c, 0x88, 0x83, 0xbc, 0x6e, 0x7c, 0x08, 0x48, 0x99, 0x76, 0xea, + 0x08, 0x8d, 0xa9, 0x5a, 0x4b, 0x31, 0xb6, 0x84, 0xf7, 0xfd, 0x73, 0x28, + 0xd6, 0xfb, 0x5e, 0x99, 0x6f, 0xd7, 0x22, 0x5f, 0xad, 0x0c, 0x9b, 0xf0, + 0x91, 0xc7, 0xd5, 0x37, 0xd1, 0x21, 0x11, 0x0f, 0x14, 0x88, 0xea, 0x4d, + 0x14, 0x39, 0xd0, 0x92, 0x4d, 0x96, 0x10, 0x42, 0xd7, 0x5f, 0xe2, 0xd9, + 0x84, 0x96, 0xce, 0xbf, 0xab, 0x3f, 0xd0, 0x2f, 0x8b, 0x9b, 0x75, 0x77 }; -unsigned int ClientRSA_Cert_CA_RSA_der_len = 622; +unsigned int ClientRSA_Cert_CA_RSA_der_len = 876; diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Key.h b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Key.h index 2dbeed07..54c108f1 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Key.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/ClientRSA_Key.h @@ -1,54 +1,103 @@ unsigned char ClientRSA_Key_der[] = { - 0x30, 0x82, 0x02, 0x5b, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xc0, - 0x21, 0x29, 0x13, 0x69, 0xbb, 0xff, 0xbb, 0x05, 0x6d, 0xd1, 0xf0, 0x29, - 0x59, 0xa2, 0x62, 0x5b, 0xeb, 0xab, 0x3a, 0xa4, 0x26, 0x38, 0x16, 0xa2, - 0x33, 0x0e, 0xe4, 0xe0, 0xa5, 0xf1, 0x06, 0xe8, 0x29, 0xf2, 0x03, 0x4a, - 0x75, 0xb9, 0x87, 0xa5, 0x65, 0x1b, 0xb4, 0x46, 0x68, 0xcf, 0x66, 0x6c, - 0x11, 0xf2, 0x37, 0x5d, 0x31, 0xc2, 0x18, 0xc1, 0xcd, 0xe4, 0x7d, 0x1d, - 0x63, 0xe3, 0x5c, 0xa2, 0x93, 0x03, 0xd6, 0x15, 0xa3, 0x5b, 0x3e, 0xd4, - 0xc9, 0xba, 0xb5, 0x71, 0x6f, 0xe8, 0x89, 0x49, 0x36, 0xba, 0xf8, 0xca, - 0x82, 0x1a, 0x4a, 0x67, 0xc6, 0x93, 0x67, 0x0d, 0x7c, 0xca, 0x67, 0x4c, - 0xdf, 0x65, 0x65, 0xd9, 0x59, 0x1d, 0xe1, 0xa8, 0x28, 0xf4, 0xdb, 0xea, - 0x9a, 0xdc, 0xe8, 0xa4, 0x37, 0xdb, 0x8d, 0x24, 0x34, 0x50, 0x9a, 0x21, - 0x22, 0xe2, 0x40, 0xda, 0xa4, 0x43, 0xd1, 0x02, 0x03, 0x01, 0x00, 0x01, - 0x02, 0x81, 0x80, 0x12, 0xc6, 0xea, 0xe1, 0xc7, 0xd2, 0xa4, 0xd2, 0x9d, - 0x5c, 0x37, 0x49, 0x56, 0x71, 0x39, 0x2a, 0x8d, 0xbb, 0x41, 0x97, 0xd0, - 0x95, 0x1f, 0xa4, 0x2e, 0xa3, 0xf8, 0xcf, 0xab, 0x98, 0xec, 0x2e, 0x75, - 0xa0, 0x2b, 0xd3, 0xe0, 0x82, 0x12, 0xe8, 0xcb, 0xe4, 0x4e, 0xc9, 0xd6, - 0x9b, 0xc5, 0xb1, 0x47, 0xdc, 0x95, 0x24, 0x8e, 0x0a, 0x1f, 0xe3, 0x15, - 0x85, 0xce, 0xcf, 0xdf, 0x80, 0x74, 0xa6, 0xdc, 0x9b, 0x94, 0xa3, 0x9b, - 0x43, 0x49, 0xf5, 0x0c, 0xfe, 0xa3, 0xae, 0x30, 0x35, 0x5f, 0xc9, 0xe1, - 0xbd, 0xa2, 0xc5, 0x5b, 0x9a, 0x4c, 0xcf, 0xae, 0x34, 0x9c, 0xcc, 0xa4, - 0x74, 0xcb, 0x3c, 0xa9, 0xa5, 0x58, 0x75, 0xf3, 0x70, 0x72, 0xf2, 0x81, - 0xce, 0xc8, 0x6f, 0x60, 0x51, 0x45, 0xea, 0xe9, 0x9d, 0x86, 0x43, 0x80, - 0xdd, 0x93, 0xb9, 0x22, 0xe0, 0x6e, 0x02, 0xcc, 0x89, 0x66, 0x31, 0x02, - 0x41, 0x00, 0xeb, 0x57, 0xad, 0x0a, 0xf2, 0x25, 0xa8, 0xd5, 0x5d, 0x24, - 0xcf, 0x39, 0x18, 0xf7, 0xfd, 0x95, 0x10, 0x06, 0x5b, 0x9f, 0x8e, 0x21, - 0x9c, 0x5b, 0x3b, 0xd2, 0xb9, 0xce, 0x29, 0x37, 0xc9, 0x7f, 0x14, 0x48, - 0xca, 0x83, 0x6a, 0x08, 0xd7, 0xb6, 0x2e, 0xc8, 0x34, 0x95, 0x5b, 0x56, - 0x3b, 0xfe, 0xfe, 0xf8, 0x8a, 0x25, 0xc5, 0x60, 0x43, 0xee, 0x4f, 0x18, - 0x58, 0x13, 0xf6, 0x20, 0x6f, 0x3d, 0x02, 0x41, 0x00, 0xd0, 0xfe, 0x74, - 0xec, 0x28, 0x21, 0xae, 0x14, 0xef, 0x71, 0x69, 0xc1, 0x04, 0x31, 0x17, - 0xde, 0x61, 0x18, 0xd9, 0xb1, 0x78, 0xd2, 0xc9, 0x3c, 0x78, 0x7b, 0x24, - 0xe3, 0x62, 0x1d, 0x20, 0x81, 0x10, 0xfa, 0x9a, 0x45, 0xeb, 0xcc, 0xe1, - 0x9c, 0x32, 0x24, 0x59, 0x3a, 0xd1, 0x97, 0x1d, 0x5e, 0x36, 0x8e, 0x6b, - 0xc8, 0x35, 0xa8, 0x42, 0x99, 0xbb, 0x09, 0x58, 0x5d, 0x79, 0x07, 0xf0, - 0x25, 0x02, 0x40, 0x51, 0xf7, 0xc5, 0x93, 0x6c, 0x67, 0x65, 0x78, 0x7a, - 0xea, 0x99, 0x2a, 0x3f, 0xe2, 0x0f, 0xf6, 0x5d, 0x10, 0x79, 0xd5, 0x06, - 0xc1, 0xfa, 0x1d, 0x64, 0xa6, 0xae, 0x84, 0x79, 0xa2, 0xae, 0x91, 0x8e, - 0x55, 0x14, 0x03, 0xd5, 0x68, 0xa3, 0x09, 0x17, 0x1e, 0x30, 0x02, 0x5d, - 0x3f, 0x99, 0xc1, 0xe4, 0xb8, 0x58, 0x15, 0x73, 0xbb, 0x65, 0xad, 0x98, - 0xea, 0xd7, 0xb2, 0x8c, 0x25, 0x1b, 0xd9, 0x02, 0x40, 0x2e, 0xaa, 0xc3, - 0x1d, 0x00, 0x91, 0x14, 0xb8, 0x24, 0x07, 0x65, 0x1f, 0xee, 0x79, 0xaf, - 0xe4, 0xbe, 0x35, 0xb8, 0x56, 0x82, 0xae, 0x3e, 0xb5, 0x3c, 0x09, 0xf3, - 0x60, 0xba, 0xc5, 0xda, 0x3e, 0x37, 0xb6, 0x5d, 0xc0, 0x83, 0x38, 0xca, - 0xa0, 0x00, 0x2a, 0x51, 0xaa, 0x6a, 0xa6, 0x9d, 0xae, 0x2d, 0xec, 0x7b, - 0x70, 0xc7, 0x5a, 0x7d, 0x14, 0xaa, 0xc9, 0x19, 0x6c, 0x35, 0xdc, 0x69, - 0xe9, 0x02, 0x40, 0x1f, 0xd4, 0x7c, 0xf6, 0x2a, 0x93, 0xa2, 0x54, 0x38, - 0xcb, 0xd1, 0xf7, 0x16, 0x12, 0x98, 0xf2, 0x2b, 0xfc, 0xda, 0xf6, 0x0b, - 0x39, 0xca, 0xef, 0xd5, 0x50, 0x66, 0x1a, 0xca, 0x3f, 0x08, 0x94, 0xa6, - 0x08, 0x6d, 0xae, 0x3d, 0x2d, 0x8b, 0xde, 0x5f, 0x01, 0x5a, 0x79, 0x2a, - 0x9c, 0xef, 0xa7, 0xba, 0xed, 0xb7, 0xaf, 0x9e, 0x16, 0x0c, 0xe3, 0xb1, - 0xea, 0x55, 0x90, 0x8b, 0x28, 0x93, 0xd2 + 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xa7, 0x97, 0x26, 0x3d, 0x78, 0x29, 0xdb, 0xd8, 0x11, 0xc9, 0xb2, 0xf6, + 0xbe, 0x36, 0xa3, 0xe5, 0xf1, 0xa4, 0xb3, 0xee, 0x87, 0xcd, 0xbf, 0xba, + 0xb3, 0x74, 0x38, 0x2a, 0xde, 0x22, 0x4c, 0xa0, 0x3e, 0xcb, 0x2a, 0xbb, + 0xdd, 0x8a, 0x07, 0xb9, 0xf6, 0x70, 0x6d, 0x6f, 0x27, 0x09, 0x4b, 0xdd, + 0xf3, 0x68, 0xd4, 0x93, 0x5b, 0xbf, 0x40, 0x4c, 0x50, 0x27, 0xad, 0xa7, + 0x8e, 0x15, 0x36, 0x1b, 0xf2, 0x63, 0x4e, 0x50, 0x69, 0xc3, 0xba, 0xf6, + 0x62, 0xb3, 0xe7, 0x69, 0x1c, 0x6a, 0xf8, 0x29, 0x4a, 0x8c, 0x06, 0xe3, + 0x87, 0x58, 0x8d, 0x20, 0xc5, 0x5c, 0xd1, 0x6d, 0x68, 0xb2, 0x50, 0xda, + 0x1a, 0xe5, 0x11, 0xdc, 0x6a, 0x26, 0x92, 0xc5, 0x41, 0x50, 0xc6, 0xd1, + 0xdc, 0x7e, 0xa1, 0x87, 0x27, 0x7a, 0xfb, 0x0c, 0xd8, 0xfa, 0x9e, 0xb5, + 0x33, 0x55, 0xe6, 0x73, 0x26, 0x40, 0xd8, 0x7a, 0x4b, 0x7b, 0x54, 0xed, + 0x4d, 0x1d, 0x3d, 0x71, 0xad, 0xe5, 0x06, 0x49, 0xc2, 0x60, 0x3a, 0xd9, + 0x16, 0x32, 0x20, 0xb4, 0x6f, 0xc8, 0x44, 0x5a, 0xc3, 0x93, 0x04, 0x99, + 0x92, 0xae, 0x4a, 0x68, 0x91, 0x1d, 0x20, 0xc1, 0x68, 0x4e, 0x22, 0x62, + 0xa9, 0xc8, 0x75, 0xc9, 0x92, 0x21, 0xe7, 0x3d, 0x72, 0x41, 0xe2, 0x9f, + 0xc1, 0xf8, 0x2f, 0xe3, 0x55, 0x12, 0xcd, 0xf0, 0xc1, 0xdb, 0xac, 0x4b, + 0xe6, 0x7d, 0xb2, 0xac, 0x0b, 0xfe, 0xe1, 0xf7, 0xe0, 0x3f, 0x89, 0x97, + 0x75, 0x0c, 0x51, 0xb5, 0x5a, 0x0c, 0x06, 0x12, 0x3e, 0x67, 0x8f, 0x7b, + 0x3c, 0x8e, 0x4d, 0xaf, 0xc1, 0x75, 0x7b, 0x94, 0xbf, 0x38, 0xce, 0x8c, + 0x70, 0xbd, 0xa9, 0xa0, 0x9d, 0xea, 0x3f, 0x37, 0x5e, 0x35, 0xa0, 0x1c, + 0x6c, 0x9d, 0xcd, 0xa9, 0xb4, 0xb0, 0xfa, 0x13, 0xaf, 0x39, 0xff, 0x14, + 0x9e, 0xe1, 0x0b, 0xb3, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x00, 0x34, 0x1d, 0x90, 0xca, 0xb4, 0xbf, 0x6f, 0x9a, 0x35, 0x8d, 0xdf, + 0x95, 0x53, 0x79, 0x72, 0x66, 0x63, 0x4a, 0xb0, 0x99, 0x90, 0xa9, 0xae, + 0xe1, 0xc4, 0x44, 0x73, 0xe3, 0x00, 0xc8, 0xf1, 0xc3, 0x33, 0x43, 0xc2, + 0xba, 0x41, 0x1e, 0x57, 0x60, 0xc0, 0xfe, 0x1d, 0x49, 0xdf, 0x7d, 0xc8, + 0x95, 0xf0, 0xc7, 0xbc, 0xb3, 0x46, 0x68, 0xa6, 0xfa, 0x14, 0x43, 0x02, + 0x81, 0x84, 0x71, 0x9c, 0x2d, 0xfc, 0xa6, 0x5d, 0x08, 0x2c, 0x9b, 0xad, + 0x5c, 0x49, 0x3d, 0x60, 0xcd, 0x13, 0x05, 0x40, 0xbe, 0xb6, 0x6b, 0xed, + 0x08, 0x7c, 0x62, 0x51, 0x20, 0xcb, 0xbf, 0x1d, 0x71, 0x44, 0x89, 0x8f, + 0x13, 0x04, 0x22, 0x0f, 0xf7, 0xd7, 0x1a, 0xbf, 0xb1, 0x8f, 0xaa, 0x2a, + 0xe9, 0xc0, 0x03, 0xb0, 0xff, 0x72, 0x8b, 0x8f, 0xde, 0x62, 0xeb, 0x2c, + 0xc7, 0x74, 0x7b, 0x55, 0xfa, 0xa0, 0xfe, 0xb1, 0x52, 0x75, 0x94, 0x64, + 0xa5, 0x3e, 0x44, 0xec, 0xde, 0x4a, 0xfb, 0x32, 0x07, 0x00, 0xa9, 0xd1, + 0xe6, 0x73, 0x6e, 0x49, 0x35, 0x8f, 0x4b, 0x88, 0x88, 0x18, 0x15, 0xd4, + 0xb5, 0x00, 0xa5, 0x80, 0x53, 0xcc, 0x2d, 0x38, 0x7c, 0x86, 0xd9, 0x27, + 0x11, 0x10, 0x2b, 0xd1, 0xdd, 0xc1, 0xb4, 0xcf, 0x5b, 0xe2, 0x48, 0x52, + 0x3d, 0x9d, 0x6b, 0x6c, 0x6e, 0x9b, 0x32, 0x86, 0x37, 0xba, 0x78, 0xbe, + 0x0e, 0xb5, 0xa4, 0xd3, 0x50, 0xfd, 0x05, 0x28, 0xd8, 0xe8, 0x22, 0xf7, + 0x64, 0x6e, 0xbe, 0xbd, 0x6f, 0xd1, 0xd8, 0x4c, 0x54, 0xb8, 0x11, 0x7f, + 0xee, 0x91, 0xf7, 0x0c, 0xb3, 0xcd, 0x10, 0x64, 0xa5, 0x49, 0x73, 0xd7, + 0xc1, 0x12, 0x5f, 0x1f, 0x4d, 0x93, 0xc8, 0x3a, 0x5c, 0x5c, 0xce, 0x29, + 0xc8, 0xe1, 0x41, 0xdc, 0x95, 0xe1, 0xf0, 0x41, 0x31, 0x48, 0x5c, 0x78, + 0x4f, 0x5f, 0x1c, 0x75, 0x61, 0x02, 0x81, 0x81, 0x00, 0xd7, 0x07, 0xcb, + 0x85, 0xbe, 0x41, 0xca, 0x4b, 0x61, 0xe4, 0x8a, 0xf3, 0xd4, 0xec, 0xb5, + 0x98, 0x0d, 0xb4, 0x9d, 0xb9, 0x2e, 0xf5, 0x33, 0xda, 0x30, 0xd9, 0x03, + 0x32, 0x04, 0x54, 0x79, 0x71, 0xb9, 0xbd, 0x4c, 0x4d, 0xc7, 0xd4, 0x38, + 0xb1, 0xb4, 0xf3, 0xdc, 0x7b, 0x87, 0x84, 0x04, 0xcc, 0x60, 0x34, 0x88, + 0xbb, 0x1d, 0x61, 0x51, 0x96, 0x43, 0x24, 0x98, 0x35, 0xa4, 0x81, 0xbb, + 0x25, 0x15, 0xc9, 0x08, 0x87, 0xf6, 0x13, 0xa7, 0x00, 0x26, 0x5a, 0x1a, + 0xad, 0x07, 0x55, 0xfb, 0x4b, 0x54, 0x2b, 0x53, 0xe2, 0x39, 0xd1, 0xd3, + 0x1c, 0x6c, 0xb4, 0x98, 0xfe, 0x3d, 0x1f, 0x2f, 0x60, 0xd9, 0xbd, 0xf4, + 0x3a, 0x4c, 0x48, 0x85, 0xab, 0x23, 0xc5, 0x3c, 0x13, 0xba, 0x2c, 0xf7, + 0x03, 0x7a, 0x75, 0x49, 0xb8, 0x1e, 0xec, 0x25, 0x23, 0x90, 0x57, 0x55, + 0xe3, 0x2d, 0x45, 0x00, 0xbf, 0x02, 0x81, 0x81, 0x00, 0xc7, 0x85, 0x72, + 0x45, 0x67, 0xa3, 0x7c, 0xc1, 0x9b, 0x6b, 0xcb, 0x0c, 0x22, 0x32, 0xd2, + 0x94, 0x05, 0x91, 0x19, 0x6a, 0xfe, 0x15, 0xbe, 0x01, 0x0a, 0xf0, 0x83, + 0x00, 0x7c, 0x61, 0xbe, 0x27, 0xf9, 0x94, 0x20, 0x80, 0x4c, 0x0a, 0xff, + 0x51, 0xb3, 0x66, 0x62, 0x9e, 0x3d, 0x07, 0xe3, 0x89, 0xd2, 0x23, 0x33, + 0x88, 0x18, 0x64, 0x4c, 0x5c, 0xf3, 0xc4, 0xe3, 0xf4, 0x15, 0x8e, 0xb1, + 0x65, 0xad, 0x09, 0x91, 0x32, 0x4d, 0x02, 0xd2, 0x7b, 0x4e, 0x6c, 0x4c, + 0x34, 0x29, 0x70, 0x71, 0xaa, 0x4b, 0xb7, 0x9e, 0x47, 0x13, 0x54, 0x44, + 0x21, 0xe4, 0x07, 0x58, 0x68, 0x3c, 0xaf, 0x4f, 0x99, 0x2a, 0x26, 0xad, + 0x3d, 0x43, 0x8e, 0x98, 0x04, 0x4f, 0x9d, 0x45, 0xce, 0xaf, 0xb5, 0x92, + 0x8c, 0x9f, 0x6b, 0x85, 0x00, 0x86, 0xc4, 0xd7, 0xbb, 0x7e, 0x87, 0xcf, + 0x14, 0x82, 0x7e, 0x7e, 0x0d, 0x02, 0x81, 0x80, 0x26, 0xe0, 0x90, 0xea, + 0x80, 0x68, 0x92, 0xb3, 0xa8, 0x62, 0x52, 0xc1, 0x1d, 0x09, 0x23, 0x17, + 0xf7, 0xba, 0x65, 0x1d, 0xdb, 0x20, 0x98, 0x1c, 0x65, 0xe2, 0x86, 0x92, + 0x5f, 0x78, 0x0a, 0x71, 0x06, 0x5c, 0xf4, 0x53, 0xc7, 0xc2, 0x55, 0xf1, + 0xc3, 0x3e, 0xa7, 0xe9, 0x69, 0xa9, 0xf3, 0xd8, 0x23, 0xb8, 0xbb, 0xd3, + 0xe0, 0xce, 0xfc, 0x9a, 0x47, 0x4f, 0x71, 0x79, 0x99, 0x61, 0x9f, 0x3d, + 0x68, 0x3f, 0xed, 0x9b, 0xef, 0x60, 0xc4, 0x3b, 0xe1, 0xb3, 0x3e, 0xc9, + 0x73, 0xdf, 0x16, 0xcd, 0x1a, 0xcd, 0xae, 0x9f, 0xe3, 0x46, 0x4d, 0x7e, + 0x01, 0x25, 0x71, 0xd7, 0xdd, 0xa3, 0x2a, 0xc4, 0xbe, 0xf9, 0x7a, 0x13, + 0xa4, 0x41, 0x24, 0x71, 0xb9, 0xc8, 0xea, 0x40, 0xc2, 0xd3, 0x68, 0x61, + 0xa7, 0x9d, 0x57, 0x13, 0xc3, 0xfb, 0x7c, 0x07, 0x7f, 0x0c, 0x5b, 0x49, + 0xf4, 0xa0, 0x5a, 0x2f, 0x02, 0x81, 0x81, 0x00, 0x88, 0xa8, 0x46, 0x54, + 0x73, 0x5f, 0xef, 0x1b, 0x4c, 0xb0, 0xd0, 0x2a, 0x47, 0x62, 0x38, 0x09, + 0x5a, 0xa6, 0xbf, 0x9a, 0x20, 0xde, 0x13, 0x7d, 0xf3, 0x58, 0x38, 0xe2, + 0x24, 0x4f, 0x6e, 0x47, 0x43, 0x12, 0xca, 0x10, 0x16, 0x05, 0x92, 0x4b, + 0x0b, 0x6d, 0x9d, 0x2e, 0x74, 0xee, 0xea, 0x52, 0x83, 0xb3, 0xc8, 0x9f, + 0xf6, 0xd4, 0xfb, 0xd8, 0xce, 0xbe, 0x94, 0xc3, 0xa1, 0xe0, 0x52, 0x71, + 0x29, 0xcb, 0xdb, 0xbf, 0x70, 0x2f, 0xf6, 0xaa, 0xae, 0x54, 0x4e, 0xfd, + 0x8b, 0x44, 0x91, 0x15, 0xeb, 0x36, 0xa1, 0x1a, 0x5d, 0x8a, 0xe1, 0xff, + 0xb4, 0x87, 0xb3, 0x6d, 0xf1, 0xe2, 0xc1, 0xca, 0x4e, 0xac, 0x9f, 0x0b, + 0xcf, 0x31, 0xe3, 0xbd, 0x50, 0x2a, 0x90, 0x9d, 0xb8, 0x8b, 0xcd, 0x0c, + 0xb4, 0x44, 0x98, 0x9c, 0x7b, 0xb2, 0x67, 0x70, 0xec, 0x81, 0x68, 0xbc, + 0xcb, 0x84, 0x88, 0x21, 0x02, 0x81, 0x80, 0x2d, 0x42, 0x9a, 0x79, 0x98, + 0x8a, 0x3d, 0xc7, 0xed, 0x2f, 0xab, 0x40, 0x2f, 0x26, 0xc3, 0xf6, 0xc7, + 0x79, 0x8d, 0x04, 0x6c, 0x71, 0x92, 0xbb, 0x6b, 0x2f, 0xde, 0x5b, 0xe6, + 0xff, 0x51, 0xc0, 0x63, 0xdc, 0xd0, 0xe4, 0x12, 0x93, 0x4d, 0xfb, 0x7e, + 0x27, 0x14, 0x98, 0x82, 0x03, 0x0b, 0x05, 0xb7, 0xd0, 0x7a, 0xb0, 0x0d, + 0xbc, 0x9e, 0xbc, 0xfa, 0xe9, 0xce, 0x05, 0x14, 0xfa, 0xe1, 0xaa, 0x27, + 0x2d, 0x8e, 0xd2, 0xe3, 0xfe, 0xb8, 0x74, 0x50, 0xa9, 0x9c, 0x16, 0xa2, + 0xe4, 0x79, 0x53, 0x2a, 0xb7, 0x32, 0xe4, 0xae, 0x32, 0xa6, 0xba, 0x5d, + 0x86, 0xdd, 0x1c, 0x66, 0xb1, 0x18, 0xaf, 0xc5, 0xfe, 0x44, 0xb9, 0xfb, + 0xe5, 0x5a, 0x5a, 0x1e, 0x45, 0x4a, 0x8b, 0xec, 0x3c, 0x7d, 0xed, 0xc0, + 0x02, 0x53, 0xa5, 0xb1, 0x5c, 0xdb, 0xf6, 0x25, 0xa0, 0xeb, 0xee, 0x16, + 0x84, 0x79, 0xde }; -unsigned int ClientRSA_Key_der_len = 607; +unsigned int ClientRSA_Key_der_len = 1191; diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerECC.Cert.CA-ECC.der b/OSX/libsecurity_ssl/regressions/test-certs/ServerECC.Cert.CA-ECC.der index d5d2420b1b637bbba7c1b553c1422884666165bf..55f266622f034e6e234bb2f3f2e6fe07915380e2 100644 GIT binary patch delta 315 zcmaFN^o?21po#Gl5YJq|%*4pVB&;J4?a;GX-sXh)x`cgo%CDs=ry6jvacH%9oU>(N zW|}CiBV%D;YGh_$Xk=<+5GBEHWMFD)U}|U%5tx`fx4yB*ps~|{hmAQ@R+y3TKMRuq zg8?6i#}DEG4PjkiAPnNGvhaY+)@Ea5Wo2h(G!Ov^3bODTa5r)0TQWaJl@7|4P| z`B=nQM55HoL?5r>)a01D^ZdpA?he9Q$Nn40gQS&NBn-qFM6~+uh<-|u%}lW@?|=6t z*WTo2>xUj>=QF!A7`QMg1U8AdbK2)z+tX;*qPFFW|IG8MlN+49H`kl-@4i*;oXez; l-rC=H{gk|_iUB8A!pC>tS-RfO7Cf=*%x$(y5}P~{OaTyLUCICe delta 167 zcmeyy{Fq7FpouXah}jk}GchtTF|rtNvaxHmd7QIlVVtO^BV%e{Y-DU;ZfIa+7A3)N zWMB#uFoX(BESsCmYrqZE!5k_p%)(^AfTWq(gTcU+Ns(dEagOJw&X(-VJ36Cu!(7)p zQVIKPo2E_UVM|xjqxpdo E0I$?C;{X5v diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerECC.Cert.CA-ECC.pem b/OSX/libsecurity_ssl/regressions/test-certs/ServerECC.Cert.CA-ECC.pem index ae9c7f4f..4466812a 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ServerECC.Cert.CA-ECC.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/ServerECC.Cert.CA-ECC.pem @@ -1,10 +1,54 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 2c:10:5b:40:8c:b3:1f:3c:c8:37:ae:60:be:7e:23:eb:1a:79:95 + Signature Algorithm: ecdsa-with-SHA256 + Issuer: CN=SecurityTest CA Cert (ECC) + Validity + Not Before: May 26 01:25:20 2018 GMT + Not After : May 17 01:25:20 2055 GMT + Subject: OU=SecurityTests Server Cert (ECC), CN=localhost + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:2d:d9:4f:91:d0:70:46:ad:b7:29:02:54:a5:e0: + b0:a8:d1:58:b5:1f:a6:b1:bf:f9:5c:5d:30:ea:ac: + 7d:76:dc:6b:57:84:2e:87:25:39:03:63:62:1f:1b: + a7:df:4e:f6:ed:8c:48:44:ed:8a:d8:52:5e:e5:42: + c3:5b:e6:01:2d + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Alternative Name: + DNS:localhost + X509v3 Subject Key Identifier: + 5A:27:76:15:E3:AA:09:29:08:95:B9:CF:D1:BF:47:40:13:2A:C6:FF + X509v3 Authority Key Identifier: + keyid:2A:8E:DC:15:F2:1D:69:64:39:77:8F:EE:F4:6D:3F:34:D9:85:F0:8C + + Signature Algorithm: ecdsa-with-SHA256 + 30:44:02:20:51:82:14:47:09:3f:6c:d6:bc:81:3e:84:26:b4: + f4:4f:99:cf:25:93:80:43:4b:b3:7f:36:0f:bb:da:77:43:6d: + 02:20:67:85:8f:8e:d7:ca:1f:25:24:30:09:0a:60:f1:ee:f7: + 04:8a:ef:9b:11:c8:ba:cc:db:06:d2:18:b2:48:60:35 -----BEGIN CERTIFICATE----- -MIIBXzCCAQagAwIBAgIBBDAJBgcqhkjOPQQBMCUxIzAhBgNVBAMTGlNlY3VyaXR5 -VGVzdCBDQSBDZXJ0IChFQ0MpMCAXDTE1MDMyMzA3MTAyNloYDzIwNTUwMzEzMDcx -MDI2WjA+MSgwJgYDVQQLEx9TZWN1cml0eVRlc3RzIFNlcnZlciBDZXJ0IChFQ0Mp -MRIwEAYDVQQDEwlsb2NhbGhvc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQt -2U+R0HBGrbcpAlSl4LCo0Vi1H6axv/lcXTDqrH123GtXhC6HJTkDY2IfG6ffTvbt -jEhE7YrYUl7lQsNb5gEtow0wCzAJBgNVHRMEAjAAMAkGByqGSM49BAEDSAAwRQIh -AKLHCOfKzXS5bsWYdbCdRdwaYL49gpWTVJqOvCVhbF7AAiBnDDTkKjUu+23OgpKv -eCU1XVcB3uIEwy/DOUU1xW9RkA== +MIIB8jCCAZmgAwIBAgITLBBbQIyzHzzIN65gvn4j6xp5lTAKBggqhkjOPQQDAjAl +MSMwIQYDVQQDExpTZWN1cml0eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xODA1MjYw +MTI1MjBaGA8yMDU1MDUxNzAxMjUyMFowPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0 +cyBTZXJ2ZXIgQ2VydCAoRUNDKTESMBAGA1UEAxMJbG9jYWxob3N0MFkwEwYHKoZI +zj0CAQYIKoZIzj0DAQcDQgAELdlPkdBwRq23KQJUpeCwqNFYtR+msb/5XF0w6qx9 +dtxrV4QuhyU5A2NiHxun30727YxIRO2K2FJe5ULDW+YBLaOBjDCBiTAMBgNVHRMB +Af8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAUBgNV +HREEDTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFFondhXjqgkpCJW5z9G/R0ATKsb/ +MB8GA1UdIwQYMBaAFCqO3BXyHWlkOXeP7vRtPzTZhfCMMAoGCCqGSM49BAMCA0cA +MEQCIFGCFEcJP2zWvIE+hCa09E+ZzyWTgENLs382D7vad0NtAiBnhY+O18ofJSQw +CQpg8e73BIrvmxHIuszbBtIYskhgNQ== -----END CERTIFICATE----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerECC.Cert.CA-RSA.der b/OSX/libsecurity_ssl/regressions/test-certs/ServerECC.Cert.CA-RSA.der index 25f48ef660a6ed644653c95d882118e59470fad2..51d8bd007965d5e241a9f7ff5daddfd1b4536319 100644 GIT binary patch delta 510 zcmZ3+vXj-opowX#K@;QL13>rHPc-WXjWrZ0T z|FbX|Fc|QGc>Ew93o{ez0s~t%AmL}c*+f&5tB0pVD3Hq2PUfK7)Q8b9@avsC8TN46&-4vf#bv$d2jM{eV|68tt z^)?;>hbDS1ZE);tTz6llKKB}5i_TB~rtT@J?80yL*nIUw#e78f{uVL4Ue`D!qp#(F z0hgHSjUP9QUrJ8PS^oW;S1_;0yG3(d?Z2BY}?{8nerWP;)3=~@L{_A zd+!o?&l@EY>=_I@7$}*GWg!)w7w_0J$ll_Dbb(#W$y{fv>f?muj6SOKzqw=e(z delta 362 zcmdnVx{O8EpovMzpox)d0W%XL6B8q|0WTY;R+~rLcV0$D)`G&qf%FBih!7D z&Eg|L<_!!<_)`Ps_?8_LnL*%HMtHx0)|0 zb8+7@%`Yo>ma->Js`})YHB(bBcv}Pe%R3X+H^|LiS@xGD}S1+s91s|$k zsTY4{ao#lEi%xpGZm~^Fd?t{*)6(%Z+oQlsskc*j_3D?p?&e>iChnTHp-#rd=UYtw zzYLYv#mAizE>F{X;b*rd(X2i;c$49}Mj-|TkIw9+0eXx(qYSr&_KD~i143L?&iN2FAsW zJqC@P20Xw(loe)V{LjKY7RWsh6*&k1H~!>O delta 357 zcmX@ax|&(qpowug5c@7*W@2OlA_Gn~cC9v#bG9su6ZLd7O%05Vj19~U4UEj9B>0UC zOo0N1FaZNQLk$BpHs(+kZsCc|n)Sk*Ir+(nIT`uIB?gW24S3l&fhM(m=VfGMWMyD( z>}4=$>||yGYb=8riE^>GcYAu7k)^PYZOR~Gr$d(Qtwj(;3}tS}Z@DJ^yM z#rutqOSvy;czUGFvF+UUW9j4znmzNXzA-3p1aaJv74LTOGZMbDF<|M3DXIa#9?8#u@#-zxw@yEZq>zCgzSB_d}sc0dmzxuBs|L31QVRv*i1ds0f rCk9lqQ+oM>4f@A6wMDC|i+D({wwb%~LB9WsaKGPoZ$0~JG+{OXK|+Q) diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-ECC.pem b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-ECC.pem index c36f927d..eac7fa03 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-ECC.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-ECC.pem @@ -1,11 +1,70 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 2c:10:5b:40:8c:b3:1f:3c:c8:37:ae:60:be:7e:23:eb:1a:79:94 + Signature Algorithm: ecdsa-with-SHA256 + Issuer: CN=SecurityTest CA Cert (ECC) + Validity + Not Before: May 26 01:25:05 2018 GMT + Not After : May 17 01:25:05 2055 GMT + Subject: OU=SecurityTests Server Cert (RSA), CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b1:d0:30:71:42:b1:df:f4:79:ea:e9:7a:ae:53: + c2:7f:a9:2e:5f:cc:a3:6e:96:0d:d1:42:2e:ba:da: + 06:91:61:e6:10:63:b9:39:41:eb:06:e2:51:d2:65: + db:64:0d:2e:7f:a5:45:bb:0f:a8:26:17:45:66:b0: + 7e:1c:44:4c:f6:5c:8f:fe:68:24:eb:73:c7:42:60: + d3:96:2a:e8:4e:3e:ac:61:36:5d:53:b2:31:ae:81: + 12:00:20:48:89:6b:a5:50:2e:01:b9:5a:31:b6:55: + 8e:14:2c:32:50:9e:44:a7:0e:61:26:ee:fc:22:0a: + e0:f5:af:68:1b:5f:ed:20:3d:61:59:38:00:8b:18: + 39:fd:48:14:90:68:5d:3e:b8:bd:e1:25:6d:d4:dc: + c4:2b:cc:ec:51:2b:92:32:06:ac:58:25:a7:a6:6e: + 12:9c:85:a2:6a:3a:2c:07:cb:f0:4a:47:85:14:1f: + 1b:bd:c8:e6:54:b8:89:7c:1a:fa:bf:93:28:d4:65: + 38:0d:f3:24:cf:14:f9:ff:0e:d3:e5:fd:5e:09:1a: + 8a:e8:64:36:25:9d:ce:ae:bf:1b:74:b8:37:8b:d5: + 00:59:14:e5:33:8f:f4:5c:33:23:2c:9f:64:1b:65: + 9a:b2:f2:6a:cb:2a:a0:af:04:93:8f:66:f9:eb:2b: + 4b:91 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Alternative Name: + DNS:localhost + X509v3 Subject Key Identifier: + C1:70:26:38:44:78:79:AB:FD:87:87:94:56:83:8C:C8:08:56:DB:98 + X509v3 Authority Key Identifier: + keyid:2A:8E:DC:15:F2:1D:69:64:39:77:8F:EE:F4:6D:3F:34:D9:85:F0:8C + + Signature Algorithm: ecdsa-with-SHA256 + 30:45:02:20:1c:72:67:58:df:e3:e3:41:9b:ef:ba:dc:8f:18: + 4a:c8:84:9a:54:0c:7e:ad:ce:0b:89:9a:8b:9c:6f:3e:34:19: + 02:21:00:a3:25:87:af:fc:38:1e:0a:82:f5:bd:70:28:5c:17: + fd:b9:03:3b:c3:7f:97:ca:ff:fe:49:70:1e:e7:55:14:c1 -----BEGIN CERTIFICATE----- -MIIBpzCCAU2gAwIBAgIBAjAJBgcqhkjOPQQBMCUxIzAhBgNVBAMTGlNlY3VyaXR5 -VGVzdCBDQSBDZXJ0IChFQ0MpMCAXDTE1MDMyMzA3MTAyNloYDzIwNTUwMzEzMDcx -MDI2WjA+MSgwJgYDVQQLEx9TZWN1cml0eVRlc3RzIFNlcnZlciBDZXJ0IChSU0Ep -MRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB -AKsFutwtswPxbGB/XoCFVCTHh27l8a52WeNLnP+iQfxA+KgzEqkbGsXo77HjdQvS -KElIZJw9ibb4pZPQKYyeevYAIAhSCNwdF4tETjIT3LFQpfCUJVD6HuOuZhkTPiCG -BZza2f+Pcm71wf2GribMS8ifqdY6H7aKjwQtu6RHs/v5AgMBAAGjDTALMAkGA1Ud -EwQCMAAwCQYHKoZIzj0EAQNJADBGAiEAsfj+ftfT76cjWqE5ITgeL6v9MQ/z+YxW -3CwoEcW+/hYCIQC5G6fgsC/GsoZbJydIG6s8nangb0/oV0773drm9TKQmw== +MIICvjCCAmSgAwIBAgITLBBbQIyzHzzIN65gvn4j6xp5lDAKBggqhkjOPQQDAjAl +MSMwIQYDVQQDExpTZWN1cml0eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xODA1MjYw +MTI1MDVaGA8yMDU1MDUxNzAxMjUwNVowPjEoMCYGA1UECwwfU2VjdXJpdHlUZXN0 +cyBTZXJ2ZXIgQ2VydCAoUlNBKTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsdAwcUKx3/R56ul6rlPCf6kuX8yjbpYN +0UIuutoGkWHmEGO5OUHrBuJR0mXbZA0uf6VFuw+oJhdFZrB+HERM9lyP/mgk63PH +QmDTliroTj6sYTZdU7IxroESACBIiWulUC4BuVoxtlWOFCwyUJ5Epw5hJu78Igrg +9a9oG1/tID1hWTgAixg5/UgUkGhdPri94SVt1NzEK8zsUSuSMgasWCWnpm4SnIWi +ajosB8vwSkeFFB8bvcjmVLiJfBr6v5Mo1GU4DfMkzxT5/w7T5f1eCRqK6GQ2JZ3O +rr8bdLg3i9UAWRTlM4/0XDMjLJ9kG2WasvJqyyqgrwSTj2b56ytLkQIDAQABo4GM +MIGJMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsG +AQUFBwMBMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAdBgNVHQ4EFgQUwXAmOER4eav9 +h4eUVoOMyAhW25gwHwYDVR0jBBgwFoAUKo7cFfIdaWQ5d4/u9G0/NNmF8IwwCgYI +KoZIzj0EAwIDSAAwRQIgHHJnWN/j40Gb77rcjxhKyISaVAx+rc4LiZqLnG8+NBkC +IQCjJYev/DgeCoL1vXAoXBf9uQM7w3+Xyv/+SXAe51UUwQ== -----END CERTIFICATE----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-RSA.der b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-RSA.der index e079f34aa897d3c285d3eca83048c7b8e4a999b9..f19c8654f7d29257009ddfa5b5b2176af6878279 100644 GIT binary patch delta 831 zcmaFM(!y?F(8Sze(8QFnfSHMriAjWEr-akL`_EP9ocneC!i%uSS1&6}HsEFB)N1o+ z`_9YA$URY3Pt(G{)X3Dx*u=uvB1(ea$iURpz|_zTDqvt|s9~VS#vIDR%`>q?vz~`D zCqFqcCnLYO#Gr{$3E414RtDxKMt%mMI2ThBBO}Ac3kHQw8}EOqeD$(wUGSm$m3r}K z7Uxalz38O3>lWL@#AgD@J1rewvpovDlzKabSFe7l>u&xPYT~YG8|q|Se7?o>|I1K$ zU3}ar;qo-C7k+kY63yykgEtwjYZPKo@aW858lcCxGsG^ce@ zmX!|s=?`A+ts?T$drv$I+0j`e^=toRjVq}Zyq{Ihi~Ri0clqhxI8Ldq`WGo?s&mh+ z+b>zVLQ>0U8ZTggTT5G|2mdX8TKVNHmPh?_dWMEv}*kjPx zX}|*vL|I`*#{Vo#1`Gy#ARa%6$HL6Sy1+mf#8+kEG2mk3&}L&~Wo2h(G!Ov^3bODT za5q7Ny&e?qvLInT7BLo)g9U09E)|ul|F*YJ32W{-!4Y)~{!Oa3A`v&s4nF`gHva(e;;3O5N|%VPXkhUgMi}liQPL_KdmGJ-VM~sp&sH zc3O3j-}2sPh3q>%?b^DxqcW+@u&Ist&ieMZyYj->>ZUE<@r)bsUt+DS~HnRNYw)L&yuS?!tE56w4zukjxTg%T_0{{;2M;ibD delta 550 zcmZo+f6F3k(8QE!(8L(HfSHMriHVWXfR~L^tIebBJ1-+6>qG-RO;ZD7BVz+|LjxnT zC<%Te15==YAxyx)&QQZZjg2{!gjA5$iTRm*MQrA6X<$b zVHPF>24v^50-f8$$jGqVH2DPA_jUX)1OhfxvMl}V5zAGTec`>h^HaquyWg*2Q4FZP z@#3TX#qCQcZ&~rCUU}cPn`idfG@7WYG|JuVxuzgu)~s0{cJ}au3%ViQtfyCR{N(ay zSMmPohqR-zJk>R8wr}*3*KlM_j_A8u=T;)fSTtGw)pv8RUoFAgZ20ayl@V&=`qsVX z#MW7}FKLKMG;{rNmpcD;;Z(mfHd?dpbH33~_N5?mbm@vWW;%mwNQoOVNFkFwdq7XEy&$(^_T` f{Y-Ddyd?X&gm+h%B5GrPSgNnQZKq;$;NA%U7*OHw diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-RSA.pem b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-RSA.pem index a2ab7222..558c92f8 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-RSA.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Cert.CA-RSA.pem @@ -1,15 +1,85 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + b9:18:42:fe:df:e7:25:9c:ce:fa:d7:d0:e8:56:e3:d5:d3:20:93 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=SecurityTest CA Cert (RSA) + Validity + Not Before: May 25 23:48:38 2018 GMT + Not After : May 16 23:48:38 2055 GMT + Subject: OU=SecurityTests Server Cert (RSA), CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b1:d0:30:71:42:b1:df:f4:79:ea:e9:7a:ae:53: + c2:7f:a9:2e:5f:cc:a3:6e:96:0d:d1:42:2e:ba:da: + 06:91:61:e6:10:63:b9:39:41:eb:06:e2:51:d2:65: + db:64:0d:2e:7f:a5:45:bb:0f:a8:26:17:45:66:b0: + 7e:1c:44:4c:f6:5c:8f:fe:68:24:eb:73:c7:42:60: + d3:96:2a:e8:4e:3e:ac:61:36:5d:53:b2:31:ae:81: + 12:00:20:48:89:6b:a5:50:2e:01:b9:5a:31:b6:55: + 8e:14:2c:32:50:9e:44:a7:0e:61:26:ee:fc:22:0a: + e0:f5:af:68:1b:5f:ed:20:3d:61:59:38:00:8b:18: + 39:fd:48:14:90:68:5d:3e:b8:bd:e1:25:6d:d4:dc: + c4:2b:cc:ec:51:2b:92:32:06:ac:58:25:a7:a6:6e: + 12:9c:85:a2:6a:3a:2c:07:cb:f0:4a:47:85:14:1f: + 1b:bd:c8:e6:54:b8:89:7c:1a:fa:bf:93:28:d4:65: + 38:0d:f3:24:cf:14:f9:ff:0e:d3:e5:fd:5e:09:1a: + 8a:e8:64:36:25:9d:ce:ae:bf:1b:74:b8:37:8b:d5: + 00:59:14:e5:33:8f:f4:5c:33:23:2c:9f:64:1b:65: + 9a:b2:f2:6a:cb:2a:a0:af:04:93:8f:66:f9:eb:2b: + 4b:91 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Alternative Name: + DNS:localhost + X509v3 Subject Key Identifier: + C1:70:26:38:44:78:79:AB:FD:87:87:94:56:83:8C:C8:08:56:DB:98 + X509v3 Authority Key Identifier: + keyid:5D:A7:1B:3B:57:D2:0E:08:1E:AA:47:CF:03:34:68:BE:53:00:D9:64 + + Signature Algorithm: sha256WithRSAEncryption + 2d:d1:12:47:d2:98:b6:1c:18:2a:58:f1:a1:e4:f9:aa:0d:9d: + d5:bb:7d:de:e9:d2:7f:4e:68:aa:06:fd:da:5a:83:79:fd:5d: + 0a:d1:cd:f3:a3:bf:84:31:45:9a:3a:72:7a:57:5b:00:de:20: + 8b:63:30:3d:55:d1:af:2c:1e:fb:a1:ce:f6:c3:45:aa:4a:40: + 6b:38:f3:a6:43:36:b5:f5:cd:f8:0b:c2:f7:2f:02:73:a3:3b: + cb:7f:98:15:af:d2:c9:1a:df:8e:2c:02:04:53:a7:7c:4d:6a: + d9:0b:49:0c:9b:98:9d:1b:8c:2d:f3:9a:26:2f:e3:c6:cb:25: + a2:4e:a7:8d:e6:71:07:b8:f2:ba:b5:bd:88:79:62:86:31:82: + 86:03:dc:af:87:ed:ba:6e:57:06:7e:96:a7:b4:e8:1f:56:d4: + 55:80:27:aa:d0:62:fd:22:ab:2e:37:0d:47:53:12:10:e5:3b: + 7c:c4:4a:0a:c0:1d:10:f0:cd:c2:fe:85:58:ac:74:fe:ec:5c: + 32:1e:18:f0:19:fc:91:21:71:67:d0:38:bb:7c:4d:5b:a5:cd: + 00:1d:4e:73:5b:e8:16:d5:29:8c:72:aa:a3:b5:5d:ee:84:b1: + 04:fb:0b:3d:4d:7c:0f:7e:63:bb:7d:17:a3:4a:ff:3e:e0:f6: + b5:77:cc:3b -----BEGIN CERTIFICATE----- -MIICaTCCAVGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAlMSMwIQYDVQQDExpTZWN1 -cml0eVRlc3QgQ0EgQ2VydCAoUlNBKTAgFw0xNTAzMjMwNzEwMjZaGA8yMDU1MDMx -MzA3MTAyNlowPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0cyBTZXJ2ZXIgQ2VydCAo -UlNBKTESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB -iQKBgQCrBbrcLbMD8Wxgf16AhVQkx4du5fGudlnjS5z/okH8QPioMxKpGxrF6O+x -43UL0ihJSGScPYm2+KWT0CmMnnr2ACAIUgjcHReLRE4yE9yxUKXwlCVQ+h7jrmYZ -Ez4ghgWc2tn/j3Ju9cH9hq4mzEvIn6nWOh+2io8ELbukR7P7+QIDAQABow0wCzAJ -BgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQCnNWPICveuD+gQULB5BKXzSF0K -emvQ7xdD5SHUu++sBCFQfdjo8T/Rt6WTtKjsI7622cy+PIE0JSSBHtmM1iAUNoMp -f1bNw5DQLVSLBcursfJE/Lpzv5fCK1pqSScpfLexSh8oQQVjWI7VfkZ0EQFykx/q -9zdK+oRTtjwO3uUcEoYK9ousyLWam9IoFRiDCvxHGs/toZVOzDwqmt8J7Cgg/cVC -8dgvIYjs4iSy4kVazrR4szA4DhxqowQOrKSX48FGCp1lmukCEvCIWMbe5SNCPFhS -Jxri9UohR7ITDLLQzLP9ZiqmOFvmLpCeYj9+YO7UAlh9XPg5J6nbPiQ8wN7I +MIIDgDCCAmigAwIBAgIUALkYQv7f5yWczvrX0OhW49XTIJMwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAxMaU2VjdXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTgw +NTI1MjM0ODM4WhgPMjA1NTA1MTYyMzQ4MzhaMD4xKDAmBgNVBAsMH1NlY3VyaXR5 +VGVzdHMgU2VydmVyIENlcnQgKFJTQSkxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALHQMHFCsd/0eerpeq5Twn+pLl/M +o26WDdFCLrraBpFh5hBjuTlB6wbiUdJl22QNLn+lRbsPqCYXRWawfhxETPZcj/5o +JOtzx0Jg05Yq6E4+rGE2XVOyMa6BEgAgSIlrpVAuAblaMbZVjhQsMlCeRKcOYSbu +/CIK4PWvaBtf7SA9YVk4AIsYOf1IFJBoXT64veElbdTcxCvM7FErkjIGrFglp6Zu +EpyFomo6LAfL8EpHhRQfG73I5lS4iXwa+r+TKNRlOA3zJM8U+f8O0+X9Xgkaiuhk +NiWdzq6/G3S4N4vVAFkU5TOP9FwzIyyfZBtlmrLyassqoK8Ek49m+esrS5ECAwEA +AaOBjDCBiTAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAK +BggrBgEFBQcDATAUBgNVHREEDTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFMFwJjhE +eHmr/YeHlFaDjMgIVtuYMB8GA1UdIwQYMBaAFF2nGztX0g4IHqpHzwM0aL5TANlk +MA0GCSqGSIb3DQEBCwUAA4IBAQAt0RJH0pi2HBgqWPGh5PmqDZ3Vu33e6dJ/Tmiq +Bv3aWoN5/V0K0c3zo7+EMUWaOnJ6V1sA3iCLYzA9VdGvLB77oc72w0WqSkBrOPOm +Qza19c34C8L3LwJzozvLf5gVr9LJGt+OLAIEU6d8TWrZC0kMm5idG4wt85omL+PG +yyWiTqeN5nEHuPK6tb2IeWKGMYKGA9yvh+26blcGfpantOgfVtRVgCeq0GL9Iqsu +Nw1HUxIQ5Tt8xEoKwB0Q8M3C/oVYrHT+7FwyHhjwGfyRIXFn0Di7fE1bpc0AHU5z +W+gW1SmMcqqjtV3uhLEE+ws9TXwPfmO7fRejSv8+4Pa1d8w7 -----END CERTIFICATE----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Key.der b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Key.der index b008e820d69dac004860ad19a708a2b47fa69eb1..466f1028dad993b99521e95050aa271e7a6ec29b 100644 GIT binary patch literal 1192 zcmV;Z1Xueof&`=j0RRGm0RaH9&@gdAvETH0>gjr}Q^J3#E?>-}Zk7$vLN2=629aUr z5M#MHLF)$MQPO4GWDPEVrA50Bs3sRhX0U!7L`?QvkN#*R>vP9KVAGZ==uSSYVK!Y; zvN5iK5&$4biEE`$E&;h(F}78X6f81Oo1TaoQ0xlIxGjv@JdI86dxPC$mUeIiF_LR zzmq7`WjGD^y03XqQ(;~2-tNcQ}7CKt;}uETvf_w&e8@Z$JJ{Q zEk4)*`UhjOGLD49iTyT(_hbi?C5CE8!+gcBW9ah?JNw1~G}U;85Y56j-(XC>;AZR~ zlqm;@xk%sB981z~0!qbb6D#11Y&OXY+)1OhkW|}`uh@AD$7?)wfqWHNyvc1nS+4=~ zS(OyPLSLy@yYY6ZxmFJ!J3Cqd0)c@5=m6P#Q8y9rfre@oPC@e=kv=*XkH_;YBU@@8 zST!Il@NG;WpOqV9xv#U=bH6wXWrcHXD9u9N%>9$eY_U~PHSGvi)0p$7a z>0*u6BndBWj1ycI&FL3T|DUk^%KRT-E#M0{x-KZsU2_rS=L#Xj>uIa=Lh;Dq0)c@5 z#58oWIfK;W_Y}TPMZaF2q8#H!pkn}*P~D0(1rJqlb@*tBY~cF^A*Le&23f*aS0D zU1{1(l77HWZ&~higMTK&lN<81;g^!Qv5{w04G9L{6mv!AfqG5fBn|EE}FyYA$AE84Bd@5QCb&|t zoh@ZSSn#8>!9Yvzm7BZ7n1URmJJ!m=N0}ZWh0H|OU>F-eGRBNu(F9}y5vWMzZQ`s& z4Fsw(o2RG4_s!}_428=|u8FQzAm_X~c-2=bsxz6dgO=X_tR4&Qf~P$2vOFeW{DiE7 GHG2CMMnCxg literal 607 zcmV-l0-*gcf&yCt0RRGlfdH!oy4)?Z1MzHNe_nuvR3yiTZsqZ=c3I;~od2Rh{6P4q zGZLvA8pY`EvEy|M(kMwtWSl*Tw)mx!&?$_bdiDSy2vP{#9T$s4PBIhRu~4P(lqFF5 z9^eOUR$8);b@yijM>>yQD|6`}qO`0RRC4fq*y! z@pntK*0#>{Fyv^S!?+}Gbzt_eS?&p_>+M8c?%nNGQyprp2{8zw^A`DV{Lb5IP9kf0 z->5{qO*B64Zh`vc^kS7T&PfqMD=un>3~C>*BJ472J{!Z!v_{qx&{AtmV|2^D>-fJh z*5g7ScWCnR@bn}QUz|K#yIUFUFaZKV0Mc@c*&2<@qE>4=c=LMHmypfPS~3Pbu)_PF zl~H5Q&0Nb%r{!PJ(^|-q;ojhbhW_2*v;cA?v>+Mwl=%Hl0Rlk)&g(V8wN@iM4I8NV=n8F`Ej zF9Hz1khJpm^?jdg5m(~^g>1&R<^Z2a-Ck8$0zgr62}mTXFtSSegM)N3T% tJF#ZLJjfT9w*}c4wnG;9`CjdQZ^Wi*I>*2vYdNg*_CVDo_e34kvNyt?B>(^b diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Key.pem b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Key.pem index 768bf2e8..2ab66cc4 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Key.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Key.pem @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICWwIBAAKBgQCrBbrcLbMD8Wxgf16AhVQkx4du5fGudlnjS5z/okH8QPioMxKp -GxrF6O+x43UL0ihJSGScPYm2+KWT0CmMnnr2ACAIUgjcHReLRE4yE9yxUKXwlCVQ -+h7jrmYZEz4ghgWc2tn/j3Ju9cH9hq4mzEvIn6nWOh+2io8ELbukR7P7+QIDAQAB -AoGAOATxd0u01rbO9DDkaJ7DuCRvdWD2sFnuCajr7URd7t3tVVMdaq0JMQii8xb5 -cPzO22pOImt536hEvE00Pu5ugfrl9GKVMM5JEUIrLmqHDGofryLsMms+G8PLtEbW -FNBSa0xjdMu+6/i/MdbjQh93aPLy8PQkEF+cPFy7WxntMAECQQDScovZGo3LolZr -O3jzetSXkM3NWjIGPbDC+5+VUWPPzVzLS6flX9DTWsiS4d7gg4b+3eG0AHIltCAZ -9pT4/U4BAkEA0AqJKplJNWAUjSzncqAZ1oZgDaZEiTCY6uvf+7VWIzzkyXZPkI5V -fVHLQfFzsKmLNvka/m+jLhMwxOMsUX0d+QJAbnJVeQSZpGS3jCGzUb2GM2F40Sxk -Eqhvy3U5hKkphBbYe41iOVx3AWWk3ImUaio9QCd82/Zb8fO94UJrXt26AQJAa1YU -QSNHLz+8Or6BR5Ws3w8DfedcEwA81XAPZxm/MH0ZeYwOLwIQv5C08vf1fZ9sEVfj -AoVsxrfmAJ9I3V5VWQJAUbWvNkuRbIkZRJZsSpRYKVw41Gsk3DuxZsE8yBeXtwXZ -GLZDFvj5Xu1+b8SmajrHwCFrOazz9kDVJfdEHdSyNw== +MIIEpAIBAAKCAQEAsdAwcUKx3/R56ul6rlPCf6kuX8yjbpYN0UIuutoGkWHmEGO5 +OUHrBuJR0mXbZA0uf6VFuw+oJhdFZrB+HERM9lyP/mgk63PHQmDTliroTj6sYTZd +U7IxroESACBIiWulUC4BuVoxtlWOFCwyUJ5Epw5hJu78Igrg9a9oG1/tID1hWTgA +ixg5/UgUkGhdPri94SVt1NzEK8zsUSuSMgasWCWnpm4SnIWiajosB8vwSkeFFB8b +vcjmVLiJfBr6v5Mo1GU4DfMkzxT5/w7T5f1eCRqK6GQ2JZ3Orr8bdLg3i9UAWRTl +M4/0XDMjLJ9kG2WasvJqyyqgrwSTj2b56ytLkQIDAQABAoIBAHYqtda/DPiZPuB3 +cxkg/tPZ+cCefUoDnIEha26vb8fz+HGR5EkB3o//nYKmQCt4extHGVUcLZHKy0tY +JSbh2QesMeFPEqIKmjQpptNYBnPhQKuF9nWlqVCf4/eDfNEeYYksWeb04q6aosYT +LQjYdSVT8Apwrcxt0FxVymjO0gYmx9VrES0+2AH6B2OyMo6Ew4n9NoX3ZAeTJYZq +R8N8xa9j6PMMO/vGATTVeIUQzcI332BMvuBm7CCUKQeIuUjf0xxL0m8CSsVoEyvg +jGw2yQvcSaO2kFTbj6/YeQvHazx1gXwVWbzJbT1ZrwH0WZUUwEJfqVe78XapuVYP +Hzs7WgECgYEA6ADZfFE3EfCBhmoVTkHzHJE+OhePx/MsI1tqH1g1ICzwbUwgn5Ub +Y7mvs9dzvzgLZYVzbSjNQt7M/ZPJbLFVgIIOJrK2Gq3nV7rJvQHk+e7pYo3WJAkv +bowTXBbN6RdO/5+w/cr8H2At4As4ui4oz11zEeTnCiHE62mr80LxyOECgYEAxDR0 +sjmD1OP3FL5ORb9enqIc40agYwCWUN2KNQXLN02CAMXre3Uz0lHeFhtsVJRYIMFg +5v9ErJSGTVPMHzHrRePCeGWb0Oj5h16lSQlmq9saRCN3VDMb1Du1tI/SXZ7wmsxJ +5TKWiSAqCEDzk8m7p6eHowLzzOUszPA7r4DkaLECgYEA4i0p2aOHj4qri3HSMYfj +zX7fblzYBDNSXWnaTJJ+wE5vWe50g38mw5Mb8rThl5K4sZFnVQ0JBt8Uc0XngXpk +g7LGvv1MwTe2qHVmBUhahTpf9n+WO21k+1295fIpbcsWbeit8M45+xCVyKzH8eHc +UUSmUNSaVOtVAbf0NWSXOKECgYBWf/3WuS6aw+ohdgkSDN2NOFFeDbwWCaM7gYA2 +Ahjmh8BB0QARTMmM9tTfkDWBUGlN/5NWI8JGB7DyFHiQZDSielg5NiqsvpmMCbj6 +6y8doxoAYlZwg5vIRI7GTQXkinbu+BO3/UaKq+h7/Q6l4DFgJ6bPwjRz57GJpHvb +0wpf8QKBgQDPi87hg50Ylghi0WaztiR7J0sIs9qdLWVBWPCjs8FAS++Vm7vEmIIc +ozvWysJHmR4hhcxE1mAYGz8yxoxd0QRkAhGoSOVt4qxFDQSqMpunp8P3zepJDIXL +Sq6JrlYg57w6eNVXKqozma+Dlt8ArB4L7oKnPPCyPCZg/ISsgzV6+w== -----END RSA PRIVATE KEY----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Req.pem b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Req.pem index f258876c..8d10ccee 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Req.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA.Req.pem @@ -1,11 +1,16 @@ -----BEGIN CERTIFICATE REQUEST----- -MIIBfTCB5wIBADA+MSgwJgYDVQQLEx9TZWN1cml0eVRlc3RzIFNlcnZlciBDZXJ0 -IChSU0EpMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0A -MIGJAoGBAKsFutwtswPxbGB/XoCFVCTHh27l8a52WeNLnP+iQfxA+KgzEqkbGsXo -77HjdQvSKElIZJw9ibb4pZPQKYyeevYAIAhSCNwdF4tETjIT3LFQpfCUJVD6HuOu -ZhkTPiCGBZza2f+Pcm71wf2GribMS8ifqdY6H7aKjwQtu6RHs/v5AgMBAAGgADAN -BgkqhkiG9w0BAQUFAAOBgQCn41FvcqnSHb6KOkK9n1bo132Co5lfn/ory7az66pU -dCfBOoM366rth2/a+NfGprKnwEbDZFcwFQf3DYfU6uF2b+6GsXgntxDJpwVoQWl4 -0dsNGBfr+ZnjoE9HlNAQ4v5EpIPCp/ZwcAOSXAiEHufvuf+S6LNOnrFVNVb1LoGn -Xw== +MIICgzCCAWsCAQAwPjEoMCYGA1UECwwfU2VjdXJpdHlUZXN0cyBTZXJ2ZXIgQ2Vy +dCAoUlNBKTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAsdAwcUKx3/R56ul6rlPCf6kuX8yjbpYN0UIuutoGkWHmEGO5 +OUHrBuJR0mXbZA0uf6VFuw+oJhdFZrB+HERM9lyP/mgk63PHQmDTliroTj6sYTZd +U7IxroESACBIiWulUC4BuVoxtlWOFCwyUJ5Epw5hJu78Igrg9a9oG1/tID1hWTgA +ixg5/UgUkGhdPri94SVt1NzEK8zsUSuSMgasWCWnpm4SnIWiajosB8vwSkeFFB8b +vcjmVLiJfBr6v5Mo1GU4DfMkzxT5/w7T5f1eCRqK6GQ2JZ3Orr8bdLg3i9UAWRTl +M4/0XDMjLJ9kG2WasvJqyyqgrwSTj2b56ytLkQIDAQABoAAwDQYJKoZIhvcNAQEL +BQADggEBACSObPnNbkzEqRja47CloL8azcq6YHgoS2Oz3utsLrVi/FdbkGCO+CP9 +q71yaenmZM4HfLxVB1xv0PMveve8gsLuhAAsEtrobSctgKZYXBBFVMnQSKt+84J6 +jeoWvDjYmP+KofiV2+vCdLQoBm8bmxOf3AZJSpzm23Pi3Eb0ksEe1+nHkLP6ilXY +UjjlQZeByd8bodm7Fr9iOdhJqYuFm7acVlgwrNbUHrGVIiwwP+rk2plcPN258HvM +qFChjZU03L2ha351GLDnqv7v9fbK0fhceEWIEI1p+4tXZbYft1J7x2TNYKOooJUj +l0VyibZul2ehFoVWTnocNCUE5KVknuE= -----END CERTIFICATE REQUEST----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Cert_CA-ECC.h b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Cert_CA-ECC.h index d251f4a8..2c404331 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Cert_CA-ECC.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Cert_CA-ECC.h @@ -1,39 +1,62 @@ unsigned char ServerRSA_Cert_CA_ECC_der[] = { - 0x30, 0x82, 0x01, 0xa7, 0x30, 0x82, 0x01, 0x4d, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x01, 0x02, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, - 0x3d, 0x04, 0x01, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, - 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x35, - 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x18, - 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31, 0x33, 0x30, 0x37, 0x31, - 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x81, 0x9f, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, - 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, - 0x00, 0xab, 0x05, 0xba, 0xdc, 0x2d, 0xb3, 0x03, 0xf1, 0x6c, 0x60, 0x7f, - 0x5e, 0x80, 0x85, 0x54, 0x24, 0xc7, 0x87, 0x6e, 0xe5, 0xf1, 0xae, 0x76, - 0x59, 0xe3, 0x4b, 0x9c, 0xff, 0xa2, 0x41, 0xfc, 0x40, 0xf8, 0xa8, 0x33, - 0x12, 0xa9, 0x1b, 0x1a, 0xc5, 0xe8, 0xef, 0xb1, 0xe3, 0x75, 0x0b, 0xd2, - 0x28, 0x49, 0x48, 0x64, 0x9c, 0x3d, 0x89, 0xb6, 0xf8, 0xa5, 0x93, 0xd0, - 0x29, 0x8c, 0x9e, 0x7a, 0xf6, 0x00, 0x20, 0x08, 0x52, 0x08, 0xdc, 0x1d, - 0x17, 0x8b, 0x44, 0x4e, 0x32, 0x13, 0xdc, 0xb1, 0x50, 0xa5, 0xf0, 0x94, - 0x25, 0x50, 0xfa, 0x1e, 0xe3, 0xae, 0x66, 0x19, 0x13, 0x3e, 0x20, 0x86, - 0x05, 0x9c, 0xda, 0xd9, 0xff, 0x8f, 0x72, 0x6e, 0xf5, 0xc1, 0xfd, 0x86, - 0xae, 0x26, 0xcc, 0x4b, 0xc8, 0x9f, 0xa9, 0xd6, 0x3a, 0x1f, 0xb6, 0x8a, - 0x8f, 0x04, 0x2d, 0xbb, 0xa4, 0x47, 0xb3, 0xfb, 0xf9, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, - 0xce, 0x3d, 0x04, 0x01, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, - 0xb1, 0xf8, 0xfe, 0x7e, 0xd7, 0xd3, 0xef, 0xa7, 0x23, 0x5a, 0xa1, 0x39, - 0x21, 0x38, 0x1e, 0x2f, 0xab, 0xfd, 0x31, 0x0f, 0xf3, 0xf9, 0x8c, 0x56, - 0xdc, 0x2c, 0x28, 0x11, 0xc5, 0xbe, 0xfe, 0x16, 0x02, 0x21, 0x00, 0xb9, - 0x1b, 0xa7, 0xe0, 0xb0, 0x2f, 0xc6, 0xb2, 0x86, 0x5b, 0x27, 0x27, 0x48, - 0x1b, 0xab, 0x3c, 0x9d, 0xa9, 0xe0, 0x6f, 0x4f, 0xe8, 0x57, 0x4e, 0xfb, - 0xdd, 0xda, 0xe6, 0xf5, 0x32, 0x90, 0x9b + 0x30, 0x82, 0x02, 0xbe, 0x30, 0x82, 0x02, 0x64, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x13, 0x2c, 0x10, 0x5b, 0x40, 0x8c, 0xb3, 0x1f, 0x3c, 0xc8, + 0x37, 0xae, 0x60, 0xbe, 0x7e, 0x23, 0xeb, 0x1a, 0x79, 0x94, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x25, + 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, + 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, 0x32, 0x36, 0x30, + 0x31, 0x32, 0x35, 0x30, 0x35, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, + 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x35, 0x30, 0x35, 0x5a, 0x30, + 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1f, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, + 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, + 0x6f, 0x73, 0x74, 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, + 0xb1, 0xd0, 0x30, 0x71, 0x42, 0xb1, 0xdf, 0xf4, 0x79, 0xea, 0xe9, 0x7a, + 0xae, 0x53, 0xc2, 0x7f, 0xa9, 0x2e, 0x5f, 0xcc, 0xa3, 0x6e, 0x96, 0x0d, + 0xd1, 0x42, 0x2e, 0xba, 0xda, 0x06, 0x91, 0x61, 0xe6, 0x10, 0x63, 0xb9, + 0x39, 0x41, 0xeb, 0x06, 0xe2, 0x51, 0xd2, 0x65, 0xdb, 0x64, 0x0d, 0x2e, + 0x7f, 0xa5, 0x45, 0xbb, 0x0f, 0xa8, 0x26, 0x17, 0x45, 0x66, 0xb0, 0x7e, + 0x1c, 0x44, 0x4c, 0xf6, 0x5c, 0x8f, 0xfe, 0x68, 0x24, 0xeb, 0x73, 0xc7, + 0x42, 0x60, 0xd3, 0x96, 0x2a, 0xe8, 0x4e, 0x3e, 0xac, 0x61, 0x36, 0x5d, + 0x53, 0xb2, 0x31, 0xae, 0x81, 0x12, 0x00, 0x20, 0x48, 0x89, 0x6b, 0xa5, + 0x50, 0x2e, 0x01, 0xb9, 0x5a, 0x31, 0xb6, 0x55, 0x8e, 0x14, 0x2c, 0x32, + 0x50, 0x9e, 0x44, 0xa7, 0x0e, 0x61, 0x26, 0xee, 0xfc, 0x22, 0x0a, 0xe0, + 0xf5, 0xaf, 0x68, 0x1b, 0x5f, 0xed, 0x20, 0x3d, 0x61, 0x59, 0x38, 0x00, + 0x8b, 0x18, 0x39, 0xfd, 0x48, 0x14, 0x90, 0x68, 0x5d, 0x3e, 0xb8, 0xbd, + 0xe1, 0x25, 0x6d, 0xd4, 0xdc, 0xc4, 0x2b, 0xcc, 0xec, 0x51, 0x2b, 0x92, + 0x32, 0x06, 0xac, 0x58, 0x25, 0xa7, 0xa6, 0x6e, 0x12, 0x9c, 0x85, 0xa2, + 0x6a, 0x3a, 0x2c, 0x07, 0xcb, 0xf0, 0x4a, 0x47, 0x85, 0x14, 0x1f, 0x1b, + 0xbd, 0xc8, 0xe6, 0x54, 0xb8, 0x89, 0x7c, 0x1a, 0xfa, 0xbf, 0x93, 0x28, + 0xd4, 0x65, 0x38, 0x0d, 0xf3, 0x24, 0xcf, 0x14, 0xf9, 0xff, 0x0e, 0xd3, + 0xe5, 0xfd, 0x5e, 0x09, 0x1a, 0x8a, 0xe8, 0x64, 0x36, 0x25, 0x9d, 0xce, + 0xae, 0xbf, 0x1b, 0x74, 0xb8, 0x37, 0x8b, 0xd5, 0x00, 0x59, 0x14, 0xe5, + 0x33, 0x8f, 0xf4, 0x5c, 0x33, 0x23, 0x2c, 0x9f, 0x64, 0x1b, 0x65, 0x9a, + 0xb2, 0xf2, 0x6a, 0xcb, 0x2a, 0xa0, 0xaf, 0x04, 0x93, 0x8f, 0x66, 0xf9, + 0xeb, 0x2b, 0x4b, 0x91, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x8c, + 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d, + 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0xc1, 0x70, 0x26, 0x38, 0x44, 0x78, 0x79, 0xab, 0xfd, + 0x87, 0x87, 0x94, 0x56, 0x83, 0x8c, 0xc8, 0x08, 0x56, 0xdb, 0x98, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0x2a, 0x8e, 0xdc, 0x15, 0xf2, 0x1d, 0x69, 0x64, 0x39, 0x77, 0x8f, 0xee, + 0xf4, 0x6d, 0x3f, 0x34, 0xd9, 0x85, 0xf0, 0x8c, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x1c, 0x72, 0x67, 0x58, 0xdf, 0xe3, 0xe3, 0x41, 0x9b, + 0xef, 0xba, 0xdc, 0x8f, 0x18, 0x4a, 0xc8, 0x84, 0x9a, 0x54, 0x0c, 0x7e, + 0xad, 0xce, 0x0b, 0x89, 0x9a, 0x8b, 0x9c, 0x6f, 0x3e, 0x34, 0x19, 0x02, + 0x21, 0x00, 0xa3, 0x25, 0x87, 0xaf, 0xfc, 0x38, 0x1e, 0x0a, 0x82, 0xf5, + 0xbd, 0x70, 0x28, 0x5c, 0x17, 0xfd, 0xb9, 0x03, 0x3b, 0xc3, 0x7f, 0x97, + 0xca, 0xff, 0xfe, 0x49, 0x70, 0x1e, 0xe7, 0x55, 0x14, 0xc1 }; -unsigned int ServerRSA_Cert_CA_ECC_der_len = 427; +unsigned int ServerRSA_Cert_CA_ECC_der_len = 706; diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Cert_CA-RSA.h b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Cert_CA-RSA.h index 959dbbf1..8ac87bff 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Cert_CA-RSA.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Cert_CA-RSA.h @@ -1,55 +1,78 @@ unsigned char ServerRSA_Cert_CA_RSA_der[] = { - 0x30, 0x82, 0x02, 0x69, 0x30, 0x82, 0x01, 0x51, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, - 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, - 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, - 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30, - 0x32, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31, - 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28, - 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, - 0x52, 0x53, 0x41, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, - 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xab, 0x05, 0xba, 0xdc, 0x2d, 0xb3, 0x03, - 0xf1, 0x6c, 0x60, 0x7f, 0x5e, 0x80, 0x85, 0x54, 0x24, 0xc7, 0x87, 0x6e, - 0xe5, 0xf1, 0xae, 0x76, 0x59, 0xe3, 0x4b, 0x9c, 0xff, 0xa2, 0x41, 0xfc, - 0x40, 0xf8, 0xa8, 0x33, 0x12, 0xa9, 0x1b, 0x1a, 0xc5, 0xe8, 0xef, 0xb1, - 0xe3, 0x75, 0x0b, 0xd2, 0x28, 0x49, 0x48, 0x64, 0x9c, 0x3d, 0x89, 0xb6, - 0xf8, 0xa5, 0x93, 0xd0, 0x29, 0x8c, 0x9e, 0x7a, 0xf6, 0x00, 0x20, 0x08, - 0x52, 0x08, 0xdc, 0x1d, 0x17, 0x8b, 0x44, 0x4e, 0x32, 0x13, 0xdc, 0xb1, - 0x50, 0xa5, 0xf0, 0x94, 0x25, 0x50, 0xfa, 0x1e, 0xe3, 0xae, 0x66, 0x19, - 0x13, 0x3e, 0x20, 0x86, 0x05, 0x9c, 0xda, 0xd9, 0xff, 0x8f, 0x72, 0x6e, - 0xf5, 0xc1, 0xfd, 0x86, 0xae, 0x26, 0xcc, 0x4b, 0xc8, 0x9f, 0xa9, 0xd6, - 0x3a, 0x1f, 0xb6, 0x8a, 0x8f, 0x04, 0x2d, 0xbb, 0xa4, 0x47, 0xb3, 0xfb, - 0xf9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x01, 0x00, 0xa7, 0x35, 0x63, 0xc8, 0x0a, 0xf7, 0xae, - 0x0f, 0xe8, 0x10, 0x50, 0xb0, 0x79, 0x04, 0xa5, 0xf3, 0x48, 0x5d, 0x0a, - 0x7a, 0x6b, 0xd0, 0xef, 0x17, 0x43, 0xe5, 0x21, 0xd4, 0xbb, 0xef, 0xac, - 0x04, 0x21, 0x50, 0x7d, 0xd8, 0xe8, 0xf1, 0x3f, 0xd1, 0xb7, 0xa5, 0x93, - 0xb4, 0xa8, 0xec, 0x23, 0xbe, 0xb6, 0xd9, 0xcc, 0xbe, 0x3c, 0x81, 0x34, - 0x25, 0x24, 0x81, 0x1e, 0xd9, 0x8c, 0xd6, 0x20, 0x14, 0x36, 0x83, 0x29, - 0x7f, 0x56, 0xcd, 0xc3, 0x90, 0xd0, 0x2d, 0x54, 0x8b, 0x05, 0xcb, 0xab, - 0xb1, 0xf2, 0x44, 0xfc, 0xba, 0x73, 0xbf, 0x97, 0xc2, 0x2b, 0x5a, 0x6a, - 0x49, 0x27, 0x29, 0x7c, 0xb7, 0xb1, 0x4a, 0x1f, 0x28, 0x41, 0x05, 0x63, - 0x58, 0x8e, 0xd5, 0x7e, 0x46, 0x74, 0x11, 0x01, 0x72, 0x93, 0x1f, 0xea, - 0xf7, 0x37, 0x4a, 0xfa, 0x84, 0x53, 0xb6, 0x3c, 0x0e, 0xde, 0xe5, 0x1c, - 0x12, 0x86, 0x0a, 0xf6, 0x8b, 0xac, 0xc8, 0xb5, 0x9a, 0x9b, 0xd2, 0x28, - 0x15, 0x18, 0x83, 0x0a, 0xfc, 0x47, 0x1a, 0xcf, 0xed, 0xa1, 0x95, 0x4e, - 0xcc, 0x3c, 0x2a, 0x9a, 0xdf, 0x09, 0xec, 0x28, 0x20, 0xfd, 0xc5, 0x42, - 0xf1, 0xd8, 0x2f, 0x21, 0x88, 0xec, 0xe2, 0x24, 0xb2, 0xe2, 0x45, 0x5a, - 0xce, 0xb4, 0x78, 0xb3, 0x30, 0x38, 0x0e, 0x1c, 0x6a, 0xa3, 0x04, 0x0e, - 0xac, 0xa4, 0x97, 0xe3, 0xc1, 0x46, 0x0a, 0x9d, 0x65, 0x9a, 0xe9, 0x02, - 0x12, 0xf0, 0x88, 0x58, 0xc6, 0xde, 0xe5, 0x23, 0x42, 0x3c, 0x58, 0x52, - 0x27, 0x1a, 0xe2, 0xf5, 0x4a, 0x21, 0x47, 0xb2, 0x13, 0x0c, 0xb2, 0xd0, - 0xcc, 0xb3, 0xfd, 0x66, 0x2a, 0xa6, 0x38, 0x5b, 0xe6, 0x2e, 0x90, 0x9e, - 0x62, 0x3f, 0x7e, 0x60, 0xee, 0xd4, 0x02, 0x58, 0x7d, 0x5c, 0xf8, 0x39, - 0x27, 0xa9, 0xdb, 0x3e, 0x24, 0x3c, 0xc0, 0xde, 0xc8 + 0x30, 0x82, 0x03, 0x80, 0x30, 0x82, 0x02, 0x68, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x00, 0xb9, 0x18, 0x42, 0xfe, 0xdf, 0xe7, 0x25, 0x9c, + 0xce, 0xfa, 0xd7, 0xd0, 0xe8, 0x56, 0xe3, 0xd5, 0xd3, 0x20, 0x93, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, + 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, + 0x35, 0x32, 0x35, 0x32, 0x33, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x18, 0x0f, + 0x32, 0x30, 0x35, 0x35, 0x30, 0x35, 0x31, 0x36, 0x32, 0x33, 0x34, 0x38, + 0x33, 0x38, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x0c, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, 0xb1, 0xd0, 0x30, 0x71, 0x42, 0xb1, 0xdf, 0xf4, + 0x79, 0xea, 0xe9, 0x7a, 0xae, 0x53, 0xc2, 0x7f, 0xa9, 0x2e, 0x5f, 0xcc, + 0xa3, 0x6e, 0x96, 0x0d, 0xd1, 0x42, 0x2e, 0xba, 0xda, 0x06, 0x91, 0x61, + 0xe6, 0x10, 0x63, 0xb9, 0x39, 0x41, 0xeb, 0x06, 0xe2, 0x51, 0xd2, 0x65, + 0xdb, 0x64, 0x0d, 0x2e, 0x7f, 0xa5, 0x45, 0xbb, 0x0f, 0xa8, 0x26, 0x17, + 0x45, 0x66, 0xb0, 0x7e, 0x1c, 0x44, 0x4c, 0xf6, 0x5c, 0x8f, 0xfe, 0x68, + 0x24, 0xeb, 0x73, 0xc7, 0x42, 0x60, 0xd3, 0x96, 0x2a, 0xe8, 0x4e, 0x3e, + 0xac, 0x61, 0x36, 0x5d, 0x53, 0xb2, 0x31, 0xae, 0x81, 0x12, 0x00, 0x20, + 0x48, 0x89, 0x6b, 0xa5, 0x50, 0x2e, 0x01, 0xb9, 0x5a, 0x31, 0xb6, 0x55, + 0x8e, 0x14, 0x2c, 0x32, 0x50, 0x9e, 0x44, 0xa7, 0x0e, 0x61, 0x26, 0xee, + 0xfc, 0x22, 0x0a, 0xe0, 0xf5, 0xaf, 0x68, 0x1b, 0x5f, 0xed, 0x20, 0x3d, + 0x61, 0x59, 0x38, 0x00, 0x8b, 0x18, 0x39, 0xfd, 0x48, 0x14, 0x90, 0x68, + 0x5d, 0x3e, 0xb8, 0xbd, 0xe1, 0x25, 0x6d, 0xd4, 0xdc, 0xc4, 0x2b, 0xcc, + 0xec, 0x51, 0x2b, 0x92, 0x32, 0x06, 0xac, 0x58, 0x25, 0xa7, 0xa6, 0x6e, + 0x12, 0x9c, 0x85, 0xa2, 0x6a, 0x3a, 0x2c, 0x07, 0xcb, 0xf0, 0x4a, 0x47, + 0x85, 0x14, 0x1f, 0x1b, 0xbd, 0xc8, 0xe6, 0x54, 0xb8, 0x89, 0x7c, 0x1a, + 0xfa, 0xbf, 0x93, 0x28, 0xd4, 0x65, 0x38, 0x0d, 0xf3, 0x24, 0xcf, 0x14, + 0xf9, 0xff, 0x0e, 0xd3, 0xe5, 0xfd, 0x5e, 0x09, 0x1a, 0x8a, 0xe8, 0x64, + 0x36, 0x25, 0x9d, 0xce, 0xae, 0xbf, 0x1b, 0x74, 0xb8, 0x37, 0x8b, 0xd5, + 0x00, 0x59, 0x14, 0xe5, 0x33, 0x8f, 0xf4, 0x5c, 0x33, 0x23, 0x2c, 0x9f, + 0x64, 0x1b, 0x65, 0x9a, 0xb2, 0xf2, 0x6a, 0xcb, 0x2a, 0xa0, 0xaf, 0x04, + 0x93, 0x8f, 0x66, 0xf9, 0xeb, 0x2b, 0x4b, 0x91, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x81, 0x8c, 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55, + 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, + 0xa0, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14, + 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc1, 0x70, 0x26, 0x38, 0x44, + 0x78, 0x79, 0xab, 0xfd, 0x87, 0x87, 0x94, 0x56, 0x83, 0x8c, 0xc8, 0x08, + 0x56, 0xdb, 0x98, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x5d, 0xa7, 0x1b, 0x3b, 0x57, 0xd2, 0x0e, 0x08, + 0x1e, 0xaa, 0x47, 0xcf, 0x03, 0x34, 0x68, 0xbe, 0x53, 0x00, 0xd9, 0x64, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x2d, 0xd1, 0x12, 0x47, + 0xd2, 0x98, 0xb6, 0x1c, 0x18, 0x2a, 0x58, 0xf1, 0xa1, 0xe4, 0xf9, 0xaa, + 0x0d, 0x9d, 0xd5, 0xbb, 0x7d, 0xde, 0xe9, 0xd2, 0x7f, 0x4e, 0x68, 0xaa, + 0x06, 0xfd, 0xda, 0x5a, 0x83, 0x79, 0xfd, 0x5d, 0x0a, 0xd1, 0xcd, 0xf3, + 0xa3, 0xbf, 0x84, 0x31, 0x45, 0x9a, 0x3a, 0x72, 0x7a, 0x57, 0x5b, 0x00, + 0xde, 0x20, 0x8b, 0x63, 0x30, 0x3d, 0x55, 0xd1, 0xaf, 0x2c, 0x1e, 0xfb, + 0xa1, 0xce, 0xf6, 0xc3, 0x45, 0xaa, 0x4a, 0x40, 0x6b, 0x38, 0xf3, 0xa6, + 0x43, 0x36, 0xb5, 0xf5, 0xcd, 0xf8, 0x0b, 0xc2, 0xf7, 0x2f, 0x02, 0x73, + 0xa3, 0x3b, 0xcb, 0x7f, 0x98, 0x15, 0xaf, 0xd2, 0xc9, 0x1a, 0xdf, 0x8e, + 0x2c, 0x02, 0x04, 0x53, 0xa7, 0x7c, 0x4d, 0x6a, 0xd9, 0x0b, 0x49, 0x0c, + 0x9b, 0x98, 0x9d, 0x1b, 0x8c, 0x2d, 0xf3, 0x9a, 0x26, 0x2f, 0xe3, 0xc6, + 0xcb, 0x25, 0xa2, 0x4e, 0xa7, 0x8d, 0xe6, 0x71, 0x07, 0xb8, 0xf2, 0xba, + 0xb5, 0xbd, 0x88, 0x79, 0x62, 0x86, 0x31, 0x82, 0x86, 0x03, 0xdc, 0xaf, + 0x87, 0xed, 0xba, 0x6e, 0x57, 0x06, 0x7e, 0x96, 0xa7, 0xb4, 0xe8, 0x1f, + 0x56, 0xd4, 0x55, 0x80, 0x27, 0xaa, 0xd0, 0x62, 0xfd, 0x22, 0xab, 0x2e, + 0x37, 0x0d, 0x47, 0x53, 0x12, 0x10, 0xe5, 0x3b, 0x7c, 0xc4, 0x4a, 0x0a, + 0xc0, 0x1d, 0x10, 0xf0, 0xcd, 0xc2, 0xfe, 0x85, 0x58, 0xac, 0x74, 0xfe, + 0xec, 0x5c, 0x32, 0x1e, 0x18, 0xf0, 0x19, 0xfc, 0x91, 0x21, 0x71, 0x67, + 0xd0, 0x38, 0xbb, 0x7c, 0x4d, 0x5b, 0xa5, 0xcd, 0x00, 0x1d, 0x4e, 0x73, + 0x5b, 0xe8, 0x16, 0xd5, 0x29, 0x8c, 0x72, 0xaa, 0xa3, 0xb5, 0x5d, 0xee, + 0x84, 0xb1, 0x04, 0xfb, 0x0b, 0x3d, 0x4d, 0x7c, 0x0f, 0x7e, 0x63, 0xbb, + 0x7d, 0x17, 0xa3, 0x4a, 0xff, 0x3e, 0xe0, 0xf6, 0xb5, 0x77, 0xcc, 0x3b }; -unsigned int ServerRSA_Cert_CA_RSA_der_len = 621; +unsigned int ServerRSA_Cert_CA_RSA_der_len = 900; diff --git a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Key.h b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Key.h index 62b304b9..70937290 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Key.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/ServerRSA_Key.h @@ -1,54 +1,103 @@ unsigned char ServerRSA_Key_der[] = { - 0x30, 0x82, 0x02, 0x5b, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xab, - 0x05, 0xba, 0xdc, 0x2d, 0xb3, 0x03, 0xf1, 0x6c, 0x60, 0x7f, 0x5e, 0x80, - 0x85, 0x54, 0x24, 0xc7, 0x87, 0x6e, 0xe5, 0xf1, 0xae, 0x76, 0x59, 0xe3, - 0x4b, 0x9c, 0xff, 0xa2, 0x41, 0xfc, 0x40, 0xf8, 0xa8, 0x33, 0x12, 0xa9, - 0x1b, 0x1a, 0xc5, 0xe8, 0xef, 0xb1, 0xe3, 0x75, 0x0b, 0xd2, 0x28, 0x49, - 0x48, 0x64, 0x9c, 0x3d, 0x89, 0xb6, 0xf8, 0xa5, 0x93, 0xd0, 0x29, 0x8c, - 0x9e, 0x7a, 0xf6, 0x00, 0x20, 0x08, 0x52, 0x08, 0xdc, 0x1d, 0x17, 0x8b, - 0x44, 0x4e, 0x32, 0x13, 0xdc, 0xb1, 0x50, 0xa5, 0xf0, 0x94, 0x25, 0x50, - 0xfa, 0x1e, 0xe3, 0xae, 0x66, 0x19, 0x13, 0x3e, 0x20, 0x86, 0x05, 0x9c, - 0xda, 0xd9, 0xff, 0x8f, 0x72, 0x6e, 0xf5, 0xc1, 0xfd, 0x86, 0xae, 0x26, - 0xcc, 0x4b, 0xc8, 0x9f, 0xa9, 0xd6, 0x3a, 0x1f, 0xb6, 0x8a, 0x8f, 0x04, - 0x2d, 0xbb, 0xa4, 0x47, 0xb3, 0xfb, 0xf9, 0x02, 0x03, 0x01, 0x00, 0x01, - 0x02, 0x81, 0x80, 0x38, 0x04, 0xf1, 0x77, 0x4b, 0xb4, 0xd6, 0xb6, 0xce, - 0xf4, 0x30, 0xe4, 0x68, 0x9e, 0xc3, 0xb8, 0x24, 0x6f, 0x75, 0x60, 0xf6, - 0xb0, 0x59, 0xee, 0x09, 0xa8, 0xeb, 0xed, 0x44, 0x5d, 0xee, 0xdd, 0xed, - 0x55, 0x53, 0x1d, 0x6a, 0xad, 0x09, 0x31, 0x08, 0xa2, 0xf3, 0x16, 0xf9, - 0x70, 0xfc, 0xce, 0xdb, 0x6a, 0x4e, 0x22, 0x6b, 0x79, 0xdf, 0xa8, 0x44, - 0xbc, 0x4d, 0x34, 0x3e, 0xee, 0x6e, 0x81, 0xfa, 0xe5, 0xf4, 0x62, 0x95, - 0x30, 0xce, 0x49, 0x11, 0x42, 0x2b, 0x2e, 0x6a, 0x87, 0x0c, 0x6a, 0x1f, - 0xaf, 0x22, 0xec, 0x32, 0x6b, 0x3e, 0x1b, 0xc3, 0xcb, 0xb4, 0x46, 0xd6, - 0x14, 0xd0, 0x52, 0x6b, 0x4c, 0x63, 0x74, 0xcb, 0xbe, 0xeb, 0xf8, 0xbf, - 0x31, 0xd6, 0xe3, 0x42, 0x1f, 0x77, 0x68, 0xf2, 0xf2, 0xf0, 0xf4, 0x24, - 0x10, 0x5f, 0x9c, 0x3c, 0x5c, 0xbb, 0x5b, 0x19, 0xed, 0x30, 0x01, 0x02, - 0x41, 0x00, 0xd2, 0x72, 0x8b, 0xd9, 0x1a, 0x8d, 0xcb, 0xa2, 0x56, 0x6b, - 0x3b, 0x78, 0xf3, 0x7a, 0xd4, 0x97, 0x90, 0xcd, 0xcd, 0x5a, 0x32, 0x06, - 0x3d, 0xb0, 0xc2, 0xfb, 0x9f, 0x95, 0x51, 0x63, 0xcf, 0xcd, 0x5c, 0xcb, - 0x4b, 0xa7, 0xe5, 0x5f, 0xd0, 0xd3, 0x5a, 0xc8, 0x92, 0xe1, 0xde, 0xe0, - 0x83, 0x86, 0xfe, 0xdd, 0xe1, 0xb4, 0x00, 0x72, 0x25, 0xb4, 0x20, 0x19, - 0xf6, 0x94, 0xf8, 0xfd, 0x4e, 0x01, 0x02, 0x41, 0x00, 0xd0, 0x0a, 0x89, - 0x2a, 0x99, 0x49, 0x35, 0x60, 0x14, 0x8d, 0x2c, 0xe7, 0x72, 0xa0, 0x19, - 0xd6, 0x86, 0x60, 0x0d, 0xa6, 0x44, 0x89, 0x30, 0x98, 0xea, 0xeb, 0xdf, - 0xfb, 0xb5, 0x56, 0x23, 0x3c, 0xe4, 0xc9, 0x76, 0x4f, 0x90, 0x8e, 0x55, - 0x7d, 0x51, 0xcb, 0x41, 0xf1, 0x73, 0xb0, 0xa9, 0x8b, 0x36, 0xf9, 0x1a, - 0xfe, 0x6f, 0xa3, 0x2e, 0x13, 0x30, 0xc4, 0xe3, 0x2c, 0x51, 0x7d, 0x1d, - 0xf9, 0x02, 0x40, 0x6e, 0x72, 0x55, 0x79, 0x04, 0x99, 0xa4, 0x64, 0xb7, - 0x8c, 0x21, 0xb3, 0x51, 0xbd, 0x86, 0x33, 0x61, 0x78, 0xd1, 0x2c, 0x64, - 0x12, 0xa8, 0x6f, 0xcb, 0x75, 0x39, 0x84, 0xa9, 0x29, 0x84, 0x16, 0xd8, - 0x7b, 0x8d, 0x62, 0x39, 0x5c, 0x77, 0x01, 0x65, 0xa4, 0xdc, 0x89, 0x94, - 0x6a, 0x2a, 0x3d, 0x40, 0x27, 0x7c, 0xdb, 0xf6, 0x5b, 0xf1, 0xf3, 0xbd, - 0xe1, 0x42, 0x6b, 0x5e, 0xdd, 0xba, 0x01, 0x02, 0x40, 0x6b, 0x56, 0x14, - 0x41, 0x23, 0x47, 0x2f, 0x3f, 0xbc, 0x3a, 0xbe, 0x81, 0x47, 0x95, 0xac, - 0xdf, 0x0f, 0x03, 0x7d, 0xe7, 0x5c, 0x13, 0x00, 0x3c, 0xd5, 0x70, 0x0f, - 0x67, 0x19, 0xbf, 0x30, 0x7d, 0x19, 0x79, 0x8c, 0x0e, 0x2f, 0x02, 0x10, - 0xbf, 0x90, 0xb4, 0xf2, 0xf7, 0xf5, 0x7d, 0x9f, 0x6c, 0x11, 0x57, 0xe3, - 0x02, 0x85, 0x6c, 0xc6, 0xb7, 0xe6, 0x00, 0x9f, 0x48, 0xdd, 0x5e, 0x55, - 0x59, 0x02, 0x40, 0x51, 0xb5, 0xaf, 0x36, 0x4b, 0x91, 0x6c, 0x89, 0x19, - 0x44, 0x96, 0x6c, 0x4a, 0x94, 0x58, 0x29, 0x5c, 0x38, 0xd4, 0x6b, 0x24, - 0xdc, 0x3b, 0xb1, 0x66, 0xc1, 0x3c, 0xc8, 0x17, 0x97, 0xb7, 0x05, 0xd9, - 0x18, 0xb6, 0x43, 0x16, 0xf8, 0xf9, 0x5e, 0xed, 0x7e, 0x6f, 0xc4, 0xa6, - 0x6a, 0x3a, 0xc7, 0xc0, 0x21, 0x6b, 0x39, 0xac, 0xf3, 0xf6, 0x40, 0xd5, - 0x25, 0xf7, 0x44, 0x1d, 0xd4, 0xb2, 0x37 + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xb1, 0xd0, 0x30, 0x71, 0x42, 0xb1, 0xdf, 0xf4, 0x79, 0xea, 0xe9, 0x7a, + 0xae, 0x53, 0xc2, 0x7f, 0xa9, 0x2e, 0x5f, 0xcc, 0xa3, 0x6e, 0x96, 0x0d, + 0xd1, 0x42, 0x2e, 0xba, 0xda, 0x06, 0x91, 0x61, 0xe6, 0x10, 0x63, 0xb9, + 0x39, 0x41, 0xeb, 0x06, 0xe2, 0x51, 0xd2, 0x65, 0xdb, 0x64, 0x0d, 0x2e, + 0x7f, 0xa5, 0x45, 0xbb, 0x0f, 0xa8, 0x26, 0x17, 0x45, 0x66, 0xb0, 0x7e, + 0x1c, 0x44, 0x4c, 0xf6, 0x5c, 0x8f, 0xfe, 0x68, 0x24, 0xeb, 0x73, 0xc7, + 0x42, 0x60, 0xd3, 0x96, 0x2a, 0xe8, 0x4e, 0x3e, 0xac, 0x61, 0x36, 0x5d, + 0x53, 0xb2, 0x31, 0xae, 0x81, 0x12, 0x00, 0x20, 0x48, 0x89, 0x6b, 0xa5, + 0x50, 0x2e, 0x01, 0xb9, 0x5a, 0x31, 0xb6, 0x55, 0x8e, 0x14, 0x2c, 0x32, + 0x50, 0x9e, 0x44, 0xa7, 0x0e, 0x61, 0x26, 0xee, 0xfc, 0x22, 0x0a, 0xe0, + 0xf5, 0xaf, 0x68, 0x1b, 0x5f, 0xed, 0x20, 0x3d, 0x61, 0x59, 0x38, 0x00, + 0x8b, 0x18, 0x39, 0xfd, 0x48, 0x14, 0x90, 0x68, 0x5d, 0x3e, 0xb8, 0xbd, + 0xe1, 0x25, 0x6d, 0xd4, 0xdc, 0xc4, 0x2b, 0xcc, 0xec, 0x51, 0x2b, 0x92, + 0x32, 0x06, 0xac, 0x58, 0x25, 0xa7, 0xa6, 0x6e, 0x12, 0x9c, 0x85, 0xa2, + 0x6a, 0x3a, 0x2c, 0x07, 0xcb, 0xf0, 0x4a, 0x47, 0x85, 0x14, 0x1f, 0x1b, + 0xbd, 0xc8, 0xe6, 0x54, 0xb8, 0x89, 0x7c, 0x1a, 0xfa, 0xbf, 0x93, 0x28, + 0xd4, 0x65, 0x38, 0x0d, 0xf3, 0x24, 0xcf, 0x14, 0xf9, 0xff, 0x0e, 0xd3, + 0xe5, 0xfd, 0x5e, 0x09, 0x1a, 0x8a, 0xe8, 0x64, 0x36, 0x25, 0x9d, 0xce, + 0xae, 0xbf, 0x1b, 0x74, 0xb8, 0x37, 0x8b, 0xd5, 0x00, 0x59, 0x14, 0xe5, + 0x33, 0x8f, 0xf4, 0x5c, 0x33, 0x23, 0x2c, 0x9f, 0x64, 0x1b, 0x65, 0x9a, + 0xb2, 0xf2, 0x6a, 0xcb, 0x2a, 0xa0, 0xaf, 0x04, 0x93, 0x8f, 0x66, 0xf9, + 0xeb, 0x2b, 0x4b, 0x91, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x00, 0x76, 0x2a, 0xb5, 0xd6, 0xbf, 0x0c, 0xf8, 0x99, 0x3e, 0xe0, 0x77, + 0x73, 0x19, 0x20, 0xfe, 0xd3, 0xd9, 0xf9, 0xc0, 0x9e, 0x7d, 0x4a, 0x03, + 0x9c, 0x81, 0x21, 0x6b, 0x6e, 0xaf, 0x6f, 0xc7, 0xf3, 0xf8, 0x71, 0x91, + 0xe4, 0x49, 0x01, 0xde, 0x8f, 0xff, 0x9d, 0x82, 0xa6, 0x40, 0x2b, 0x78, + 0x7b, 0x1b, 0x47, 0x19, 0x55, 0x1c, 0x2d, 0x91, 0xca, 0xcb, 0x4b, 0x58, + 0x25, 0x26, 0xe1, 0xd9, 0x07, 0xac, 0x31, 0xe1, 0x4f, 0x12, 0xa2, 0x0a, + 0x9a, 0x34, 0x29, 0xa6, 0xd3, 0x58, 0x06, 0x73, 0xe1, 0x40, 0xab, 0x85, + 0xf6, 0x75, 0xa5, 0xa9, 0x50, 0x9f, 0xe3, 0xf7, 0x83, 0x7c, 0xd1, 0x1e, + 0x61, 0x89, 0x2c, 0x59, 0xe6, 0xf4, 0xe2, 0xae, 0x9a, 0xa2, 0xc6, 0x13, + 0x2d, 0x08, 0xd8, 0x75, 0x25, 0x53, 0xf0, 0x0a, 0x70, 0xad, 0xcc, 0x6d, + 0xd0, 0x5c, 0x55, 0xca, 0x68, 0xce, 0xd2, 0x06, 0x26, 0xc7, 0xd5, 0x6b, + 0x11, 0x2d, 0x3e, 0xd8, 0x01, 0xfa, 0x07, 0x63, 0xb2, 0x32, 0x8e, 0x84, + 0xc3, 0x89, 0xfd, 0x36, 0x85, 0xf7, 0x64, 0x07, 0x93, 0x25, 0x86, 0x6a, + 0x47, 0xc3, 0x7c, 0xc5, 0xaf, 0x63, 0xe8, 0xf3, 0x0c, 0x3b, 0xfb, 0xc6, + 0x01, 0x34, 0xd5, 0x78, 0x85, 0x10, 0xcd, 0xc2, 0x37, 0xdf, 0x60, 0x4c, + 0xbe, 0xe0, 0x66, 0xec, 0x20, 0x94, 0x29, 0x07, 0x88, 0xb9, 0x48, 0xdf, + 0xd3, 0x1c, 0x4b, 0xd2, 0x6f, 0x02, 0x4a, 0xc5, 0x68, 0x13, 0x2b, 0xe0, + 0x8c, 0x6c, 0x36, 0xc9, 0x0b, 0xdc, 0x49, 0xa3, 0xb6, 0x90, 0x54, 0xdb, + 0x8f, 0xaf, 0xd8, 0x79, 0x0b, 0xc7, 0x6b, 0x3c, 0x75, 0x81, 0x7c, 0x15, + 0x59, 0xbc, 0xc9, 0x6d, 0x3d, 0x59, 0xaf, 0x01, 0xf4, 0x59, 0x95, 0x14, + 0xc0, 0x42, 0x5f, 0xa9, 0x57, 0xbb, 0xf1, 0x76, 0xa9, 0xb9, 0x56, 0x0f, + 0x1f, 0x3b, 0x3b, 0x5a, 0x01, 0x02, 0x81, 0x81, 0x00, 0xe8, 0x00, 0xd9, + 0x7c, 0x51, 0x37, 0x11, 0xf0, 0x81, 0x86, 0x6a, 0x15, 0x4e, 0x41, 0xf3, + 0x1c, 0x91, 0x3e, 0x3a, 0x17, 0x8f, 0xc7, 0xf3, 0x2c, 0x23, 0x5b, 0x6a, + 0x1f, 0x58, 0x35, 0x20, 0x2c, 0xf0, 0x6d, 0x4c, 0x20, 0x9f, 0x95, 0x1b, + 0x63, 0xb9, 0xaf, 0xb3, 0xd7, 0x73, 0xbf, 0x38, 0x0b, 0x65, 0x85, 0x73, + 0x6d, 0x28, 0xcd, 0x42, 0xde, 0xcc, 0xfd, 0x93, 0xc9, 0x6c, 0xb1, 0x55, + 0x80, 0x82, 0x0e, 0x26, 0xb2, 0xb6, 0x1a, 0xad, 0xe7, 0x57, 0xba, 0xc9, + 0xbd, 0x01, 0xe4, 0xf9, 0xee, 0xe9, 0x62, 0x8d, 0xd6, 0x24, 0x09, 0x2f, + 0x6e, 0x8c, 0x13, 0x5c, 0x16, 0xcd, 0xe9, 0x17, 0x4e, 0xff, 0x9f, 0xb0, + 0xfd, 0xca, 0xfc, 0x1f, 0x60, 0x2d, 0xe0, 0x0b, 0x38, 0xba, 0x2e, 0x28, + 0xcf, 0x5d, 0x73, 0x11, 0xe4, 0xe7, 0x0a, 0x21, 0xc4, 0xeb, 0x69, 0xab, + 0xf3, 0x42, 0xf1, 0xc8, 0xe1, 0x02, 0x81, 0x81, 0x00, 0xc4, 0x34, 0x74, + 0xb2, 0x39, 0x83, 0xd4, 0xe3, 0xf7, 0x14, 0xbe, 0x4e, 0x45, 0xbf, 0x5e, + 0x9e, 0xa2, 0x1c, 0xe3, 0x46, 0xa0, 0x63, 0x00, 0x96, 0x50, 0xdd, 0x8a, + 0x35, 0x05, 0xcb, 0x37, 0x4d, 0x82, 0x00, 0xc5, 0xeb, 0x7b, 0x75, 0x33, + 0xd2, 0x51, 0xde, 0x16, 0x1b, 0x6c, 0x54, 0x94, 0x58, 0x20, 0xc1, 0x60, + 0xe6, 0xff, 0x44, 0xac, 0x94, 0x86, 0x4d, 0x53, 0xcc, 0x1f, 0x31, 0xeb, + 0x45, 0xe3, 0xc2, 0x78, 0x65, 0x9b, 0xd0, 0xe8, 0xf9, 0x87, 0x5e, 0xa5, + 0x49, 0x09, 0x66, 0xab, 0xdb, 0x1a, 0x44, 0x23, 0x77, 0x54, 0x33, 0x1b, + 0xd4, 0x3b, 0xb5, 0xb4, 0x8f, 0xd2, 0x5d, 0x9e, 0xf0, 0x9a, 0xcc, 0x49, + 0xe5, 0x32, 0x96, 0x89, 0x20, 0x2a, 0x08, 0x40, 0xf3, 0x93, 0xc9, 0xbb, + 0xa7, 0xa7, 0x87, 0xa3, 0x02, 0xf3, 0xcc, 0xe5, 0x2c, 0xcc, 0xf0, 0x3b, + 0xaf, 0x80, 0xe4, 0x68, 0xb1, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x2d, 0x29, + 0xd9, 0xa3, 0x87, 0x8f, 0x8a, 0xab, 0x8b, 0x71, 0xd2, 0x31, 0x87, 0xe3, + 0xcd, 0x7e, 0xdf, 0x6e, 0x5c, 0xd8, 0x04, 0x33, 0x52, 0x5d, 0x69, 0xda, + 0x4c, 0x92, 0x7e, 0xc0, 0x4e, 0x6f, 0x59, 0xee, 0x74, 0x83, 0x7f, 0x26, + 0xc3, 0x93, 0x1b, 0xf2, 0xb4, 0xe1, 0x97, 0x92, 0xb8, 0xb1, 0x91, 0x67, + 0x55, 0x0d, 0x09, 0x06, 0xdf, 0x14, 0x73, 0x45, 0xe7, 0x81, 0x7a, 0x64, + 0x83, 0xb2, 0xc6, 0xbe, 0xfd, 0x4c, 0xc1, 0x37, 0xb6, 0xa8, 0x75, 0x66, + 0x05, 0x48, 0x5a, 0x85, 0x3a, 0x5f, 0xf6, 0x7f, 0x96, 0x3b, 0x6d, 0x64, + 0xfb, 0x5d, 0xbd, 0xe5, 0xf2, 0x29, 0x6d, 0xcb, 0x16, 0x6d, 0xe8, 0xad, + 0xf0, 0xce, 0x39, 0xfb, 0x10, 0x95, 0xc8, 0xac, 0xc7, 0xf1, 0xe1, 0xdc, + 0x51, 0x44, 0xa6, 0x50, 0xd4, 0x9a, 0x54, 0xeb, 0x55, 0x01, 0xb7, 0xf4, + 0x35, 0x64, 0x97, 0x38, 0xa1, 0x02, 0x81, 0x80, 0x56, 0x7f, 0xfd, 0xd6, + 0xb9, 0x2e, 0x9a, 0xc3, 0xea, 0x21, 0x76, 0x09, 0x12, 0x0c, 0xdd, 0x8d, + 0x38, 0x51, 0x5e, 0x0d, 0xbc, 0x16, 0x09, 0xa3, 0x3b, 0x81, 0x80, 0x36, + 0x02, 0x18, 0xe6, 0x87, 0xc0, 0x41, 0xd1, 0x00, 0x11, 0x4c, 0xc9, 0x8c, + 0xf6, 0xd4, 0xdf, 0x90, 0x35, 0x81, 0x50, 0x69, 0x4d, 0xff, 0x93, 0x56, + 0x23, 0xc2, 0x46, 0x07, 0xb0, 0xf2, 0x14, 0x78, 0x90, 0x64, 0x34, 0xa2, + 0x7a, 0x58, 0x39, 0x36, 0x2a, 0xac, 0xbe, 0x99, 0x8c, 0x09, 0xb8, 0xfa, + 0xeb, 0x2f, 0x1d, 0xa3, 0x1a, 0x00, 0x62, 0x56, 0x70, 0x83, 0x9b, 0xc8, + 0x44, 0x8e, 0xc6, 0x4d, 0x05, 0xe4, 0x8a, 0x76, 0xee, 0xf8, 0x13, 0xb7, + 0xfd, 0x46, 0x8a, 0xab, 0xe8, 0x7b, 0xfd, 0x0e, 0xa5, 0xe0, 0x31, 0x60, + 0x27, 0xa6, 0xcf, 0xc2, 0x34, 0x73, 0xe7, 0xb1, 0x89, 0xa4, 0x7b, 0xdb, + 0xd3, 0x0a, 0x5f, 0xf1, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x8b, 0xce, 0xe1, + 0x83, 0x9d, 0x18, 0x96, 0x08, 0x62, 0xd1, 0x66, 0xb3, 0xb6, 0x24, 0x7b, + 0x27, 0x4b, 0x08, 0xb3, 0xda, 0x9d, 0x2d, 0x65, 0x41, 0x58, 0xf0, 0xa3, + 0xb3, 0xc1, 0x40, 0x4b, 0xef, 0x95, 0x9b, 0xbb, 0xc4, 0x98, 0x82, 0x1c, + 0xa3, 0x3b, 0xd6, 0xca, 0xc2, 0x47, 0x99, 0x1e, 0x21, 0x85, 0xcc, 0x44, + 0xd6, 0x60, 0x18, 0x1b, 0x3f, 0x32, 0xc6, 0x8c, 0x5d, 0xd1, 0x04, 0x64, + 0x02, 0x11, 0xa8, 0x48, 0xe5, 0x6d, 0xe2, 0xac, 0x45, 0x0d, 0x04, 0xaa, + 0x32, 0x9b, 0xa7, 0xa7, 0xc3, 0xf7, 0xcd, 0xea, 0x49, 0x0c, 0x85, 0xcb, + 0x4a, 0xae, 0x89, 0xae, 0x56, 0x20, 0xe7, 0xbc, 0x3a, 0x78, 0xd5, 0x57, + 0x2a, 0xaa, 0x33, 0x99, 0xaf, 0x83, 0x96, 0xdf, 0x00, 0xac, 0x1e, 0x0b, + 0xee, 0x82, 0xa7, 0x3c, 0xf0, 0xb2, 0x3c, 0x26, 0x60, 0xfc, 0x84, 0xac, + 0x83, 0x35, 0x7a, 0xfb }; -unsigned int ServerRSA_Key_der_len = 607; +unsigned int ServerRSA_Key_der_len = 1192; diff --git a/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Cert.Untrusted-CA-RSA.der b/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Cert.Untrusted-CA-RSA.der index 97bbecddcdc31560453c476267760bc71a0fc001..8958d51254fec9f952e408c26d00b5649d2b1bdc 100644 GIT binary patch delta 806 zcmey#@{LX3pozK2pouAJ0W%XL6O*uA=7Je@3#;|zUu9i?t{S)5Gu_I7myJ`a&7!x&i^n41{+8GzzkOihf844axH6>4*AQeW&cH{+XeE%q#D%lpeZ zCzjTPbM|y8iv|B$IpfOPe?A{gO{Y#eb5^J==IgE`lOV?BHo@9_&Fm}IUdoDi)w51I zw_$lf-F1&zcloONde=V(lUc51NIvq~c}_OJDc>fsS~F)-sk;5&^%HX^Hoq!<&!&I$ z@wfSo>P*b0Vp_L0Fcu5hbT_Mf-k(=+d|PJj0cFM1$3Lh1nZdHI-QO#wB`!K3hjmF_ zY+l2r+pHsebp1tV~De$~_@OVLYq|<-9y~#|+dv%SvzJ6JC)XiNyA!+6-Bj)GY zhxi`^X2nDnUyzA0->)z6JKeRRZ(2@$)9xHj8Lj(g?v+1I_X^&zWa+VwqB}o$#jOiE z#>|+uQr^t=&AKet*<8=UE;`L#XuWYuSyM-yjlJ>=rR!o`?cy1)d-~ar#>_3=c63Vn zya?IFqQ=G#BpJW@c+6b?@oieX$jsVZigE7KBo0HlF~Ol6$|&VKc7+IVAjXv+;(hH>V|5;{OP-nH^nR~ W-IwW?9@dc~f4AuKMBAe#;h_LPc0OnT delta 551 zcmeyy_LD`FISMh2!p0YjL8fhUk@$i^JX!Yw?p&7@wKGbcYeF()IxxWu4wKC)SitPISJy$lA8 zolK3544YDWK3IKPe*S0DqKO@wCSGpnnrnWYrMGm}#LL`@&HI_v-v^s*zL=i3c%JV8 z{xv2)MZE9l3qGFQ_dxiN`VNNP6;~IXHZ0Gx@vU}p=U8;-!{i;Mr_apPsjuJJ78TU> ztfJ3cbIy{|GcUwv)+!nbefjz0(DL}7YtLQ|xWsy4y|cuG=$A~)j0}v6c@4M?IDxL0 z6=q>FU_f>*E6}-3jEoGG4h8?c1)hs2|25oO8*t+C_YK$EG)&K3e`OALK zc)F?4WxCPEglrb6dTuVJ>u+7J?{aQC?Dau7{843M*Y~HdbFRHJPXE7BS7__cTpmx+ zIXr93?>rJ(+tg_}^#xxM!?$eB$2B)KpPheK^F8OYS-pTs$jAM$=hfEo{JePgPPEF! zzzw%I%oG0_ry<4C4F_DFuBU$`Ww6Ig`)pE zKh|D+p?mh$`k;yJ4R;>P?x;HisnATm*354&{EXbvNR|$-YBNkKo zshHI5{!H;THIGtGA!XzFl>C?ku7^)bT!da*P;3RHZe4DGvTdGO*AB7zwn3w_rku0< z%<76a-k%rqqQ*|}XV474<5D6`k(@|u%pk0=dIovt0jI}x4KS_jHEA&PvU5B=m&l-E z*TMC*HXBrmR;k{~YMmJZ0|5X50)hbma_pgEvV94Wj<~$6_s-l*J)%HN>c=forEj0T zG=2K`p11e0}#@Bf(0|JD2?ojgo9kt984T)AQG^7|H0a!5? zrXz-DH>d@u>ZH)^NU*^RU~D*3Mr$>zDa&;Jl*9nL>hNRqNzu^N^}{5ZoRfwg2PFrP z#3zMso(LWOFos4LJJ1W80rgoHS69bpW@MDZMU)!XHR*tNSE{uLw8bm0C}=lbojL!8 zAQ{XGfeMaWa-eWR;f+v~AxU77b!i*Tl<>Tv?tW7j*<532RZL+}B5ChV%5cqMmFD$V zxJUZ&`tv@KC2?)}xfo;6KlRVi0)c@5*mgy)&dL)yT*A@J{RiTU1rZnpL7z3HItNAm zXw1*(xW9@(@wh@sqa?^HdgpioqxC{K=PHMpbqHD#9nAk0)c@5 z(;XbTk`mh$HjJmSElS|-oXnn!MdE(WpnwM8OMADKWdsd`G3e7mJ3#d=sEjYe^6h^vwb2X)pG} z_Q9Mh{5+QC3i!4E8i7Xhv+T+0)c>5vB&30;}sxc)`UQvcJlnn;1%HjM|ufLcb@i=(6hQiQ9u-dgGGlDte zQka4r=J3S_7Ex+h2pTS{X#Hr5oTPO%R#%f$JWrQ0Y*M%#WO3A>UWgyU3pSxYRIp(J zfq+SS?64GobGhP<`ycfH2V;jg!bbo=Vw+LQzM1?iNG`laxZSq#ulKC+!l62PUb2#Y zR&Jg!(I;Knid!A2lj2NWpV-pZM$!Mx9BnK~%3*P;Kr;r!#g9-;6qOsh2H5#I65Q_~ zKIq?1Z7A|rw7$kV` zwQ#dz_a>dE4IYAcxv-nvrBXf$xE6VC9Vrb|*IZVH3SP=G|HbpT(y)h%8a>gBk9j(S z7qWF3*OZ9EQXd{BKEP@PX>4<19${HjdwVkGzG%icWfB7d#m*ify21-V7;L5#T(4w5 EZ}Ry^mjD0& literal 610 zcmV-o0-gOZf&yLw0RRGlfdH~)jPN@0r_cFfqLGNQk<);Roj2D6jdhxl(+eSkzXK=l zQ#P~FXKtgOO~4PVH2D-u-)|A)laAmM!Y8-@ji}Y4%Q1IuJWYE-M+lG=0RRC4fq?*{ zOKU&&WoeLTagFD5UMV+~fXq5^+8g#;UqSQzV2}2`mPPPemce_s&rZ@1MvPLn?qGgZ zyq~l8j(&MY=TgFg0xJ?R@z~u*ke5h@)dfJiNg8*&kGgy;&h-`_P9ONN4v$T<80hUP*G-+)l zSPhpG_e=quhdo2NM}78kB<-e5Qw@xi7-!H|>EbI_2QP66)QbW^0L=~9p*#H$m%bV{ zeBo-}8@*J!Mz$C2M(L8e&~)LW;M!ob&ANP3c-}f!opuSt97-4d*H4|qsP#2>?S2ZiifZp{O=DM7ytkO diff --git a/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Key.pem b/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Key.pem index 7e97e141..54094fd0 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Key.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Key.pem @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXgIBAAKBgQCyZYzwOvKnz/liopGIspHTgIqdN9cEjXWakdMLIYO/AyfvUzaz -0Wduo55NwA+sNPkUS99vEeOTjuATwie4AI2o1aLLMXduPE17QkcIotzwk7h1y8yZ -LH+5hlpSiuZ4jjcpnKR1zOgXmX0hMRL0+fjCp1/5rc3TUNIF0K9DGJBb6QIDAQAB -AoGBAKNLaz/2ZWmQaHGN53NeKTeVgMw6cdob9ltfQfP9YI/2vpZF8FuWwXu3z07S -EEaMUrbuYH5VvJ+z945+eUbnUsKCAisSMfHY3UeQl0iH1QVAu0kaeN3eLd49+FU6 -mcFFg2aVdsoDS16X87iihs4EDFJv2kjhb35sL/SKlmJHxDrVAkEA3rgzWJN4iGyJ -mhzkITeztJFjAZZJDzRpbSRYDZcT90wBnYc9Q7lHffZyJO2mTFMNjJQYZ9BX6eIr -VwcvcQnUiwJBAM0N2KE7/RCXvho2fOFq3xu9VLtGthftRyEFqETSbO1OUqMxE0N8 -OZSWiOvGdxmnrUtkGvQUQyVLHS1qJNNyu9sCQHdoqNbHkisKjifbb5BDrgyUmlFi -gt8tCY0jnDYFFwZScNdFh9pEfwkQ1Zfo9m0bZjtFt2QJdukFgpkRWCUx0QsCQQCo -qArWExFC5Ixn4wk0H0MC/ecDYlXDuFYYwx5z/N+7EADIWUUO7M4veOGFi+fKIjBX -Ii9JMqFHu1B0WimQAX6hAkEAiuUxXWg0iR24NvVGMlQ0n9JD7z82TZp+6I4fZjXK -dnWKyKUKwZTIwsJfN6t1tYJ74K5Ho8fQcOwmJUCKh7Ab/A== +MIIEogIBAAKCAQEAsoIZIH1sPGXoujc2DpjWXc0JhO/TLMilfFcJjIojFlP6qZjU +7f5M8TU1lZLMzRKGXPW6YjRSAac8UysOgweordJqWOqMrhttgKdwftdIfUcfen9F +/MFjBNZoGeJKuc4db4JvPGF7KWySdSc//a+RbZGD6nPvBi/F4/afQScCAzUWKtqw +AXMSPIuDJPO/bnDHtmltwCMhZeP5lPyYBK6HT0pchF5bUGwFpG5dboCybZ5Z1w6x ++rZBo7OmnLP8zOqKN96fF/Oixk7wZ9AMv+NSIk2RnEhszCCssHoGeecBp8d1DTCt +7DVpMPSyczw9l8igYtfB9bU2G1SKVqneymqdGQIDAQABAoIBAHLsoWKyfQmRjri8 +rPfO3Ew9okBM6sctUqVvn700fgx0+q9Prt6eV0j/ucTXYzUwFQMqTNnG13krAwKE +eO5Q8v8dtcwTDYlWLTSkGCABWDEXpiOGZzeoBajqpNDtSLDBC2BsOFNGazWrKct0 +/pTEALvq8GP0SdHQ1fXDJJqck4YeByUHkMQnhW+eCB3+MIZGGDvQC5sB9VkWV1fH +Z2ZklMNFlBrXNemAd1eqtQi0xSuvKGg3XZ05/4YgGcwKgQqOW3KgcELhjVCUIUlg +kXVpG82U8Lyh7n5TF9lcY2hVTGFQImnvTspwzWKV5vVXuEf68frzPpElcW35uRhj +0D/1z9ECgYEA2HZFr87KEzpcwtHM/QfiiwURGAVBnzWlOgdF/mjMz+i4v4pA8bt7 +URl5PcrwAcOLI9UPa3XK0uTTGOwGN80IwfrYZVhRx/jhU1ZHwfI7ufrBvxH8BPK9 +m3McWrsokdYxjkpHzREzO3ip71cINlb4UZ1/uCZA8pWioA7oysReaE0CgYEA0x0c +upIS2xU2jKexLUrg7pzMnotF4n7OoIAG4Et7t5VlBA2EMejTQuTywMkRl4Ms220L +gJFu0p6gGCcG3kBjP1c3wQx23cTC5B05niaXtW5tNe6kdeAWfXwToFJrSRAR9M0B +6Gkv9sP2wZwr/DyW5gr4tf/lV/qU6aqzg4foLf0CgYBWscfnSeMVIGLWhECddvL8 +yuK1xCUsJsguHYujAUZGXubfj/fC2Vvid1lfrk/B5RdtGoA6gcrh/FOvv5gd8Th4 +uIbC0ESw2rUkM4I541KYgh3m8MUHFlFqWQgaLqto/WiLnKR1NVZXk1Q8T5cybFK4 +HWRx1KBeiB/CCzahP1SwYQKBgEl77LAUgHO54o77H/UAB2OHOMJHAEBim1HKvpn8 +LEguvEa43bbxr/es8cKhOnpespJ+Vm6eMNEnXdqKWx2pk+JMXZ/Y0tdG0f/NHG0s +ScphcapAMwbExY9QTRSVG7sG2Pk5EtzvID7o309tKPJXtL7GOuQ++nmxQ3xCatHx +0KORAoGAB5OpcrjeA6Ns/MH60+PIu87d5kVK63+1cLNj9yadpw0egni5sJvdpVI+ +CrgWeW4dKQ1U11xWhgpeyjL/xfO40rCHixo90YyPeTqDF7J1GdeUiMNSHx4mPsBq +BWlsc2IeYVlUe3sy5r5oxjhlEgMCxc4eIbrCC0EYbKYUXK9kP28= -----END RSA PRIVATE KEY----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Req.pem b/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Req.pem index 6bd2e3b9..ead5764a 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Req.pem +++ b/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA.Req.pem @@ -1,11 +1,16 @@ -----BEGIN CERTIFICATE REQUEST----- -MIIBiDCB8gIBADBJMTMwMQYDVQQLEypTZWN1cml0eVRlc3RzIENsaWVudCBDZXJ0 -IChSU0EpKFVudHJ1c3RlZCkxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG -9w0BAQEFAAOBjQAwgYkCgYEAsmWM8Dryp8/5YqKRiLKR04CKnTfXBI11mpHTCyGD -vwMn71M2s9FnbqOeTcAPrDT5FEvfbxHjk47gE8InuACNqNWiyzF3bjxNe0JHCKLc -8JO4dcvMmSx/uYZaUormeI43KZykdczoF5l9ITES9Pn4wqdf+a3N01DSBdCvQxiQ -W+kCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAHwoEtLs6TKO0aqVBgf9+GeF4qlz -jrSRobVCzneQI7EqrUjCSQZoSgEMbraw7siTC+/eFb/aMF6Lh3kiXzMpBuFtl62d -+c3tKMq3Kpff+lvLy9VB8webD2FGOX0dnUQTqtxcY2TWdkuQUr+DWFieAbqpVEfJ -gN+7XRqcEKy1VR95 +MIICjjCCAXYCAQAwSTEzMDEGA1UECwwqU2VjdXJpdHlUZXN0cyBDbGllbnQgQ2Vy +dCAoUlNBKShVbnRydXN0ZWQpMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyghkgfWw8Zei6NzYOmNZdzQmE79MsyKV8 +VwmMiiMWU/qpmNTt/kzxNTWVkszNEoZc9bpiNFIBpzxTKw6DB6it0mpY6oyuG22A +p3B+10h9Rx96f0X8wWME1mgZ4kq5zh1vgm88YXspbJJ1Jz/9r5FtkYPqc+8GL8Xj +9p9BJwIDNRYq2rABcxI8i4Mk879ucMe2aW3AIyFl4/mU/JgErodPSlyEXltQbAWk +bl1ugLJtnlnXDrH6tkGjs6acs/zM6oo33p8X86LGTvBn0Ay/41IiTZGcSGzMIKyw +egZ55wGnx3UNMK3sNWkw9LJzPD2XyKBi18H1tTYbVIpWqd7Kap0ZAgMBAAGgADAN +BgkqhkiG9w0BAQsFAAOCAQEALlUXJdlmD8meWpE4UdZj4Qaiy4aOSSGdYqLl6yOK +AWbPrEB5U07zizbYmJzAG9xsbg5v5MZKEiQsRwwY2neqJOVtyVIC7EjcDll8pK0M +JOOXpfYCxScXRhWxnRe9nUDYkhsdWRSMSHguNCK+mEEpcDLXe61eZV1BWgzkaYZJ +Zer4lHNlSbEFzs+WlZSvggfAFNPi7OB+nLREZlrfW2uptdk77/JBKOwAeHxasK+H +rB/Is53KOKYpaqTPqx7UpMWP3PwkTT1Zo1OfgDnMyhPcBhnI2eZ4UuWB9uI3BHpL +omBVTl6LcsYK2kIK1yLNM/e50N77kdT/euqGNPErf/woyw== -----END CERTIFICATE REQUEST----- diff --git a/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA_Cert_Untrusted-CA-RSA.h b/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA_Cert_Untrusted-CA-RSA.h index e0726ab3..bf3979af 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA_Cert_Untrusted-CA-RSA.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA_Cert_Untrusted-CA-RSA.h @@ -1,56 +1,77 @@ unsigned char UntrustedClientRSA_Cert_Untrusted_CA_RSA_der[] = { - 0x30, 0x82, 0x02, 0x75, 0x30, 0x82, 0x01, 0x5d, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x27, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, - 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, - 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, - 0x20, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, - 0x30, 0x32, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, - 0x31, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x49, 0x31, - 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x53, 0x65, - 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, - 0x28, 0x52, 0x53, 0x41, 0x29, 0x28, 0x55, 0x6e, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x65, 0x64, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, - 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xb2, 0x65, 0x8c, 0xf0, 0x3a, 0xf2, 0xa7, - 0xcf, 0xf9, 0x62, 0xa2, 0x91, 0x88, 0xb2, 0x91, 0xd3, 0x80, 0x8a, 0x9d, - 0x37, 0xd7, 0x04, 0x8d, 0x75, 0x9a, 0x91, 0xd3, 0x0b, 0x21, 0x83, 0xbf, - 0x03, 0x27, 0xef, 0x53, 0x36, 0xb3, 0xd1, 0x67, 0x6e, 0xa3, 0x9e, 0x4d, - 0xc0, 0x0f, 0xac, 0x34, 0xf9, 0x14, 0x4b, 0xdf, 0x6f, 0x11, 0xe3, 0x93, - 0x8e, 0xe0, 0x13, 0xc2, 0x27, 0xb8, 0x00, 0x8d, 0xa8, 0xd5, 0xa2, 0xcb, - 0x31, 0x77, 0x6e, 0x3c, 0x4d, 0x7b, 0x42, 0x47, 0x08, 0xa2, 0xdc, 0xf0, - 0x93, 0xb8, 0x75, 0xcb, 0xcc, 0x99, 0x2c, 0x7f, 0xb9, 0x86, 0x5a, 0x52, - 0x8a, 0xe6, 0x78, 0x8e, 0x37, 0x29, 0x9c, 0xa4, 0x75, 0xcc, 0xe8, 0x17, - 0x99, 0x7d, 0x21, 0x31, 0x12, 0xf4, 0xf9, 0xf8, 0xc2, 0xa7, 0x5f, 0xf9, - 0xad, 0xcd, 0xd3, 0x50, 0xd2, 0x05, 0xd0, 0xaf, 0x43, 0x18, 0x90, 0x5b, - 0xe9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x01, 0x00, 0x79, 0x40, 0x70, 0xff, 0x4b, 0x10, 0xe7, - 0x14, 0x23, 0xfd, 0x31, 0xbd, 0x7d, 0x50, 0xc8, 0xd3, 0xf7, 0xb0, 0xd7, - 0x86, 0x28, 0x35, 0xce, 0xd7, 0xea, 0x10, 0xae, 0xaa, 0xb7, 0xea, 0x0e, - 0x6f, 0xa6, 0xfb, 0x98, 0xe5, 0xb2, 0x81, 0x44, 0x97, 0x32, 0xb1, 0x60, - 0x6b, 0x04, 0x1a, 0x0b, 0x0a, 0x02, 0xd7, 0xed, 0x45, 0xd7, 0xba, 0x43, - 0x86, 0xc3, 0x4a, 0xf0, 0x13, 0x57, 0xe2, 0x79, 0x61, 0x8a, 0xf7, 0xe5, - 0xeb, 0x6c, 0xd6, 0xee, 0x33, 0x67, 0xff, 0xa9, 0x2d, 0x12, 0xb5, 0xf9, - 0x6d, 0x0c, 0x49, 0x15, 0x9c, 0x0c, 0xac, 0x37, 0xdc, 0xe2, 0x12, 0xad, - 0x82, 0x89, 0x39, 0x95, 0xe8, 0x0e, 0x72, 0x00, 0xf6, 0x6b, 0x29, 0xe3, - 0x7c, 0xd9, 0x29, 0xe6, 0xcf, 0xee, 0x7c, 0xf7, 0x6c, 0xf3, 0x36, 0x7f, - 0x10, 0x34, 0x54, 0xf1, 0xbf, 0x5d, 0xcf, 0x26, 0xad, 0x0c, 0xf9, 0xd1, - 0xdd, 0xdc, 0x5b, 0x24, 0xd1, 0x51, 0xb0, 0xdb, 0xb0, 0x99, 0x8b, 0xe9, - 0x05, 0xaf, 0x13, 0x7d, 0x8c, 0x78, 0xd5, 0xb4, 0x1e, 0x9a, 0x0b, 0xc8, - 0x4d, 0x2f, 0x76, 0x24, 0x51, 0xe7, 0xd4, 0xa5, 0x94, 0x36, 0x89, 0x2d, - 0xc8, 0xf9, 0x29, 0x22, 0x2f, 0x27, 0x4c, 0x56, 0x1e, 0x79, 0x7f, 0xd8, - 0xba, 0x7f, 0x12, 0x5b, 0xff, 0x43, 0xe3, 0x2b, 0xa3, 0xd0, 0x8b, 0x9b, - 0xb5, 0x7f, 0x52, 0x91, 0x87, 0x80, 0xdc, 0xe3, 0x4e, 0x2a, 0xbc, 0x64, - 0xc9, 0x92, 0x20, 0xeb, 0x4f, 0xfa, 0xa0, 0xcf, 0xc0, 0x3e, 0x0b, 0x93, - 0x57, 0x67, 0xb0, 0xe3, 0xac, 0xf6, 0xe8, 0xdc, 0x5d, 0xde, 0x34, 0x5b, - 0xd9, 0x9a, 0x4e, 0x0e, 0x71, 0x8e, 0xa5, 0xbd, 0x7c, 0x63, 0xef, 0x12, - 0x8a, 0x40, 0xec, 0x64, 0x50, 0x5f, 0x18, 0xa3, 0xa6, 0x75, 0xdb, 0x8e, - 0x41, 0x50, 0x46, 0x33, 0xba, 0xa2, 0x0f, 0x4b, 0xd4 + 0x30, 0x82, 0x03, 0x72, 0x30, 0x82, 0x02, 0x5a, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x13, 0x3e, 0x69, 0xa0, 0x98, 0x7e, 0xa1, 0x7b, 0x2f, 0x1f, + 0xea, 0x6a, 0xd7, 0xe7, 0x25, 0x5e, 0xb3, 0x49, 0x67, 0x3a, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, + 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, + 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, + 0x32, 0x36, 0x30, 0x31, 0x32, 0x39, 0x30, 0x38, 0x5a, 0x18, 0x0f, 0x32, + 0x30, 0x35, 0x35, 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x39, 0x30, + 0x38, 0x5a, 0x30, 0x49, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x2a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, + 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x28, 0x55, + 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x29, 0x31, 0x12, 0x30, + 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, 0xb2, 0x82, 0x19, 0x20, 0x7d, 0x6c, 0x3c, 0x65, 0xe8, 0xba, + 0x37, 0x36, 0x0e, 0x98, 0xd6, 0x5d, 0xcd, 0x09, 0x84, 0xef, 0xd3, 0x2c, + 0xc8, 0xa5, 0x7c, 0x57, 0x09, 0x8c, 0x8a, 0x23, 0x16, 0x53, 0xfa, 0xa9, + 0x98, 0xd4, 0xed, 0xfe, 0x4c, 0xf1, 0x35, 0x35, 0x95, 0x92, 0xcc, 0xcd, + 0x12, 0x86, 0x5c, 0xf5, 0xba, 0x62, 0x34, 0x52, 0x01, 0xa7, 0x3c, 0x53, + 0x2b, 0x0e, 0x83, 0x07, 0xa8, 0xad, 0xd2, 0x6a, 0x58, 0xea, 0x8c, 0xae, + 0x1b, 0x6d, 0x80, 0xa7, 0x70, 0x7e, 0xd7, 0x48, 0x7d, 0x47, 0x1f, 0x7a, + 0x7f, 0x45, 0xfc, 0xc1, 0x63, 0x04, 0xd6, 0x68, 0x19, 0xe2, 0x4a, 0xb9, + 0xce, 0x1d, 0x6f, 0x82, 0x6f, 0x3c, 0x61, 0x7b, 0x29, 0x6c, 0x92, 0x75, + 0x27, 0x3f, 0xfd, 0xaf, 0x91, 0x6d, 0x91, 0x83, 0xea, 0x73, 0xef, 0x06, + 0x2f, 0xc5, 0xe3, 0xf6, 0x9f, 0x41, 0x27, 0x02, 0x03, 0x35, 0x16, 0x2a, + 0xda, 0xb0, 0x01, 0x73, 0x12, 0x3c, 0x8b, 0x83, 0x24, 0xf3, 0xbf, 0x6e, + 0x70, 0xc7, 0xb6, 0x69, 0x6d, 0xc0, 0x23, 0x21, 0x65, 0xe3, 0xf9, 0x94, + 0xfc, 0x98, 0x04, 0xae, 0x87, 0x4f, 0x4a, 0x5c, 0x84, 0x5e, 0x5b, 0x50, + 0x6c, 0x05, 0xa4, 0x6e, 0x5d, 0x6e, 0x80, 0xb2, 0x6d, 0x9e, 0x59, 0xd7, + 0x0e, 0xb1, 0xfa, 0xb6, 0x41, 0xa3, 0xb3, 0xa6, 0x9c, 0xb3, 0xfc, 0xcc, + 0xea, 0x8a, 0x37, 0xde, 0x9f, 0x17, 0xf3, 0xa2, 0xc6, 0x4e, 0xf0, 0x67, + 0xd0, 0x0c, 0xbf, 0xe3, 0x52, 0x22, 0x4d, 0x91, 0x9c, 0x48, 0x6c, 0xcc, + 0x20, 0xac, 0xb0, 0x7a, 0x06, 0x79, 0xe7, 0x01, 0xa7, 0xc7, 0x75, 0x0d, + 0x30, 0xad, 0xec, 0x35, 0x69, 0x30, 0xf4, 0xb2, 0x73, 0x3c, 0x3d, 0x97, + 0xc8, 0xa0, 0x62, 0xd7, 0xc1, 0xf5, 0xb5, 0x36, 0x1b, 0x54, 0x8a, 0x56, + 0xa9, 0xde, 0xca, 0x6a, 0x9d, 0x19, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x75, 0x30, 0x73, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x13, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc4, 0x64, 0xb9, 0x16, 0x40, 0xa6, 0x81, + 0x7f, 0xa0, 0x26, 0x36, 0xc4, 0x44, 0x3a, 0xc6, 0xae, 0x21, 0x26, 0x86, + 0xa2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x83, 0xc8, 0x7c, 0x54, 0x9e, 0x94, 0x80, 0xb4, 0x14, 0x5e, + 0x91, 0xa6, 0x1b, 0x10, 0x5f, 0x74, 0xe7, 0x43, 0x8a, 0x3e, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4c, 0xca, 0x4d, 0x9c, 0xe6, 0xec, + 0x8b, 0x54, 0x70, 0x49, 0xd1, 0xc1, 0xc7, 0x70, 0x8b, 0x59, 0x42, 0xff, + 0x3e, 0xbd, 0x63, 0x02, 0xc7, 0x8d, 0x2d, 0x32, 0x8a, 0xf5, 0xf4, 0xaa, + 0xc5, 0x46, 0x47, 0x17, 0x60, 0x62, 0x99, 0xea, 0x32, 0x03, 0xe7, 0x2b, + 0xc2, 0x0f, 0xe0, 0x51, 0x6a, 0x5c, 0x59, 0x73, 0xd0, 0x1c, 0x5c, 0x37, + 0xbf, 0x2f, 0x18, 0xfb, 0x67, 0x45, 0x80, 0x8e, 0x96, 0x6c, 0x82, 0xbb, + 0x6c, 0x09, 0x1c, 0x2a, 0xdf, 0xcc, 0xde, 0x77, 0xe3, 0x67, 0x4a, 0x53, + 0xb8, 0xa4, 0xa5, 0xc6, 0xf1, 0x15, 0xb9, 0xf0, 0x4a, 0x5e, 0xae, 0x52, + 0xc6, 0x03, 0x01, 0x66, 0xa9, 0x1f, 0x36, 0x3d, 0xec, 0xae, 0x6a, 0x45, + 0x9b, 0x0a, 0xe6, 0x56, 0xd1, 0x42, 0x9b, 0xa1, 0x3b, 0xb1, 0xb4, 0x76, + 0x82, 0x88, 0x7e, 0x3c, 0x3f, 0x23, 0x98, 0x22, 0xd7, 0x16, 0x0a, 0x87, + 0x17, 0x68, 0xeb, 0x8c, 0x8f, 0x07, 0xc5, 0x5c, 0x9d, 0x73, 0xb6, 0xc5, + 0x94, 0x87, 0x9e, 0x58, 0x1d, 0xa3, 0x15, 0x33, 0x33, 0xe0, 0x19, 0x01, + 0xf5, 0x4c, 0x48, 0x99, 0xaf, 0xf1, 0xed, 0x66, 0x5f, 0x14, 0x99, 0x7d, + 0xba, 0x77, 0xed, 0x22, 0x26, 0x5f, 0x6d, 0x11, 0x13, 0xe6, 0x48, 0x92, + 0x01, 0x0d, 0xc1, 0x27, 0x42, 0x77, 0xe4, 0x82, 0xe8, 0x05, 0xa9, 0x4c, + 0xc4, 0xf0, 0x5c, 0x14, 0x71, 0x3a, 0x86, 0xce, 0x14, 0x1e, 0xce, 0xfe, + 0xfa, 0xfd, 0xab, 0xdf, 0x3b, 0x49, 0x4c, 0x35, 0x7f, 0x3c, 0x19, 0x1b, + 0xd9, 0x49, 0x21, 0x71, 0xbe, 0x07, 0xe7, 0x98, 0x78, 0x40, 0x36, 0x8e, + 0x02, 0x43, 0x86, 0xc6, 0xa2, 0x65, 0xb0, 0x7b, 0x11, 0x6f, 0x97, 0xba, + 0xc7, 0x82, 0x5c, 0xa6, 0x75, 0xbe, 0x69, 0x4e, 0x67, 0x56, 0x88, 0x6c, + 0x1f, 0xdd, 0x72, 0xf3, 0x91, 0x3d, 0xc5, 0x34, 0x57, 0x55 }; -unsigned int UntrustedClientRSA_Cert_Untrusted_CA_RSA_der_len = 633; +unsigned int UntrustedClientRSA_Cert_Untrusted_CA_RSA_der_len = 886; diff --git a/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA_Key.h b/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA_Key.h index 3f6d9acf..cb52b1bb 100644 --- a/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA_Key.h +++ b/OSX/libsecurity_ssl/regressions/test-certs/UntrustedClientRSA_Key.h @@ -1,54 +1,103 @@ unsigned char UntrustedClientRSA_Key_der[] = { - 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xb2, - 0x65, 0x8c, 0xf0, 0x3a, 0xf2, 0xa7, 0xcf, 0xf9, 0x62, 0xa2, 0x91, 0x88, - 0xb2, 0x91, 0xd3, 0x80, 0x8a, 0x9d, 0x37, 0xd7, 0x04, 0x8d, 0x75, 0x9a, - 0x91, 0xd3, 0x0b, 0x21, 0x83, 0xbf, 0x03, 0x27, 0xef, 0x53, 0x36, 0xb3, - 0xd1, 0x67, 0x6e, 0xa3, 0x9e, 0x4d, 0xc0, 0x0f, 0xac, 0x34, 0xf9, 0x14, - 0x4b, 0xdf, 0x6f, 0x11, 0xe3, 0x93, 0x8e, 0xe0, 0x13, 0xc2, 0x27, 0xb8, - 0x00, 0x8d, 0xa8, 0xd5, 0xa2, 0xcb, 0x31, 0x77, 0x6e, 0x3c, 0x4d, 0x7b, - 0x42, 0x47, 0x08, 0xa2, 0xdc, 0xf0, 0x93, 0xb8, 0x75, 0xcb, 0xcc, 0x99, - 0x2c, 0x7f, 0xb9, 0x86, 0x5a, 0x52, 0x8a, 0xe6, 0x78, 0x8e, 0x37, 0x29, - 0x9c, 0xa4, 0x75, 0xcc, 0xe8, 0x17, 0x99, 0x7d, 0x21, 0x31, 0x12, 0xf4, - 0xf9, 0xf8, 0xc2, 0xa7, 0x5f, 0xf9, 0xad, 0xcd, 0xd3, 0x50, 0xd2, 0x05, - 0xd0, 0xaf, 0x43, 0x18, 0x90, 0x5b, 0xe9, 0x02, 0x03, 0x01, 0x00, 0x01, - 0x02, 0x81, 0x81, 0x00, 0xa3, 0x4b, 0x6b, 0x3f, 0xf6, 0x65, 0x69, 0x90, - 0x68, 0x71, 0x8d, 0xe7, 0x73, 0x5e, 0x29, 0x37, 0x95, 0x80, 0xcc, 0x3a, - 0x71, 0xda, 0x1b, 0xf6, 0x5b, 0x5f, 0x41, 0xf3, 0xfd, 0x60, 0x8f, 0xf6, - 0xbe, 0x96, 0x45, 0xf0, 0x5b, 0x96, 0xc1, 0x7b, 0xb7, 0xcf, 0x4e, 0xd2, - 0x10, 0x46, 0x8c, 0x52, 0xb6, 0xee, 0x60, 0x7e, 0x55, 0xbc, 0x9f, 0xb3, - 0xf7, 0x8e, 0x7e, 0x79, 0x46, 0xe7, 0x52, 0xc2, 0x82, 0x02, 0x2b, 0x12, - 0x31, 0xf1, 0xd8, 0xdd, 0x47, 0x90, 0x97, 0x48, 0x87, 0xd5, 0x05, 0x40, - 0xbb, 0x49, 0x1a, 0x78, 0xdd, 0xde, 0x2d, 0xde, 0x3d, 0xf8, 0x55, 0x3a, - 0x99, 0xc1, 0x45, 0x83, 0x66, 0x95, 0x76, 0xca, 0x03, 0x4b, 0x5e, 0x97, - 0xf3, 0xb8, 0xa2, 0x86, 0xce, 0x04, 0x0c, 0x52, 0x6f, 0xda, 0x48, 0xe1, - 0x6f, 0x7e, 0x6c, 0x2f, 0xf4, 0x8a, 0x96, 0x62, 0x47, 0xc4, 0x3a, 0xd5, - 0x02, 0x41, 0x00, 0xde, 0xb8, 0x33, 0x58, 0x93, 0x78, 0x88, 0x6c, 0x89, - 0x9a, 0x1c, 0xe4, 0x21, 0x37, 0xb3, 0xb4, 0x91, 0x63, 0x01, 0x96, 0x49, - 0x0f, 0x34, 0x69, 0x6d, 0x24, 0x58, 0x0d, 0x97, 0x13, 0xf7, 0x4c, 0x01, - 0x9d, 0x87, 0x3d, 0x43, 0xb9, 0x47, 0x7d, 0xf6, 0x72, 0x24, 0xed, 0xa6, - 0x4c, 0x53, 0x0d, 0x8c, 0x94, 0x18, 0x67, 0xd0, 0x57, 0xe9, 0xe2, 0x2b, - 0x57, 0x07, 0x2f, 0x71, 0x09, 0xd4, 0x8b, 0x02, 0x41, 0x00, 0xcd, 0x0d, - 0xd8, 0xa1, 0x3b, 0xfd, 0x10, 0x97, 0xbe, 0x1a, 0x36, 0x7c, 0xe1, 0x6a, - 0xdf, 0x1b, 0xbd, 0x54, 0xbb, 0x46, 0xb6, 0x17, 0xed, 0x47, 0x21, 0x05, - 0xa8, 0x44, 0xd2, 0x6c, 0xed, 0x4e, 0x52, 0xa3, 0x31, 0x13, 0x43, 0x7c, - 0x39, 0x94, 0x96, 0x88, 0xeb, 0xc6, 0x77, 0x19, 0xa7, 0xad, 0x4b, 0x64, - 0x1a, 0xf4, 0x14, 0x43, 0x25, 0x4b, 0x1d, 0x2d, 0x6a, 0x24, 0xd3, 0x72, - 0xbb, 0xdb, 0x02, 0x40, 0x77, 0x68, 0xa8, 0xd6, 0xc7, 0x92, 0x2b, 0x0a, - 0x8e, 0x27, 0xdb, 0x6f, 0x90, 0x43, 0xae, 0x0c, 0x94, 0x9a, 0x51, 0x62, - 0x82, 0xdf, 0x2d, 0x09, 0x8d, 0x23, 0x9c, 0x36, 0x05, 0x17, 0x06, 0x52, - 0x70, 0xd7, 0x45, 0x87, 0xda, 0x44, 0x7f, 0x09, 0x10, 0xd5, 0x97, 0xe8, - 0xf6, 0x6d, 0x1b, 0x66, 0x3b, 0x45, 0xb7, 0x64, 0x09, 0x76, 0xe9, 0x05, - 0x82, 0x99, 0x11, 0x58, 0x25, 0x31, 0xd1, 0x0b, 0x02, 0x41, 0x00, 0xa8, - 0xa8, 0x0a, 0xd6, 0x13, 0x11, 0x42, 0xe4, 0x8c, 0x67, 0xe3, 0x09, 0x34, - 0x1f, 0x43, 0x02, 0xfd, 0xe7, 0x03, 0x62, 0x55, 0xc3, 0xb8, 0x56, 0x18, - 0xc3, 0x1e, 0x73, 0xfc, 0xdf, 0xbb, 0x10, 0x00, 0xc8, 0x59, 0x45, 0x0e, - 0xec, 0xce, 0x2f, 0x78, 0xe1, 0x85, 0x8b, 0xe7, 0xca, 0x22, 0x30, 0x57, - 0x22, 0x2f, 0x49, 0x32, 0xa1, 0x47, 0xbb, 0x50, 0x74, 0x5a, 0x29, 0x90, - 0x01, 0x7e, 0xa1, 0x02, 0x41, 0x00, 0x8a, 0xe5, 0x31, 0x5d, 0x68, 0x34, - 0x89, 0x1d, 0xb8, 0x36, 0xf5, 0x46, 0x32, 0x54, 0x34, 0x9f, 0xd2, 0x43, - 0xef, 0x3f, 0x36, 0x4d, 0x9a, 0x7e, 0xe8, 0x8e, 0x1f, 0x66, 0x35, 0xca, - 0x76, 0x75, 0x8a, 0xc8, 0xa5, 0x0a, 0xc1, 0x94, 0xc8, 0xc2, 0xc2, 0x5f, - 0x37, 0xab, 0x75, 0xb5, 0x82, 0x7b, 0xe0, 0xae, 0x47, 0xa3, 0xc7, 0xd0, - 0x70, 0xec, 0x26, 0x25, 0x40, 0x8a, 0x87, 0xb0, 0x1b, 0xfc + 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xb2, 0x82, 0x19, 0x20, 0x7d, 0x6c, 0x3c, 0x65, 0xe8, 0xba, 0x37, 0x36, + 0x0e, 0x98, 0xd6, 0x5d, 0xcd, 0x09, 0x84, 0xef, 0xd3, 0x2c, 0xc8, 0xa5, + 0x7c, 0x57, 0x09, 0x8c, 0x8a, 0x23, 0x16, 0x53, 0xfa, 0xa9, 0x98, 0xd4, + 0xed, 0xfe, 0x4c, 0xf1, 0x35, 0x35, 0x95, 0x92, 0xcc, 0xcd, 0x12, 0x86, + 0x5c, 0xf5, 0xba, 0x62, 0x34, 0x52, 0x01, 0xa7, 0x3c, 0x53, 0x2b, 0x0e, + 0x83, 0x07, 0xa8, 0xad, 0xd2, 0x6a, 0x58, 0xea, 0x8c, 0xae, 0x1b, 0x6d, + 0x80, 0xa7, 0x70, 0x7e, 0xd7, 0x48, 0x7d, 0x47, 0x1f, 0x7a, 0x7f, 0x45, + 0xfc, 0xc1, 0x63, 0x04, 0xd6, 0x68, 0x19, 0xe2, 0x4a, 0xb9, 0xce, 0x1d, + 0x6f, 0x82, 0x6f, 0x3c, 0x61, 0x7b, 0x29, 0x6c, 0x92, 0x75, 0x27, 0x3f, + 0xfd, 0xaf, 0x91, 0x6d, 0x91, 0x83, 0xea, 0x73, 0xef, 0x06, 0x2f, 0xc5, + 0xe3, 0xf6, 0x9f, 0x41, 0x27, 0x02, 0x03, 0x35, 0x16, 0x2a, 0xda, 0xb0, + 0x01, 0x73, 0x12, 0x3c, 0x8b, 0x83, 0x24, 0xf3, 0xbf, 0x6e, 0x70, 0xc7, + 0xb6, 0x69, 0x6d, 0xc0, 0x23, 0x21, 0x65, 0xe3, 0xf9, 0x94, 0xfc, 0x98, + 0x04, 0xae, 0x87, 0x4f, 0x4a, 0x5c, 0x84, 0x5e, 0x5b, 0x50, 0x6c, 0x05, + 0xa4, 0x6e, 0x5d, 0x6e, 0x80, 0xb2, 0x6d, 0x9e, 0x59, 0xd7, 0x0e, 0xb1, + 0xfa, 0xb6, 0x41, 0xa3, 0xb3, 0xa6, 0x9c, 0xb3, 0xfc, 0xcc, 0xea, 0x8a, + 0x37, 0xde, 0x9f, 0x17, 0xf3, 0xa2, 0xc6, 0x4e, 0xf0, 0x67, 0xd0, 0x0c, + 0xbf, 0xe3, 0x52, 0x22, 0x4d, 0x91, 0x9c, 0x48, 0x6c, 0xcc, 0x20, 0xac, + 0xb0, 0x7a, 0x06, 0x79, 0xe7, 0x01, 0xa7, 0xc7, 0x75, 0x0d, 0x30, 0xad, + 0xec, 0x35, 0x69, 0x30, 0xf4, 0xb2, 0x73, 0x3c, 0x3d, 0x97, 0xc8, 0xa0, + 0x62, 0xd7, 0xc1, 0xf5, 0xb5, 0x36, 0x1b, 0x54, 0x8a, 0x56, 0xa9, 0xde, + 0xca, 0x6a, 0x9d, 0x19, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x00, 0x72, 0xec, 0xa1, 0x62, 0xb2, 0x7d, 0x09, 0x91, 0x8e, 0xb8, 0xbc, + 0xac, 0xf7, 0xce, 0xdc, 0x4c, 0x3d, 0xa2, 0x40, 0x4c, 0xea, 0xc7, 0x2d, + 0x52, 0xa5, 0x6f, 0x9f, 0xbd, 0x34, 0x7e, 0x0c, 0x74, 0xfa, 0xaf, 0x4f, + 0xae, 0xde, 0x9e, 0x57, 0x48, 0xff, 0xb9, 0xc4, 0xd7, 0x63, 0x35, 0x30, + 0x15, 0x03, 0x2a, 0x4c, 0xd9, 0xc6, 0xd7, 0x79, 0x2b, 0x03, 0x02, 0x84, + 0x78, 0xee, 0x50, 0xf2, 0xff, 0x1d, 0xb5, 0xcc, 0x13, 0x0d, 0x89, 0x56, + 0x2d, 0x34, 0xa4, 0x18, 0x20, 0x01, 0x58, 0x31, 0x17, 0xa6, 0x23, 0x86, + 0x67, 0x37, 0xa8, 0x05, 0xa8, 0xea, 0xa4, 0xd0, 0xed, 0x48, 0xb0, 0xc1, + 0x0b, 0x60, 0x6c, 0x38, 0x53, 0x46, 0x6b, 0x35, 0xab, 0x29, 0xcb, 0x74, + 0xfe, 0x94, 0xc4, 0x00, 0xbb, 0xea, 0xf0, 0x63, 0xf4, 0x49, 0xd1, 0xd0, + 0xd5, 0xf5, 0xc3, 0x24, 0x9a, 0x9c, 0x93, 0x86, 0x1e, 0x07, 0x25, 0x07, + 0x90, 0xc4, 0x27, 0x85, 0x6f, 0x9e, 0x08, 0x1d, 0xfe, 0x30, 0x86, 0x46, + 0x18, 0x3b, 0xd0, 0x0b, 0x9b, 0x01, 0xf5, 0x59, 0x16, 0x57, 0x57, 0xc7, + 0x67, 0x66, 0x64, 0x94, 0xc3, 0x45, 0x94, 0x1a, 0xd7, 0x35, 0xe9, 0x80, + 0x77, 0x57, 0xaa, 0xb5, 0x08, 0xb4, 0xc5, 0x2b, 0xaf, 0x28, 0x68, 0x37, + 0x5d, 0x9d, 0x39, 0xff, 0x86, 0x20, 0x19, 0xcc, 0x0a, 0x81, 0x0a, 0x8e, + 0x5b, 0x72, 0xa0, 0x70, 0x42, 0xe1, 0x8d, 0x50, 0x94, 0x21, 0x49, 0x60, + 0x91, 0x75, 0x69, 0x1b, 0xcd, 0x94, 0xf0, 0xbc, 0xa1, 0xee, 0x7e, 0x53, + 0x17, 0xd9, 0x5c, 0x63, 0x68, 0x55, 0x4c, 0x61, 0x50, 0x22, 0x69, 0xef, + 0x4e, 0xca, 0x70, 0xcd, 0x62, 0x95, 0xe6, 0xf5, 0x57, 0xb8, 0x47, 0xfa, + 0xf1, 0xfa, 0xf3, 0x3e, 0x91, 0x25, 0x71, 0x6d, 0xf9, 0xb9, 0x18, 0x63, + 0xd0, 0x3f, 0xf5, 0xcf, 0xd1, 0x02, 0x81, 0x81, 0x00, 0xd8, 0x76, 0x45, + 0xaf, 0xce, 0xca, 0x13, 0x3a, 0x5c, 0xc2, 0xd1, 0xcc, 0xfd, 0x07, 0xe2, + 0x8b, 0x05, 0x11, 0x18, 0x05, 0x41, 0x9f, 0x35, 0xa5, 0x3a, 0x07, 0x45, + 0xfe, 0x68, 0xcc, 0xcf, 0xe8, 0xb8, 0xbf, 0x8a, 0x40, 0xf1, 0xbb, 0x7b, + 0x51, 0x19, 0x79, 0x3d, 0xca, 0xf0, 0x01, 0xc3, 0x8b, 0x23, 0xd5, 0x0f, + 0x6b, 0x75, 0xca, 0xd2, 0xe4, 0xd3, 0x18, 0xec, 0x06, 0x37, 0xcd, 0x08, + 0xc1, 0xfa, 0xd8, 0x65, 0x58, 0x51, 0xc7, 0xf8, 0xe1, 0x53, 0x56, 0x47, + 0xc1, 0xf2, 0x3b, 0xb9, 0xfa, 0xc1, 0xbf, 0x11, 0xfc, 0x04, 0xf2, 0xbd, + 0x9b, 0x73, 0x1c, 0x5a, 0xbb, 0x28, 0x91, 0xd6, 0x31, 0x8e, 0x4a, 0x47, + 0xcd, 0x11, 0x33, 0x3b, 0x78, 0xa9, 0xef, 0x57, 0x08, 0x36, 0x56, 0xf8, + 0x51, 0x9d, 0x7f, 0xb8, 0x26, 0x40, 0xf2, 0x95, 0xa2, 0xa0, 0x0e, 0xe8, + 0xca, 0xc4, 0x5e, 0x68, 0x4d, 0x02, 0x81, 0x81, 0x00, 0xd3, 0x1d, 0x1c, + 0xba, 0x92, 0x12, 0xdb, 0x15, 0x36, 0x8c, 0xa7, 0xb1, 0x2d, 0x4a, 0xe0, + 0xee, 0x9c, 0xcc, 0x9e, 0x8b, 0x45, 0xe2, 0x7e, 0xce, 0xa0, 0x80, 0x06, + 0xe0, 0x4b, 0x7b, 0xb7, 0x95, 0x65, 0x04, 0x0d, 0x84, 0x31, 0xe8, 0xd3, + 0x42, 0xe4, 0xf2, 0xc0, 0xc9, 0x11, 0x97, 0x83, 0x2c, 0xdb, 0x6d, 0x0b, + 0x80, 0x91, 0x6e, 0xd2, 0x9e, 0xa0, 0x18, 0x27, 0x06, 0xde, 0x40, 0x63, + 0x3f, 0x57, 0x37, 0xc1, 0x0c, 0x76, 0xdd, 0xc4, 0xc2, 0xe4, 0x1d, 0x39, + 0x9e, 0x26, 0x97, 0xb5, 0x6e, 0x6d, 0x35, 0xee, 0xa4, 0x75, 0xe0, 0x16, + 0x7d, 0x7c, 0x13, 0xa0, 0x52, 0x6b, 0x49, 0x10, 0x11, 0xf4, 0xcd, 0x01, + 0xe8, 0x69, 0x2f, 0xf6, 0xc3, 0xf6, 0xc1, 0x9c, 0x2b, 0xfc, 0x3c, 0x96, + 0xe6, 0x0a, 0xf8, 0xb5, 0xff, 0xe5, 0x57, 0xfa, 0x94, 0xe9, 0xaa, 0xb3, + 0x83, 0x87, 0xe8, 0x2d, 0xfd, 0x02, 0x81, 0x80, 0x56, 0xb1, 0xc7, 0xe7, + 0x49, 0xe3, 0x15, 0x20, 0x62, 0xd6, 0x84, 0x40, 0x9d, 0x76, 0xf2, 0xfc, + 0xca, 0xe2, 0xb5, 0xc4, 0x25, 0x2c, 0x26, 0xc8, 0x2e, 0x1d, 0x8b, 0xa3, + 0x01, 0x46, 0x46, 0x5e, 0xe6, 0xdf, 0x8f, 0xf7, 0xc2, 0xd9, 0x5b, 0xe2, + 0x77, 0x59, 0x5f, 0xae, 0x4f, 0xc1, 0xe5, 0x17, 0x6d, 0x1a, 0x80, 0x3a, + 0x81, 0xca, 0xe1, 0xfc, 0x53, 0xaf, 0xbf, 0x98, 0x1d, 0xf1, 0x38, 0x78, + 0xb8, 0x86, 0xc2, 0xd0, 0x44, 0xb0, 0xda, 0xb5, 0x24, 0x33, 0x82, 0x39, + 0xe3, 0x52, 0x98, 0x82, 0x1d, 0xe6, 0xf0, 0xc5, 0x07, 0x16, 0x51, 0x6a, + 0x59, 0x08, 0x1a, 0x2e, 0xab, 0x68, 0xfd, 0x68, 0x8b, 0x9c, 0xa4, 0x75, + 0x35, 0x56, 0x57, 0x93, 0x54, 0x3c, 0x4f, 0x97, 0x32, 0x6c, 0x52, 0xb8, + 0x1d, 0x64, 0x71, 0xd4, 0xa0, 0x5e, 0x88, 0x1f, 0xc2, 0x0b, 0x36, 0xa1, + 0x3f, 0x54, 0xb0, 0x61, 0x02, 0x81, 0x80, 0x49, 0x7b, 0xec, 0xb0, 0x14, + 0x80, 0x73, 0xb9, 0xe2, 0x8e, 0xfb, 0x1f, 0xf5, 0x00, 0x07, 0x63, 0x87, + 0x38, 0xc2, 0x47, 0x00, 0x40, 0x62, 0x9b, 0x51, 0xca, 0xbe, 0x99, 0xfc, + 0x2c, 0x48, 0x2e, 0xbc, 0x46, 0xb8, 0xdd, 0xb6, 0xf1, 0xaf, 0xf7, 0xac, + 0xf1, 0xc2, 0xa1, 0x3a, 0x7a, 0x5e, 0xb2, 0x92, 0x7e, 0x56, 0x6e, 0x9e, + 0x30, 0xd1, 0x27, 0x5d, 0xda, 0x8a, 0x5b, 0x1d, 0xa9, 0x93, 0xe2, 0x4c, + 0x5d, 0x9f, 0xd8, 0xd2, 0xd7, 0x46, 0xd1, 0xff, 0xcd, 0x1c, 0x6d, 0x2c, + 0x49, 0xca, 0x61, 0x71, 0xaa, 0x40, 0x33, 0x06, 0xc4, 0xc5, 0x8f, 0x50, + 0x4d, 0x14, 0x95, 0x1b, 0xbb, 0x06, 0xd8, 0xf9, 0x39, 0x12, 0xdc, 0xef, + 0x20, 0x3e, 0xe8, 0xdf, 0x4f, 0x6d, 0x28, 0xf2, 0x57, 0xb4, 0xbe, 0xc6, + 0x3a, 0xe4, 0x3e, 0xfa, 0x79, 0xb1, 0x43, 0x7c, 0x42, 0x6a, 0xd1, 0xf1, + 0xd0, 0xa3, 0x91, 0x02, 0x81, 0x80, 0x07, 0x93, 0xa9, 0x72, 0xb8, 0xde, + 0x03, 0xa3, 0x6c, 0xfc, 0xc1, 0xfa, 0xd3, 0xe3, 0xc8, 0xbb, 0xce, 0xdd, + 0xe6, 0x45, 0x4a, 0xeb, 0x7f, 0xb5, 0x70, 0xb3, 0x63, 0xf7, 0x26, 0x9d, + 0xa7, 0x0d, 0x1e, 0x82, 0x78, 0xb9, 0xb0, 0x9b, 0xdd, 0xa5, 0x52, 0x3e, + 0x0a, 0xb8, 0x16, 0x79, 0x6e, 0x1d, 0x29, 0x0d, 0x54, 0xd7, 0x5c, 0x56, + 0x86, 0x0a, 0x5e, 0xca, 0x32, 0xff, 0xc5, 0xf3, 0xb8, 0xd2, 0xb0, 0x87, + 0x8b, 0x1a, 0x3d, 0xd1, 0x8c, 0x8f, 0x79, 0x3a, 0x83, 0x17, 0xb2, 0x75, + 0x19, 0xd7, 0x94, 0x88, 0xc3, 0x52, 0x1f, 0x1e, 0x26, 0x3e, 0xc0, 0x6a, + 0x05, 0x69, 0x6c, 0x73, 0x62, 0x1e, 0x61, 0x59, 0x54, 0x7b, 0x7b, 0x32, + 0xe6, 0xbe, 0x68, 0xc6, 0x38, 0x65, 0x12, 0x03, 0x02, 0xc5, 0xce, 0x1e, + 0x21, 0xba, 0xc2, 0x0b, 0x41, 0x18, 0x6c, 0xa6, 0x14, 0x5c, 0xaf, 0x64, + 0x3f, 0x6f }; -unsigned int UntrustedClientRSA_Key_der_len = 610; +unsigned int UntrustedClientRSA_Key_der_len = 1190; diff --git a/OSX/libsecurity_transform/lib/CEncryptDecrypt.c b/OSX/libsecurity_transform/lib/CEncryptDecrypt.c index 3897796f..dace9859 100644 --- a/OSX/libsecurity_transform/lib/CEncryptDecrypt.c +++ b/OSX/libsecurity_transform/lib/CEncryptDecrypt.c @@ -37,8 +37,13 @@ CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue); CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue) CF_RETURNS_RETAINED { - cc_unit paddingBuffer[ccn_nof_size(desired_message_length)]; - bzero(paddingBuffer, sizeof(cc_unit) * ccn_nof_size(desired_message_length)); // XXX needed?? + size_t pBufferSize = ccn_sizeof_size(desired_message_length); + cc_unit *paddingBuffer = malloc(pBufferSize); + if (paddingBuffer == NULL){ + return (void*)GetNoMemoryErrorAndRetain(); + } + + bzero(paddingBuffer, pBufferSize); // XXX needed?? static dispatch_once_t randomNumberGenneratorInitialzed; static struct ccrng_system_state rng; dispatch_once(&randomNumberGenneratorInitialzed, ^{ @@ -47,23 +52,29 @@ CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue) CF ccrsa_oaep_encode(ccsha1_di(), (struct ccrng_state*)&rng, - sizeof(paddingBuffer), (cc_unit*)paddingBuffer, + pBufferSize, (cc_unit*)paddingBuffer, CFDataGetLength(dataValue), CFDataGetBytePtr(dataValue)); - ccn_swap(ccn_nof_size(sizeof(paddingBuffer)), (cc_unit*)paddingBuffer); + ccn_swap(ccn_nof_size(pBufferSize), (cc_unit*)paddingBuffer); CFDataRef paddedValue = CFDataCreate(NULL, (UInt8*)paddingBuffer, desired_message_length); - return paddedValue ? paddedValue : (void*)GetNoMemoryErrorAndRetain(); + free(paddingBuffer); + return paddedValue ? paddedValue : (void*)GetNoMemoryErrorAndRetain(); } CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage); CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage) CF_RETURNS_RETAINED { size_t mlen = CFDataGetLength(encodedMessage); - cc_size n = ccn_nof_size(mlen); - cc_unit paddingBuffer[n]; - UInt8 plainText[mlen]; + size_t pBufferSize = ccn_sizeof_size(mlen); + cc_unit *paddingBuffer = malloc(pBufferSize); + UInt8 *plainText = malloc(mlen); + if (plainText == NULL || paddingBuffer == NULL) { + free(plainText); + free(paddingBuffer); + return (void*)GetNoMemoryErrorAndRetain(); + } - ccn_read_uint(n, paddingBuffer, mlen, CFDataGetBytePtr(encodedMessage)); + ccn_read_uint(ccn_nof_size(mlen), paddingBuffer, mlen, CFDataGetBytePtr(encodedMessage)); size_t plainTextLength = mlen; int err = ccrsa_oaep_decode(ccsha1_di(), &plainTextLength, plainText, mlen, paddingBuffer); @@ -71,8 +82,15 @@ CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage) CF_RETURNS_RETAINED // XXX should make a CFError or something. CFErrorRef error = fancy_error(CFSTR("CoreCrypto"), err, CFSTR("OAEP decode error")); CFRetainSafe(error); + free(plainText); + free(paddingBuffer); return (void*)error; } - CFDataRef result = CFDataCreate(NULL, (UInt8*)plainText, plainTextLength); - return result; + + CFDataRef result = CFDataCreate(NULL, (UInt8*)plainText, plainTextLength); + + free(plainText); + free(paddingBuffer); + + return result; } diff --git a/OSX/libsecurity_transform/lib/SecCustomTransform.cpp b/OSX/libsecurity_transform/lib/SecCustomTransform.cpp index 6ae31b84..4d29a3d0 100644 --- a/OSX/libsecurity_transform/lib/SecCustomTransform.cpp +++ b/OSX/libsecurity_transform/lib/SecCustomTransform.cpp @@ -32,7 +32,7 @@ #include "Utilities.h" #include "misc.h" -static const CFStringRef kSecCustom = CFSTR("CustomTransform"); +const CFStringRef kSecCustom = CFSTR("CustomTransform"); const CFStringRef kSecTransformPreviousErrorKey = CFSTR("PreviousError"); const CFStringRef kSecTransformAbortOriginatorKey = CFSTR("Originating Transform"); const CFStringRef kSecTransformActionCanExecute = CFSTR("CanExecute"); @@ -303,14 +303,14 @@ public: }; -static SecTransformActionBlock default_can_run = ^{ return (CFTypeRef)NULL; }; -static SecTransformActionBlock default_execute_starting = default_can_run; -static SecTransformActionBlock default_finalize = default_execute_starting; -static SecTransformActionBlock default_externalize_data = default_finalize; +static const SecTransformActionBlock default_can_run = ^{ return (CFTypeRef)NULL; }; +static const SecTransformActionBlock default_execute_starting = default_can_run; +static const SecTransformActionBlock default_finalize = default_execute_starting; +static const SecTransformActionBlock default_externalize_data = default_finalize; -static SecTransformDataBlock default_process_data = ^(CFTypeRef value) { return value; }; +static const SecTransformDataBlock default_process_data = ^(CFTypeRef value) { return value; }; //static SecTransformDataBlock default_validate = ^(CFTypeRef value) { return (CFTypeRef)NULL; }; -static SecTransformAttributeActionBlock default_generic_attribute_set_notification = +static const SecTransformAttributeActionBlock default_generic_attribute_set_notification = ^(SecTransformAttributeRef ah, CFTypeRef value) { return value; }; static SecTransformAttributeActionBlock default_generic_attribute_validation = diff --git a/OSX/libsecurity_transform/lib/Transform.cpp b/OSX/libsecurity_transform/lib/Transform.cpp index 9046c3ce..a9d1fc7c 100644 --- a/OSX/libsecurity_transform/lib/Transform.cpp +++ b/OSX/libsecurity_transform/lib/Transform.cpp @@ -265,7 +265,12 @@ bool Transform::HasNoOutboundConnections() { // make an array big enough to hold all of the attributes CFIndex numAttributes = CFSetGetCount(mAttributes); - transform_attribute* attributes[numAttributes]; + transform_attribute **attributes = (transform_attribute**)malloc(numAttributes*sizeof(transform_attribute)); + + if (attributes == NULL) { + // No more memory, we assume it's orphaned + return true; + } TAGetAll(attributes); @@ -275,10 +280,13 @@ bool Transform::HasNoOutboundConnections() { if (attributes[i]->connections && CFArrayGetCount(attributes[i]->connections) != 0) { + free(attributes); return false; } } + free(attributes); + return true; } @@ -288,7 +296,12 @@ bool Transform::HasNoInboundConnections() { // make an array big enough to hold all of the attributes CFIndex numAttributes = CFSetGetCount(mAttributes); - transform_attribute* attributes[numAttributes]; + transform_attribute **attributes = (transform_attribute**)malloc(numAttributes*sizeof(transform_attribute)); + + if (attributes == NULL) { + // No more memory, we assume it's orphaned + return true; + } TAGetAll(attributes); @@ -298,10 +311,13 @@ bool Transform::HasNoInboundConnections() { if (attributes[i]->has_incoming_connection) { + free(attributes); return false; } } + free(attributes); + return true; } @@ -413,8 +429,14 @@ void Transform::FinalizePhase2() void Transform::FinalizeForClang() { CFIndex numAttributes = CFSetGetCount(mAttributes); - SecTransformAttributeRef handles[numAttributes]; - CFSetGetValues(mAttributes, (const void**)&handles); + SecTransformAttributeRef *handles = (const void**)malloc(numAttributes*sizeof(SecTransformAttributeRef)); + + if (handles == NULL) { + syslog(LOG_ERR, "Unable to allocate SecTransformAttributeRef handles in FinalizeForClang"); + return; + } + + CFSetGetValues(mAttributes, handles); for(CFIndex i = 0; i < numAttributes; ++i) { SecTransformAttributeRef ah = handles[i]; @@ -431,7 +453,7 @@ void Transform::FinalizeForClang() } dispatch_release(ta->q); } - + // We might be finalizing a transform as it is being activated, make sure that is complete before we do the rest dispatch_group_notify(mActivationPending, mDispatchQueue, ^{ if (mActivationQueue != NULL) { @@ -446,6 +468,8 @@ void Transform::FinalizeForClang() }); dispatch_release(mDispatchQueue); }); + + free(handles); } void Transform::Finalize() @@ -1598,9 +1622,17 @@ CFDictionaryRef Transform::GetAHDictForSaveState(SecTransformStringOrAttributeRe CFDictionaryRef Transform::CopyState() { CFIndex i, j, cnt = CFSetGetCount(mAttributes); - transform_attribute *attrs[cnt]; - CFStringRef names[cnt]; - CFDictionaryRef values[cnt]; + transform_attribute **attrs = (transform_attribute**)malloc(cnt*sizeof(transform_attribute)); + CFStringRef *names = (CFStringRef*)malloc(cnt*sizeof(CFStringRef)); + CFDictionaryRef *values = (CFDictionaryRef*)malloc(sizeof(CFDictionaryRef) * cnt); + + if (attrs == NULL || names == NULL || values == NULL) { + free(attrs); + free(names); + free(values); + return NULL; + } + TAGetAll(attrs); for(i = j = 0; i < cnt; ++i) { @@ -1613,7 +1645,9 @@ CFDictionaryRef Transform::CopyState() } CFDictionaryRef result = CFDictionaryCreate(NULL, (const void**)&names, (const void**)&values, j, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - + + free(names); + for(i = j = 0; i < cnt; ++i) { transform_attribute *ta = attrs[i]; @@ -1623,6 +1657,8 @@ CFDictionaryRef Transform::CopyState() } } + free(attrs); + free(values); return result; } @@ -1783,7 +1819,12 @@ CFErrorRef Transform::ProcessExternalize(CFMutableArrayRef transforms, CFMutable // now walk the attribute list CFIndex numAttributes = CFSetGetCount(mAttributes); - transform_attribute *attributes[numAttributes]; + transform_attribute **attributes = (transform_attribute**)malloc(numAttributes*sizeof(transform_attribute)); + + if (attributes == NULL) { + return GetNoMemoryErrorAndRetain(); + } + TAGetAll(attributes); CFIndex i; @@ -1819,5 +1860,7 @@ CFErrorRef Transform::ProcessExternalize(CFMutableArrayRef transforms, CFMutable } } + free(attributes); + return NULL; } diff --git a/OSX/libsecurity_transform/lib/TransformFactory.cpp b/OSX/libsecurity_transform/lib/TransformFactory.cpp index 6ab2ea34..91f7d661 100644 --- a/OSX/libsecurity_transform/lib/TransformFactory.cpp +++ b/OSX/libsecurity_transform/lib/TransformFactory.cpp @@ -85,7 +85,13 @@ SecTransformRef TransformFactory::MakeTransformWithType(CFStringRef type, CFErro dispatch_barrier_sync(gRegisteredQueue, ^(void) { CFMutableStringRef transformNames = CFStringCreateMutable(NULL, 0); CFIndex numberRegistered = CFDictionaryGetCount(gRegistered); - CFStringRef names[numberRegistered]; + CFStringRef *names = (CFStringRef*)malloc(numberRegistered * sizeof(CFStringRef)); + if (names == NULL) { + *baseError = CreateSecTransformErrorRef(errSecMemoryError, + "The %s transform names can't be allocated.", type); + return NULL; + } + CFDictionaryGetKeysAndValues(gRegistered, (const void**)names, NULL); for(int i = 0; i < numberRegistered; i++) { if (i != 0) { @@ -94,6 +100,8 @@ SecTransformRef TransformFactory::MakeTransformWithType(CFStringRef type, CFErro CFStringAppend(transformNames, names[i]); } + free(names); + *baseError = CreateSecTransformErrorRef(kSecTransformTransformIsNotRegistered, "The %s transform is not registered, choose from: %@", type,transformNames); diff --git a/OSX/libsecurity_transform/lib/misc.h b/OSX/libsecurity_transform/lib/misc.h index 9750393d..1c6cf751 100644 --- a/OSX/libsecurity_transform/lib/misc.h +++ b/OSX/libsecurity_transform/lib/misc.h @@ -36,8 +36,8 @@ extern "C" { CFErrorRef fancy_error(CFStringRef domain, CFIndex code, CFStringRef description); extern void graphviz(FILE *f, SecTransformRef tr); extern void CFfprintf(FILE *f, const char *format, ...); - CFErrorRef GetNoMemoryError(); - CFErrorRef GetNoMemoryErrorAndRetain(); + CFErrorRef GetNoMemoryError(void); + CFErrorRef GetNoMemoryErrorAndRetain(void); void CFSafeRelease(CFTypeRef object); // NOTE: the return may or allocate a fair bit more space then it needs. diff --git a/OSX/libsecurity_utilities/lib/debugging_internal.h b/OSX/libsecurity_utilities/lib/debugging_internal.h index a33ee7c2..334f7123 100644 --- a/OSX/libsecurity_utilities/lib/debugging_internal.h +++ b/OSX/libsecurity_utilities/lib/debugging_internal.h @@ -80,7 +80,8 @@ string typeName() #undef DEBUGGING #if !defined(NDEBUG) # define DEBUGGING 1 -# define DEBUGDUMP 1 +// No more debugdump, it emits thread-unsafe buggy code which hampers actual debugging, ironically enough +// # define DEBUGDUMP 1 #else //NDEBUG # define DEBUGGING 0 #endif //NDEBUG @@ -125,8 +126,8 @@ typedef const void *DTException; #include // The following are deprecated functions. Don't use them (but they need to be here for symbol reasons). -void secdebug_internal(const char* scope, const char* format, ...); -void secdebugfunc_internal(const char* scope, const char* functionname, const char* format, ...); +__attribute__((visibility("default"))) void secdebug_internal(const char* scope, const char* format, ...); +__attribute__((visibility("default"))) void secdebugfunc_internal(const char* scope, const char* functionname, const char* format, ...); __END_DECLS diff --git a/OSX/libsecurity_utilities/lib/errors.cpp b/OSX/libsecurity_utilities/lib/errors.cpp index 9ecda042..9c99aea5 100644 --- a/OSX/libsecurity_utilities/lib/errors.cpp +++ b/OSX/libsecurity_utilities/lib/errors.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -164,8 +165,14 @@ MacOSError::MacOSError(int err) : error(err) SECURITY_EXCEPTION_THROW_OSSTATUS(this, err); snprintf(whatBuffer, whatBufferSize, "MacOS error: %d", this->error); - secnotice("security_exception", "%s", what()); - LogBacktrace(); + switch (err) { + case errSecCSReqFailed: + // This 'error' isn't an actual error and doesn't warrant being logged. + break; + default: + secnotice("security_exception", "%s", what()); + LogBacktrace(); + } } const char *MacOSError::what() const throw () diff --git a/OSX/libsecurity_utilities/lib/mach++.cpp b/OSX/libsecurity_utilities/lib/mach++.cpp index fcd1c4a7..c8271d94 100644 --- a/OSX/libsecurity_utilities/lib/mach++.cpp +++ b/OSX/libsecurity_utilities/lib/mach++.cpp @@ -25,6 +25,9 @@ // // mach++ - C++ bindings for useful Mach primitives // +#define __STDC_WANT_LIB_EXT1__ 1 +#include + #include #include #include @@ -347,10 +350,14 @@ void Message::setBuffer(mach_msg_size_t size) assert(size >= sizeof(mach_msg_header_t)); release(); mSize = size + MAX_TRAILER_SIZE; - mBuffer = reinterpret_cast(new char[mSize]); + mBuffer = reinterpret_cast(new char[mSize]()); mRelease = true; } +void Message::clearBuffer(void) +{ + (void)memset_s(mBuffer, mSize, 0, mSize); +} void Message::release() { diff --git a/OSX/libsecurity_utilities/lib/mach++.h b/OSX/libsecurity_utilities/lib/mach++.h index db092231..b2fe9425 100644 --- a/OSX/libsecurity_utilities/lib/mach++.h +++ b/OSX/libsecurity_utilities/lib/mach++.h @@ -276,6 +276,7 @@ public: void setBuffer(void *buffer, mach_msg_size_t size); // use buffer with size void setBuffer(mach_msg_size_t size); // allocate buffer with size + void clearBuffer(void); void release(); // discard buffer (if any) operator mig_reply_error_t & () const { return *mBuffer; } diff --git a/OSX/libsecurity_utilities/lib/mach_notify.h b/OSX/libsecurity_utilities/lib/mach_notify.h index 86853c6b..fef3bf90 100644 --- a/OSX/libsecurity_utilities/lib/mach_notify.h +++ b/OSX/libsecurity_utilities/lib/mach_notify.h @@ -45,7 +45,7 @@ typedef struct { char *name; function_ptr_t function; } function_table_entry; -typedef function_table_entry *function_table_t; +typedef function_table_entry *function_table_t; #endif /* FUNCTION_PTR_T */ #endif /* AUTOTEST */ @@ -54,11 +54,15 @@ typedef function_table_entry *function_table_t; #endif /* notify_MSG_COUNT */ #include +#include #ifdef __BeforeMigUserHeader __BeforeMigUserHeader #endif /* __BeforeMigUserHeader */ +#include +__BEGIN_DECLS + /* SimpleRoutine mach_notify_port_deleted */ #ifdef mig_external @@ -66,7 +70,7 @@ mig_external #else extern #endif /* mig_external */ -kern_return_t mach_notify_port_deleted +kern_return_t cdsa_mach_notify_port_deleted ( mach_port_t notify, mach_port_name_t name @@ -78,11 +82,10 @@ mig_external #else extern #endif /* mig_external */ -kern_return_t mach_notify_port_destroyed +kern_return_t cdsa_mach_notify_port_destroyed ( mach_port_t notify, - mach_port_t rights, - mach_msg_type_name_t rightsPoly + mach_port_t rights ); /* SimpleRoutine mach_notify_no_senders */ @@ -91,7 +94,7 @@ mig_external #else extern #endif /* mig_external */ -kern_return_t mach_notify_no_senders +kern_return_t cdsa_mach_notify_no_senders ( mach_port_t notify, mach_port_mscount_t mscount @@ -103,7 +106,7 @@ mig_external #else extern #endif /* mig_external */ -kern_return_t mach_notify_send_once +kern_return_t cdsa_mach_notify_send_once ( mach_port_t notify ); @@ -114,12 +117,14 @@ mig_external #else extern #endif /* mig_external */ -kern_return_t mach_notify_dead_name +kern_return_t cdsa_mach_notify_dead_name ( mach_port_t notify, mach_port_name_t name ); +__END_DECLS + #ifndef subsystem_to_name_map_notify #define subsystem_to_name_map_notify \ { "mach_notify_port_deleted", 65 },\ diff --git a/OSX/libsecurity_utilities/lib/machserver.cpp b/OSX/libsecurity_utilities/lib/machserver.cpp index b2f2b775..8f825ba2 100644 --- a/OSX/libsecurity_utilities/lib/machserver.cpp +++ b/OSX/libsecurity_utilities/lib/machserver.cpp @@ -237,6 +237,9 @@ void MachServer::runServerThread(bool doTimeout) continue; } + // reset the buffer each time, handlers don't consistently set out params + bufReply.clearBuffer(); + // process received message if (bufRequest.msgId() >= MACH_NOTIFY_FIRST && bufRequest.msgId() <= MACH_NOTIFY_LAST) { @@ -546,52 +549,57 @@ void MachServer::clearTimer(Timer *timer) // // Notification hooks and shims. Defaults do nothing. // -void cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port) +kern_return_t cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port) { try { MachServer::active().notifyDeadName(port); } catch (...) { } + return KERN_SUCCESS; } void MachServer::notifyDeadName(Port) { } -void cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port) +kern_return_t cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port) { try { MachServer::active().notifyPortDeleted(port); } catch (...) { } + return KERN_SUCCESS; } void MachServer::notifyPortDeleted(Port) { } -void cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port) +kern_return_t cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port) { try { MachServer::active().notifyPortDestroyed(port); } catch (...) { } + return KERN_SUCCESS; } void MachServer::notifyPortDestroyed(Port) { } -void cdsa_mach_notify_send_once(mach_port_t port) +kern_return_t cdsa_mach_notify_send_once(mach_port_t port) { try { MachServer::active().notifySendOnce(port); } catch (...) { } + return KERN_SUCCESS; } void MachServer::notifySendOnce(Port) { } -void cdsa_mach_notify_no_senders(mach_port_t port, mach_port_mscount_t count) +kern_return_t cdsa_mach_notify_no_senders(mach_port_t port, mach_port_mscount_t count) { try { MachServer::active().notifyNoSenders(port, count); } catch (...) { } + return KERN_SUCCESS; } void MachServer::notifyNoSenders(Port, mach_port_mscount_t) { } diff --git a/OSX/libsecurity_utilities/lib/machserver.h b/OSX/libsecurity_utilities/lib/machserver.h index 972aa9de..5b153ab1 100644 --- a/OSX/libsecurity_utilities/lib/machserver.h +++ b/OSX/libsecurity_utilities/lib/machserver.h @@ -41,11 +41,11 @@ namespace MachPlusPlus { extern "C" { - void cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port); - void cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port); - void cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port); - void cdsa_mach_notify_send_once(mach_port_t); - void cdsa_mach_notify_no_senders(mach_port_t, mach_port_mscount_t); + kern_return_t cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port); + kern_return_t cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port); + kern_return_t cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port); + kern_return_t cdsa_mach_notify_send_once(mach_port_t); + kern_return_t cdsa_mach_notify_no_senders(mach_port_t, mach_port_mscount_t); }; @@ -236,11 +236,11 @@ private: void setup(const char *name); void runServerThread(bool doTimeout = false); - friend void cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port); - friend void cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port); - friend void cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port); - friend void cdsa_mach_notify_send_once(mach_port_t); - friend void cdsa_mach_notify_no_senders(mach_port_t, mach_port_mscount_t); + friend kern_return_t cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port); + friend kern_return_t cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port); + friend kern_return_t cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port); + friend kern_return_t cdsa_mach_notify_send_once(mach_port_t); + friend kern_return_t cdsa_mach_notify_no_senders(mach_port_t, mach_port_mscount_t); }; diff --git a/OSX/libsecurity_utilities/lib/refcount.h b/OSX/libsecurity_utilities/lib/refcount.h index 945488f1..e94f5657 100644 --- a/OSX/libsecurity_utilities/lib/refcount.h +++ b/OSX/libsecurity_utilities/lib/refcount.h @@ -82,9 +82,6 @@ protected: RCDEBUG(DOWN, mRefCount - 1); return OSAtomicDecrement32(&mRefCount); } - - // if you call this for anything but debug output, you will go to hell (free handbasket included) - unsigned int refCountForDebuggingOnly() const { return mRefCount; } private: volatile mutable int32_t mRefCount; diff --git a/OSX/macos_tapi_hacks.h b/OSX/macos_tapi_hacks.h index c5b25793..ae9740d2 100644 --- a/OSX/macos_tapi_hacks.h +++ b/OSX/macos_tapi_hacks.h @@ -38,7 +38,11 @@ #include #include +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvisibility" + CFDataRef SecDistinguishedNameCopyNormalizedContent(CFDataRef distinguished_name); +SecKeyRef SecCertificateCopyPublicKey_ios(SecCertificateRef certificate); CFDataRef _SecItemCreatePersistentRef(CFTypeRef iclass, sqlite_int64 rowid, CFDictionaryRef attributes); CFDictionaryRef SecTokenItemValueCopy(CFDataRef db_value, CFErrorRef *error); CFArrayRef SecTrustCopyProperties_ios(SecTrustRef trust); @@ -65,6 +69,10 @@ extern SecurityClient * SecSecurityClientGet(void); bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error, bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), bool (^handle_response)(xpc_object_t response, CFErrorRef* error)); +typedef void (^securityd_handler_t)(xpc_object_t reply, CFErrorRef error); +void securityd_send_async_and_do(enum SecXPCOperation op, dispatch_queue_t replyq, + bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), + securityd_handler_t handler); XPC_RETURNS_RETAINED xpc_object_t securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error); XPC_RETURNS_RETAINED xpc_object_t securityd_create_message(enum SecXPCOperation op, CFErrorRef *error); bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error); @@ -86,4 +94,6 @@ CFDataRef SecSHA256DigestCreateFromData(CFAllocatorRef allocator, CFDataRef data CFStringRef SecFrameworkCopyLocalizedString(CFStringRef key, CFStringRef tableName); +#pragma clang diagnostic pop + #endif /* macos_tapi_hack_h */ diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c index 771179a5..af3c99d3 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c +++ b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c @@ -130,17 +130,25 @@ errOut: return retval; }; +static SOSCloudTransportRef defaultTransport = NULL; + +void +SOSCloudTransportSetDefaultTransport(SOSCloudTransportRef transport) +{ + defaultTransport = transport; +} static SOSCloudTransportRef SOSCloudTransportDefaultTransport(void) { static dispatch_once_t sTransportOnce; - static SOSCloudTransportRef sTransport = NULL; dispatch_once(&sTransportOnce, ^{ - sTransport = SOSCloudTransportCreateXPCTransport(); - // provide state handler to sysdiagnose and logging - os_state_add_handler(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), kvsStateBlock); + if (defaultTransport == NULL) { + defaultTransport = SOSCloudTransportCreateXPCTransport(); + // provide state handler to sysdiagnose and logging + os_state_add_handler(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), kvsStateBlock); + } }); - return sTransport; + return defaultTransport; } @@ -199,7 +207,6 @@ struct SOSXPCCloudTransport { struct SOSCloudTransport transport; xpc_connection_t serviceConnection; - xpc_connection_t idsProxyServiceConnection; dispatch_queue_t xpc_queue; }; @@ -240,31 +247,6 @@ static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CF return false; } -static void setupIDSProxyServiceConnection(SOSXPCCloudTransportRef transport) -{ - secnotice(SOSCKCSCOPE, "IDS Transport: setting up xpc connection"); - transport->idsProxyServiceConnection = xpc_connection_create_mach_service(xpcIDSServiceName, transport->xpc_queue, 0); - - secdebug(SOSCKCSCOPE, "ids service connection: %p\n", transport->idsProxyServiceConnection); - - xpc_connection_set_event_handler(transport->idsProxyServiceConnection, ^(xpc_object_t event) { - secdebug(SOSCKCSCOPE, "IDS Transport, xpc_connection_set_event_handler\n"); - if(event == XPC_ERROR_CONNECTION_INVALID){ - secnotice(SOSCKCSCOPE, "IDS Transport: xpc connection invalid. Oh well."); - } - }); - - xpc_connection_activate(transport->idsProxyServiceConnection); -} - -static void teardownIDSProxyServiceConnection(SOSXPCCloudTransportRef transport) -{ - secnotice(SOSCKCSCOPE, "IDS Transport: tearing down xpc connection"); - dispatch_assert_queue(transport->xpc_queue); - xpc_release(transport->idsProxyServiceConnection); - transport->idsProxyServiceConnection = NULL; -} - static void setupServiceConnection(SOSXPCCloudTransportRef transport) { secnotice(SOSCKCSCOPE, "CKP Transport: setting up xpc connection"); @@ -297,79 +279,16 @@ static void SOSXPCCloudTransportInit(SOSXPCCloudTransportRef transport) transport->xpc_queue = dispatch_queue_create(xpcServiceName, DISPATCH_QUEUE_SERIAL); setupServiceConnection(transport); - setupIDSProxyServiceConnection(transport); // Any time a new session starts, reestablish the XPC connections. int token; notify_register_dispatch("com.apple.system.loginwindow.desktopUp", &token, transport->xpc_queue, ^(int token2) { - secnotice(SOSCKCSCOPE, "CKP/IDS Transport: desktopUp happened, reestablishing xpc connections"); + secnotice(SOSCKCSCOPE, "CKP Transport: desktopUp happened, reestablishing xpc connections"); teardownServiceConnection(transport); setupServiceConnection(transport); - teardownIDSProxyServiceConnection(transport); - setupIDSProxyServiceConnection(transport); }); } -static void talkWithIDS(SOSXPCCloudTransportRef transport, xpc_object_t message, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) -{ - CFErrorRef connectionError = NULL; - - os_activity_t trace_activity = os_activity_start("talkWithIDS", OS_ACTIVITY_FLAG_DEFAULT); - require_action(transport->idsProxyServiceConnection, xit, connectionError = makeError(kSOSConnectionNotOpen)); - require_action(message, xit, connectionError = makeError(kSOSObjectNotFoundError)); - dispatch_retain(processQueue); - - xpc_connection_send_message_with_reply(transport->idsProxyServiceConnection, message, transport->xpc_queue, ^(xpc_object_t reply) - { - CFErrorRef serverError = NULL; - CFTypeRef object = NULL; - if (xpc_event_filter(transport->idsProxyServiceConnection, reply, &serverError) && reply) - { - if (serverError) - secerror("Error from xpc_event_filter: %@", serverError); - xpc_object_t xrv = xpc_dictionary_get_value(reply, kMessageKeyValue); - if (xrv) - { - /* - * The given XPC object must be one that was previously returned by - * _CFXPCCreateXPCMessageWithCFObject(). - */ - object = _CFXPCCreateCFObjectFromXPCObject(xrv); // CF object is retained; release in callback - secnotice("talkwithIDS", "converted CF object: %@", object); - } - else - secerror("missing value reply"); - - xpc_object_t xerror = xpc_dictionary_get_value(reply, kMessageKeyError); - if (xerror) - serverError = SecCreateCFErrorWithXPCObject(xerror); // use SecCFCreateErrorWithFormat? - } - dispatch_async(processQueue, ^{ - if (replyBlock) - replyBlock(object, serverError); - CFReleaseSafe(object); - if (serverError) - { - secerror("talkwithIDS callback error: %@", serverError); - CFReleaseSafe(serverError); - } - dispatch_release(processQueue); - }); - }); - return; - -xit: - secerror("talkWithIDS error: %@", connectionError); - dispatch_async(processQueue, ^{ - if (replyBlock) - replyBlock(NULL, connectionError); - CFReleaseSafe(connectionError); - dispatch_release(processQueue); - }); - - os_activity_end(trace_activity); -} - typedef void (^ProxyReplyBlock)(xpc_object_t reply); static bool messageToProxy(SOSXPCCloudTransportRef transport, xpc_object_t message, CFErrorRef *error, dispatch_queue_t processQueue, ProxyReplyBlock replyBlock) { @@ -524,105 +443,6 @@ static void SecXPCDictionarySetCFObject(xpc_object_t xdict, const char *key, CFT xpc_release(xpc_obj); } -static void SOSCloudTransportGetIDSDeviceID(SOSCloudTransportRef transport, CloudKeychainReplyBlock replyBlock) -{ - dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - - SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport; - - xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); - xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion); - xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGetDeviceID); - - talkWithIDS(xpcTransport, message, processQueue, replyBlock); - xpc_release(message); -} - -static void SOSCloudTransportGetPerformanceStats(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) -{ - SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport; - - xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); - xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion); - xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGetIDSPerfCounters); - - talkWithIDS(xpcTransport, message, processQueue, replyBlock); - xpc_release(message); -} - -static void SOSCloudTransportSendFragmentedIDSMessage(SOSCloudTransportRef transport, CFDictionaryRef messageData, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){ - - SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport; - xpc_object_t xmessageData = _CFXPCCreateXPCObjectFromCFObject(messageData); - - xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); - xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion); - xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSendFragmentedIDSMessage); - - xpc_dictionary_set_value(message, kMessageKeyValue, xmessageData); - SecXPCDictionarySetCFObject(message, kMessageKeyDeviceName, deviceName); - SecXPCDictionarySetCFObject(message, kMessageKeyPeerID, peerID); - SecXPCDictionarySetCFObject(message, kMessageKeyDeviceID, myDeviceID); - - talkWithIDS(xpcTransport, message, processQueue, replyBlock); - - xpc_release(xmessageData); - xpc_release(message); -} - -static void SOSCloudTransportRetrievePendingMessagesInFlight(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){ - - SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport; - - xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); - xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion); - xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGetPendingMesages); - - talkWithIDS(xpcTransport, message, processQueue, replyBlock); - - xpc_release(message); -} - -static void SOSCloudTransportCheckIDSDeviceIDAvailability(SOSCloudTransportRef transport, CFArrayRef ids, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) -{ - secdebug(SOSCKCSCOPE, "start"); - SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport; - - xpc_object_t xIDSArray = _CFXPCCreateXPCObjectFromCFObject(ids); - - xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); - xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion); - xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSendDeviceList); - - SecXPCDictionarySetCFObject(message, kMessageKeyPeerID, peerID); - xpc_dictionary_set_value(message, kMessageKeyValue, xIDSArray); - - talkWithIDS(xpcTransport, message, processQueue, replyBlock); - - xpc_release(xIDSArray); - xpc_release(message); - -} - -static void SOSCloudTransportSendIDSMessage(SOSCloudTransportRef transport, CFDictionaryRef messageData, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){ - - SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport; - xpc_object_t xmessageData = _CFXPCCreateXPCObjectFromCFObject(messageData); - - xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); - xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion); - xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSendIDSMessage); - - xpc_dictionary_set_value(message, kMessageKeyValue, xmessageData); - SecXPCDictionarySetCFObject(message, kMessageKeyDeviceName, deviceName); - SecXPCDictionarySetCFObject(message, kMessageKeyPeerID, peerID); - SecXPCDictionarySetCFObject(message, kMessageKeyDeviceID, myDeviceID); - talkWithIDS(xpcTransport, message, processQueue, replyBlock); - - xpc_release(xmessageData); - xpc_release(message); -} - static void SOSCloudTransportUpdateKeys(SOSCloudTransportRef transport, CFDictionaryRef keys, CFStringRef accountUUID, @@ -833,11 +653,7 @@ static SOSCloudTransportRef SOSCloudTransportCreateXPCTransport(void) st = calloc(1, sizeof(*st)); st->transport.put = SOSCloudTransportPut; st->transport.updateKeys = SOSCloudTransportUpdateKeys; - st->transport.sendIDSMessage = SOSCloudTransportSendIDSMessage; - st->transport.sendFragmentedIDSMessage = SOSCloudTransportSendFragmentedIDSMessage; - st->transport.retrieveMessages = SOSCloudTransportRetrievePendingMessagesInFlight; - st->transport.getDeviceID = SOSCloudTransportGetIDSDeviceID; st->transport.get = SOSCloudTransportGet; st->transport.getAll = SOSCloudTransportGetAll; st->transport.synchronize = SOSCloudTransportSync; @@ -848,10 +664,8 @@ static SOSCloudTransportRef SOSCloudTransportCreateXPCTransport(void) st->transport.hasPendingKey = SOSCloudTransportHasPendingKey; st->transport.requestEnsurePeerRegistration = SOSCloudTransportRequestEnsurePeerRegistration; st->transport.requestPerfCounters = SOSCloudTransportRequestPerfCounters; - st->transport.getIDSDeviceAvailability = SOSCloudTransportCheckIDSDeviceIDAvailability; st->transport.flush = SOSCloudTransportFlush; st->transport.removeKeys = SOSCloudTransportRemoveKeys; - st->transport.counters = SOSCloudTransportGetPerformanceStats; st->transport.itemsChangedBlock = Block_copy(^CFArrayRef(CFDictionaryRef changes) { secerror("Calling default itemsChangedBlock - fatal: %@", changes); assert(false); @@ -893,47 +707,6 @@ void SOSCloudKeychainRemoveKeys(CFArrayRef keys, CFStringRef accountUUID, dispat cTransportRef->removeKeys(cTransportRef, keys, accountUUID, processQueue, replyBlock); } -void SOSCloudKeychainSendIDSMessage(CFDictionaryRef message, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CFBooleanRef fragmentation, CloudKeychainReplyBlock replyBlock) -{ - SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport(); - - if(cTransportRef && fragmentation == kCFBooleanTrue) - cTransportRef->sendFragmentedIDSMessage(cTransportRef, message, deviceName, peerID, myDeviceID, processQueue, replyBlock); - else if(cTransportRef) - cTransportRef->sendIDSMessage(cTransportRef, message, deviceName, peerID, myDeviceID, processQueue, replyBlock); - -} - -void SOSCloudKeychainRetrievePendingMessageFromProxy(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) -{ - SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport(); - - if(cTransportRef) - cTransportRef->retrieveMessages(cTransportRef, processQueue, replyBlock); - -} -void SOSCloudKeychainRetrieveCountersFromIDSProxy(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) -{ - SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport(); - - if(cTransportRef) - cTransportRef->counters(cTransportRef, processQueue, replyBlock); - -} -void SOSCloudKeychainGetIDSDeviceID(CloudKeychainReplyBlock replyBlock) -{ - SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport(); - if (cTransportRef) - cTransportRef->getDeviceID(cTransportRef, replyBlock); - -} -void SOSCloudKeychainGetIDSDeviceAvailability(CFArrayRef ids, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){ - - SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport(); - - if (cTransportRef) - cTransportRef->getIDSDeviceAvailability(cTransportRef, ids, peerID, processQueue, replyBlock); -} CF_RETURNS_RETAINED CFArrayRef SOSCloudKeychainHandleUpdateMessage(CFDictionaryRef updates) { CFArrayRef result = NULL; diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h index b3e2ffd0..9d20907e 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h +++ b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h @@ -67,9 +67,6 @@ struct SOSCloudTransport void (*put)(SOSCloudTransportRef transport, CFDictionaryRef valuesToPut, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void (*updateKeys)(SOSCloudTransportRef transport, CFDictionaryRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); - void (*sendIDSMessage)(SOSCloudTransportRef transport, CFDictionaryRef data, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); - void (*sendFragmentedIDSMessage)(SOSCloudTransportRef transport, CFDictionaryRef data, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); - void (*retrieveMessages) (SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void (*getDeviceID)(SOSCloudTransportRef transport, CloudKeychainReplyBlock replyBlock); // Debug calls @@ -90,15 +87,11 @@ struct SOSCloudTransport void (*requestPerfCounters)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void (*flush)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); const void *itemsChangedBlock; - void (*getIDSDeviceAvailability)(SOSCloudTransportRef transport, CFArrayRef ids, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void (*removeKeys)(SOSCloudTransportRef transport, CFArrayRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void (*counters)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); }; -void SOSCloudKeychainGetIDSDeviceID(CloudKeychainReplyBlock replyBlock); -void SOSCloudKeychainRetrievePendingMessageFromProxy(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); - void SOSCloudKeychainUpdateKeys(CFDictionaryRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void SOSCloudKeychainPutObjectsInCloud(CFDictionaryRef objects, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); @@ -124,11 +117,11 @@ void SOSCloudKeychainRequestPerfCounters(dispatch_queue_t processQueue, CloudKey void SOSCloudKeychainFlush(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); CFDictionaryRef SOSCloudCopyKVSState(void); -void SOSCloudKeychainGetIDSDeviceAvailability(CFArrayRef ids, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void SOSCloudKeychainRemoveKeys(CFArrayRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); -void SOSCloudKeychainRetrieveCountersFromIDSProxy(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); -void SOSCloudKeychainSendIDSMessage(CFDictionaryRef message, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CFBooleanRef fragmentation, CloudKeychainReplyBlock replyBlock); +// For unit tests +void +SOSCloudTransportSetDefaultTransport(SOSCloudTransportRef transport); __END_DECLS diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c index fed2fc46..7841f7a5 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c +++ b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c @@ -41,7 +41,6 @@ const uint64_t kCKDXPCVersion = 1; // seems like launchd looks for the BundleIdentifier, not the name const char *xpcServiceName = "com.apple.security.cloudkeychainproxy3"; //"CloudKeychainProxy"; -const char *xpcIDSServiceName = "com.apple.security.keychainsyncingoveridsproxy"; const char *kMessageKeyOperation = "operation"; const char *kMessageKeyKey = "key"; @@ -55,7 +54,6 @@ const char *kMessageKeyKeysRequiresUnlocked = "KeysRequiresUnlocked"; const char *kMessageKeyNotificationFlags = "NotificationFlags"; const char *kMessageKeyPeerIDList = "peerIDList"; const char *kMesssgeKeyBackupPeerIDList = "backupPeerIDList"; -const char *kOperationSendDeviceList = "IDSDeviceList"; /* parameters within the dictionary */ const char *kMessageAlwaysKeys = "AlwaysKeys"; @@ -68,12 +66,9 @@ const char *kMessageKeyParameter = "KeyParameter"; const char *kMessageCircle = "Circle"; const char *kMessageMessage = "Message"; const char *kMessageKeyDeviceName = "deviceName"; -const char *kMessageKeyIDSDataMessage = "idsDataMessage"; -const char *kMessageKeyDeviceID = "deviceID"; const char *kMessageKeyPeerID = "peerID"; const char *kMessageKeySendersPeerID = "sendersPeerID"; const char *kMessageKeyAccountUUID = "AcctUUID"; -const char *kMessageKeySenderDeviceID = "SendersDeviceID"; const char *kMessageOperationItemChanged = "ItemChanged"; @@ -91,15 +86,8 @@ const char *kOperationGETv2 = "GETv2"; const char *kOperationRegisterKeys = "RegisterKeys"; const char *kOperationRemoveKeys = "RemoveKeys"; -const char *kOperationGetDeviceID = "DeviceID"; -const char *kOperationGetIDSPerfCounters = "IDSPerf"; - const char *kOperationHasPendingKey = "hasPendingKey"; -const char *kOperationSendIDSMessage = "IDSMessage"; -const char *kOperationSendFragmentedIDSMessage = "IDSMessageFragmented"; -const char *kOperationGetPendingMesages = "IDSPendingMessages"; - const char *kOperationRequestSyncWithPeers = "requestSyncWithPeers"; const char *kOperationHasPendingSyncWithPeer = "hasPendingSyncWithPeer"; const char *kOperationRequestEnsurePeerRegistration = "requestEnsurePeerRegistration"; diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h index 46879416..a9fda436 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h +++ b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h @@ -31,7 +31,6 @@ __BEGIN_DECLS extern const char *xpcServiceName; -extern const char *xpcIDSServiceName;; extern const char *kMessageKeyOperation; extern const char *kMessageKeyKey; @@ -45,16 +44,9 @@ extern const char *kMessageKeyKeysRequiresUnlocked; extern const char *kMessageOperationItemChanged; extern const char *kMessageKeyNotificationFlags; extern const char *kMessageKeyPeerIDList; -extern const char *kMesssgeKeyBackupPeerIDList; -extern const char *kMessageKeyIDS; -extern const char *kMessageKeyDeviceName; -extern const char *kMessageKeyIDSDataMessage; -extern const char *kMessageKeyDeviceID; extern const char *kMessageKeyPeerID; -extern const char *kMessageKeySendersPeerID; +extern const char *kMesssgeKeyBackupPeerIDList; extern const char *kMessageKeyAccountUUID; -extern const char *kOperationSendDeviceList; -extern const char *kMessageKeySenderDeviceID; extern const char *kMessageContext; extern const char *kMessageKeyParameter; @@ -75,9 +67,7 @@ extern const char *kOperationGETv2; extern const char *kOperationRegisterKeys; extern const char *kOperationRemoveKeys; -extern const char *kOperationGetDeviceID; extern const char *kOperationHasPendingKey; -extern const char *kOperationGetIDSPerfCounters; extern const uint64_t kCKDXPCVersion; @@ -89,9 +79,7 @@ extern const char *kOperationRequestSyncWithPeers; extern const char *kOperationHasPendingSyncWithPeer; extern const char *kOperationRequestEnsurePeerRegistration; -extern const char *kOperationSendIDSMessage; -extern const char *kOperationSendFragmentedIDSMessage; extern const char *kOperationGetPendingMesages; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h index a0baeb5d..f19f91b2 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -51,7 +50,8 @@ __BEGIN_DECLS #define RETIREMENT_FINALIZATION_SECONDS (24*60*60) -typedef void (^SOSAccountCircleMembershipChangeBlock)(SOSCircleRef new_circle, +typedef void (^SOSAccountCircleMembershipChangeBlock)(SOSAccount* account, + SOSCircleRef new_circle, CFSetRef added_peers, CFSetRef removed_peers, CFSetRef added_applicants, CFSetRef removed_applicants); @@ -61,18 +61,6 @@ SOSAccount* SOSAccountCreate(CFAllocatorRef allocator, CFDictionaryRef gestalt, SOSDataSourceFactoryRef factory); -// -// MARK: Persistent Encode decode -// - -// -//MARK: IDS Device ID -CFStringRef SOSAccountCopyDeviceID(SOSAccount* account, CFErrorRef *error); -bool SOSAccountSetMyDSID(SOSAccountTransaction* txn, CFStringRef IDS, CFErrorRef* errror); -bool SOSAccountSendIDSTestMessage(SOSAccount* account, CFStringRef message, CFErrorRef *error); -bool SOSAccountStartPingTest(SOSAccount* account, CFStringRef message, CFErrorRef *error); -bool SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(SOSAccount* account, CFErrorRef *error); - // // MARK: Credential management // @@ -118,8 +106,11 @@ void SOSTransportEachMessage(SOSAccount* account, CFDictionaryRef updates, CFEr CFStringRef SOSAccountGetSOSCCStatusString(SOSCCStatus status); SOSCCStatus SOSAccountGetSOSCCStatusFromString(CFStringRef status); bool SOSAccountJoinCircles(SOSAccountTransaction* aTxn, CFErrorRef* error); +bool SOSAccountJoinCirclesWithAnalytics(SOSAccountTransaction* aTxn, NSData* parentEvent, CFErrorRef* error); bool SOSAccountJoinCirclesAfterRestore(SOSAccountTransaction* aTxn, CFErrorRef* error); +bool SOSAccountJoinCirclesAfterRestoreWithAnalytics(SOSAccountTransaction* aTxn, NSData* parentEvent, CFErrorRef* error); bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFErrorRef* error); +bool SOSAccountRemovePeersFromCircleWithAnalytics(SOSAccount* account, CFArrayRef peers, NSData* parentEvent, CFErrorRef* error); bool SOSAccountBail(SOSAccount* account, uint64_t limit_in_seconds, CFErrorRef* error); bool SOSAccountAcceptApplicants(SOSAccount* account, CFArrayRef applicants, CFErrorRef* error); bool SOSAccountRejectApplicants(SOSAccount* account, CFArrayRef applicants, CFErrorRef* error); @@ -175,7 +166,6 @@ bool SOSAccountHandleParametersChange(SOSAccount* account, CFDataRef updates, C // bool SOSAccountRequestSyncWithAllPeers(SOSAccountTransaction* txn, CFErrorRef *error); CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransaction* txn, CFSetRef /* CFStringRef */ peerIDs, CFErrorRef *error); -CF_RETURNS_RETAINED CFSetRef SOSAccountSyncWithPeersOverIDS(SOSAccountTransaction* txn, CFSetRef peers); CFSetRef SOSAccountSyncWithPeersOverKVS(SOSAccountTransaction* txn, CFSetRef peers); bool SOSAccountInflateTransports(SOSAccount* account, CFStringRef circleName, CFErrorRef *error); @@ -184,15 +174,10 @@ bool SOSAccountInflateTransports(SOSAccount* account, CFStringRef circleName, CF // bool SOSAccountSyncWithKVSPeerWithMessage(SOSAccountTransaction* txn, CFStringRef peerid, CFDataRef message, CFErrorRef *error); -bool SOSAccountClearPeerMessageKey(SOSAccountTransaction* txn, CFStringRef peerID, CFErrorRef *error); CF_RETURNS_RETAINED CFSetRef SOSAccountProcessSyncWithPeers(SOSAccountTransaction* txn, CFSetRef /* CFStringRef */ peers, CFSetRef /* CFStringRef */ backupPeers, CFErrorRef *error); CF_RETURNS_RETAINED CFSetRef SOSAccountCopyBackupPeersAndForceSync(SOSAccountTransaction* txn, CFErrorRef *error); -bool SOSAccountSendIKSPSyncList(SOSAccount* account, CFErrorRef *error); -bool SOSAccountSyncWithKVSUsingIDSID(SOSAccount* account, CFStringRef deviceID, CFErrorRef *error); - - // // MARK: Cleanup functions // @@ -212,8 +197,10 @@ CFStringRef SOSAccountCopyIncompatibilityInfo(SOSAccount* account, CFErrorRef* bool SOSAccountIsBackupRingEmpty(SOSAccount* account, CFStringRef viewName); bool SOSAccountNewBKSBForView(SOSAccount* account, CFStringRef viewName, CFErrorRef *error); + bool SOSAccountSetBackupPublicKey(SOSAccountTransaction* aTxn, CFDataRef backupKey, CFErrorRef *error); bool SOSAccountRemoveBackupPublickey(SOSAccountTransaction* aTxn, CFErrorRef *error); +bool SOSAccountBackupUpdateBackupPublicKey(SOSAccount *account, CFDataRef backupKey); bool SOSAccountSetBSKBagForAllSlices(SOSAccount* account, CFDataRef backupSlice, bool setupV0Only, CFErrorRef *error); CF_RETURNS_RETAINED SOSBackupSliceKeyBagRef SOSAccountBackupSliceKeyBagForView(SOSAccount* account, CFStringRef viewName, CFErrorRef* error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m index c289643a..2e1a1cf6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m @@ -17,7 +17,6 @@ #import "Security/SecureObjectSync/SOSTransportCircleKVS.h" #include #include -#include #include #include #include @@ -26,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -67,6 +65,7 @@ #include #include +const CFStringRef kSOSAccountName = CFSTR("AccountName"); const CFStringRef kSOSEscrowRecord = CFSTR("EscrowRecord"); const CFStringRef kSOSUnsyncedViewsKey = CFSTR("unsynced"); const CFStringRef kSOSInitialSyncTimeoutV0 = CFSTR("initialsynctimeout"); @@ -82,6 +81,8 @@ const CFStringRef kSOSAccountPeerLastSentTimestamp = CFSTR("kSOSAccountPeerLastS const CFStringRef kSOSAccountRenegotiationRetryCount = CFSTR("NegotiationRetryCount"); const CFStringRef kOTRConfigVersion = CFSTR("OTRConfigVersion"); NSString* const SecSOSAggdReattemptOTRNegotiation = @"com.apple.security.sos.otrretry"; +NSString* const SOSAccountUserDefaultsSuite = @"com.apple.security.sosaccount"; +NSString* const SOSAccountLastKVSCleanup = @"lastKVSCleanup"; const uint64_t max_packet_size_over_idms = 500; @@ -114,11 +115,7 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); self.isListeningForSync = false; self.lock_notification_token = -1; - self.key_transport = nil; self.circle_transport = NULL; - self.kvs_message_transport = nil; - self.ids_message_transport = nil; - self.ck_storage = nil; self.circle_rings_retirements_need_attention = false; self.engine_peer_state_needs_repair = false; @@ -137,6 +134,12 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); self.previousAccountKey = NULL; self.saveBlock = nil; + + self.notifyCircleChangeOnExit = false; + self.notifyViewChangeOnExit = false; + self.notifyBackupOnExit = false; + + self.settings = [[NSUserDefaults alloc] initWithSuiteName:SOSAccountUserDefaultsSuite]; } return self; } @@ -243,7 +246,6 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); self.circle_transport = NULL; self.ck_storage = nil; self.kvs_message_transport = nil; - self.ids_message_transport = nil; self.circle_rings_retirements_need_attention = false; self.engine_peer_state_needs_repair = false; @@ -308,13 +310,6 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); reply((__bridge NSDictionary *)returnedValues); }); } -- (void)idsPerformanceCounters:(void(^)(NSDictionary *))reply -{ - SOSCloudKeychainRetrieveCountersFromIDSProxy(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef returnedValues, CFErrorRef error) - { - reply((__bridge NSDictionary *)returnedValues); - }); -} - (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary *))reply { @@ -689,6 +684,8 @@ void SOSAccountPendDisableViewSet(SOSAccount* account, CFSetRef disabledViews) [account.trust valueSubtractFrom:kSOSPendingEnableViewsToBeSetKey valuesToSubtract:disabledViews]; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-value" SOSViewResultCode SOSAccountVirtualV0Behavior(SOSAccount* account, SOSViewActionCode actionCode) { SOSViewResultCode retval = kSOSCCGeneralViewError; // The V0 view switches on and off all on it's own, we allow people the delusion @@ -703,6 +700,7 @@ SOSViewResultCode SOSAccountVirtualV0Behavior(SOSAccount* account, SOSViewActio errOut: return retval; } +#pragma clang diagnostic pop SOSAccount* SOSAccountCreate(CFAllocatorRef allocator, CFDictionaryRef gestalt, @@ -837,13 +835,11 @@ void SOSAccountSetToNew(SOSAccount* a) // update_interest_block; // update_block; SOSUnregisterTransportKeyParameter(a.key_transport); - SOSUnregisterTransportMessage(a.ids_message_transport); SOSUnregisterTransportMessage(a.kvs_message_transport); SOSUnregisterTransportCircle(a.circle_transport); a.circle_transport = NULL; - a.kvs_message_transport = NULL; - a.ids_message_transport = NULL; + a.kvs_message_transport = nil; a.trust = nil; a.trust = [[SOSAccountTrustClassic alloc]initWithRetirees:[NSMutableSet set] fpi:NULL circle:NULL departureCode:kSOSDepartureReasonError peerExpansion:[NSMutableDictionary dictionary]]; @@ -886,7 +882,7 @@ void SOSAccountSetUserPublicTrustedForTesting(SOSAccount* account){ -(SOSCCStatus) getCircleStatus:(CFErrorRef*) error { - SOSCCStatus circleStatus = [self.trust getCircleStatus:error]; + SOSCCStatus circleStatus = [self.trust getCircleStatusOnly:error]; if (!SOSAccountHasPublicKey(self, error)) { if(circleStatus == kSOSCCInCircle) { if(error) { @@ -899,6 +895,17 @@ void SOSAccountSetUserPublicTrustedForTesting(SOSAccount* account){ return circleStatus; } +-(bool) isInCircle:(CFErrorRef *)error +{ + SOSCCStatus result = [self getCircleStatus:error]; + if (result != kSOSCCInCircle) { + SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("Not in circle")); + return false; + } + return true; +} + + bool SOSAccountScanForRetired(SOSAccount* account, SOSCircleRef circle, CFErrorRef *error) { SOSAccountTrustClassic *trust = account.trust; @@ -945,6 +952,7 @@ SOSCircleRef SOSAccountCloneCircleWithRetirement(SOSAccount* account, SOSCircle CFReleaseNull(new_circle); return NULL; } + account.notifyBackupOnExit = true; } else { // Do nothing. We can't resetToOffering without a userPrivKey. If we were to resetToEmpty // we won't push the result later in handleUpdateCircle. If we leave the circle as it is @@ -992,6 +1000,85 @@ void SOSAccountPurgeIdentity(SOSAccount* account) { } } +bool sosAccountLeaveCircleWithAnalytics(SOSAccount* account, SOSCircleRef circle, NSData* parentData, CFErrorRef* error) { + SOSAccountTrustClassic *trust = account.trust; + SOSFullPeerInfoRef identity = trust.fullPeerInfo; + NSMutableSet* retirees = trust.retirees; + + NSError* localError = nil; + SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentData error:&localError]; + + SOSFullPeerInfoRef fpi = identity; + if(!fpi) return false; + + CFErrorRef retiredError = NULL; + + bool retval = false; + + SFSignInAnalytics *promoteToRetiredEvent = [parent newSubTaskForEvent:@"promoteToRetiredEvent"]; + SOSPeerInfoRef retire_peer = SOSFullPeerInfoPromoteToRetiredAndCopy(fpi, &retiredError); + if(retiredError){ + [promoteToRetiredEvent logRecoverableError:(__bridge NSError*)retiredError]; + secerror("SOSFullPeerInfoPromoteToRetiredAndCopy error: %@", retiredError); + if(error){ + *error = retiredError; + }else{ + CFReleaseNull(retiredError); + } + } + [promoteToRetiredEvent stopWithAttributes:nil]; + + if (!retire_peer) { + secerror("Create ticket failed for peer %@: %@", fpi, localError); + } else { + // See if we need to repost the circle we could either be an applicant or a peer already in the circle + if(SOSCircleHasApplicant(circle, retire_peer, NULL)) { + // Remove our application if we have one. + SOSCircleWithdrawRequest(circle, retire_peer, NULL); + } else if (SOSCircleHasPeer(circle, retire_peer, NULL)) { + if (SOSCircleUpdatePeerInfo(circle, retire_peer)) { + CFErrorRef cleanupError = NULL; + SFSignInAnalytics *cleanupEvent = [parent newSubTaskForEvent:@"cleanupAfterPeerEvent"]; + if (![account.trust cleanupAfterPeer:account.kvs_message_transport circleTransport:account.circle_transport seconds:RETIREMENT_FINALIZATION_SECONDS circle:circle cleanupPeer:retire_peer err:&cleanupError]) { + secerror("Error cleanup up after peer (%@): %@", retire_peer, cleanupError); + } + [cleanupEvent stopWithAttributes:nil]; + CFReleaseSafe(cleanupError); + } + } + + // Store the retirement record locally. + CFSetAddValue((__bridge CFMutableSetRef)retirees, retire_peer); + + trust.retirees = retirees; + + // Write retirement to Transport + CFErrorRef postError = NULL; + SFSignInAnalytics *postRestirementEvent = [parent newSubTaskForEvent:@"postRestirementEvent"]; + if(![account.circle_transport postRetirement:SOSCircleGetName(circle) peer:retire_peer err:&postError]){ + [postRestirementEvent logRecoverableError:(__bridge NSError*)postError]; + secwarning("Couldn't post retirement (%@)", postError); + } + [postRestirementEvent stopWithAttributes:nil]; + + SFSignInAnalytics *flushChangesEvent = [parent newSubTaskForEvent:@"flushChangesEvent"]; + + if(![account.circle_transport flushChanges:&postError]){ + [flushChangesEvent logRecoverableError:(__bridge NSError*)postError]; + secwarning("Couldn't flush retirement data (%@)", postError); + } + [flushChangesEvent stopWithAttributes:nil]; + CFReleaseNull(postError); + } + SFSignInAnalytics *purgeIdentityEvent = [parent newSubTaskForEvent:@"purgeIdentityEvent"]; + SOSAccountPurgeIdentity(account); + [purgeIdentityEvent stopWithAttributes:nil]; + retval = true; + + CFReleaseNull(retire_peer); + return retval; +} + bool sosAccountLeaveCircle(SOSAccount* account, SOSCircleRef circle, CFErrorRef* error) { SOSAccountTrustClassic *trust = account.trust; SOSFullPeerInfoRef identity = trust.fullPeerInfo; @@ -1281,6 +1368,62 @@ CFDataRef SOSAccountCopyRecoveryPublicKey(SOSAccountTransaction* txn, CFErrorRef // MARK: Joining // +static bool SOSAccountJoinCircleWithAnalytics(SOSAccountTransaction* aTxn, SecKeyRef user_key, + bool use_cloud_peer, NSData* parentEvent, CFErrorRef* error) { + SOSAccount* account = aTxn.account; + SOSAccountTrustClassic *trust = account.trust; + __block bool result = false; + __block SOSFullPeerInfoRef cloud_full_peer = NULL; + SFSignInAnalytics *ensureFullPeerAvailableEvent = nil; + NSError* localError = nil; + SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + + require_action_quiet(trust.trustedCircle, fail, SOSCreateErrorWithFormat(kSOSErrorPeerNotFound, NULL, error, NULL, CFSTR("Don't have circle when joining???"))); + ensureFullPeerAvailableEvent = [parent newSubTaskForEvent:@"ensureFullPeerAvailableEvent"]; + require_quiet([account.trust ensureFullPeerAvailable:(__bridge CFDictionaryRef)account.gestalt deviceID:(__bridge CFStringRef)account.deviceID backupKey:(__bridge CFDataRef)account.backup_key err:error], fail); + [ensureFullPeerAvailableEvent stopWithAttributes:nil]; + + SOSFullPeerInfoRef myCirclePeer = trust.fullPeerInfo; + if (SOSCircleCountPeers(trust.trustedCircle) == 0 || SOSAccountGhostResultsInReset(account)) { + secnotice("resetToOffering", "Resetting circle to offering since there are no peers"); + // this also clears initial sync data + result = [account.trust resetCircleToOffering:aTxn userKey:user_key err:error]; + } else { + SOSAccountSetValue(account, kSOSUnsyncedViewsKey, kCFBooleanTrue, NULL); + if (use_cloud_peer) { + cloud_full_peer = SOSCircleCopyiCloudFullPeerInfoRef(trust.trustedCircle, NULL); + } + SFSignInAnalytics *acceptApplicantEvent = [parent newSubTaskForEvent:@"acceptApplicantEvent"]; + [account.trust modifyCircle:account.circle_transport err:error action:^bool(SOSCircleRef circle) { + result = SOSAccountAddEscrowToPeerInfo(account, myCirclePeer, error); + result &= SOSCircleRequestAdmission(circle, user_key, myCirclePeer, error); + trust.departureCode = kSOSNeverLeftCircle; + if(result && cloud_full_peer) { + CFErrorRef localError = NULL; + CFStringRef cloudid = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(cloud_full_peer)); + require_quiet(cloudid, finish); + require_quiet(SOSCircleHasActivePeerWithID(circle, cloudid, &localError), finish); + require_quiet(SOSCircleAcceptRequest(circle, user_key, cloud_full_peer, SOSFullPeerInfoGetPeerInfo(myCirclePeer), &localError), finish); + finish: + if (localError){ + [acceptApplicantEvent logRecoverableError:(__bridge NSError *)(localError)]; + secerror("Failed to join with cloud identity: %@", localError); + CFReleaseNull(localError); + } + } + return result; + }]; + [acceptApplicantEvent stopWithAttributes:nil]; + if (use_cloud_peer) { + SFSignInAnalytics *updateOutOfDateSyncViewsEvent = [acceptApplicantEvent newSubTaskForEvent:@"updateOutOfDateSyncViewsEvent"]; + SOSAccountUpdateOutOfSyncViews(aTxn, SOSViewsGetAllCurrent()); + [updateOutOfDateSyncViewsEvent stopWithAttributes:nil]; + } + } +fail: + CFReleaseNull(cloud_full_peer); + return result; +} static bool SOSAccountJoinCircle(SOSAccountTransaction* aTxn, SecKeyRef user_key, bool use_cloud_peer, CFErrorRef* error) { @@ -1327,7 +1470,7 @@ fail: return result; } -static bool SOSAccountJoinCircles_internal(SOSAccountTransaction* aTxn, bool use_cloud_identity, CFErrorRef* error) { +static bool SOSAccountJoinCirclesWithAnalytics_internal(SOSAccountTransaction* aTxn, bool use_cloud_identity, NSData* parentEvent, CFErrorRef* error) { SOSAccount* account = aTxn.account; SOSAccountTrustClassic *trust = account.trust; bool success = false; @@ -1336,7 +1479,7 @@ static bool SOSAccountJoinCircles_internal(SOSAccountTransaction* aTxn, bool use require_quiet(user_key, done); // Fail if we don't get one. require_action_quiet(trust.trustedCircle, done, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to join"))); - + if (trust.fullPeerInfo != NULL) { SOSPeerInfoRef myPeer = trust.peerInfo; success = SOSCircleHasPeer(trust.trustedCircle, myPeer, NULL); @@ -1345,165 +1488,143 @@ static bool SOSAccountJoinCircles_internal(SOSAccountTransaction* aTxn, bool use SOSCircleRemoveRejectedPeer(trust.trustedCircle, myPeer, NULL); // If we were rejected we should remove it now. if (!SOSCircleHasApplicant(trust.trustedCircle, myPeer, NULL)) { - secerror("Resetting my peer (ID: %@) for circle '%@' during application", SOSPeerInfoGetPeerID(myPeer), SOSCircleGetName(trust.trustedCircle)); - + secerror("Resetting my peer (ID: %@) for circle '%@' during application", SOSPeerInfoGetPeerID(myPeer), SOSCircleGetName(trust.trustedCircle)); + trust.fullPeerInfo = NULL; } } - - success = SOSAccountJoinCircle(aTxn, user_key, use_cloud_identity, error); + + success = SOSAccountJoinCircleWithAnalytics(aTxn, user_key, use_cloud_identity, parentEvent, error); require_quiet(success, done); - + trust.departureCode = kSOSNeverLeftCircle; done: return success; } -bool SOSAccountJoinCircles(SOSAccountTransaction* aTxn, CFErrorRef* error) { - secnotice("circleOps", "Normal path circle join (SOSAccountJoinCircles)"); - return SOSAccountJoinCircles_internal(aTxn, false, error); -} - -CFStringRef SOSAccountCopyDeviceID(SOSAccount* account, CFErrorRef *error){ - CFStringRef result = NULL; +static bool SOSAccountJoinCircles_internal(SOSAccountTransaction* aTxn, bool use_cloud_identity, CFErrorRef* error) { + SOSAccount* account = aTxn.account; SOSAccountTrustClassic *trust = account.trust; + bool success = false; - require_action_quiet(trust.fullPeerInfo, fail, SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("No peer for me"))); - - result = SOSPeerInfoCopyDeviceID(trust.peerInfo); + SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error); + require_quiet(user_key, done); // Fail if we don't get one. -fail: - return result; -} + require_action_quiet(trust.trustedCircle, done, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to join"))); + + if (trust.fullPeerInfo != NULL) { + SOSPeerInfoRef myPeer = trust.peerInfo; + success = SOSCircleHasPeer(trust.trustedCircle, myPeer, NULL); + require_quiet(!success, done); -bool SOSAccountSetMyDSID(SOSAccountTransaction* txn, CFStringRef IDS, CFErrorRef* error){ - bool result = true; - SOSAccount* account = txn.account; - SOSAccountTrustClassic *trust = account.trust; + SOSCircleRemoveRejectedPeer(trust.trustedCircle, myPeer, NULL); // If we were rejected we should remove it now. - secdebug("IDS Transport", "We are setting our device ID: %@", IDS); - if(IDS != NULL && (CFStringGetLength(IDS) > 0)){ - if(!trust.fullPeerInfo){ - account.deviceID = [[NSString alloc] initWithString:(__bridge NSString * _Nonnull)(IDS)]; - SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("No peer for me")); - return result; - } - result = [trust modifyCircle:account.circle_transport err:error action:^bool(SOSCircleRef circle) { + if (!SOSCircleHasApplicant(trust.trustedCircle, myPeer, NULL)) { + secerror("Resetting my peer (ID: %@) for circle '%@' during application", SOSPeerInfoGetPeerID(myPeer), SOSCircleGetName(trust.trustedCircle)); - SOSFullPeerInfoUpdateDeviceID(trust.fullPeerInfo, IDS, error); - SOSFullPeerInfoUpdateTransportType(trust.fullPeerInfo, SOSTransportMessageTypeKVS, error); - SOSFullPeerInfoUpdateTransportPreference(trust.fullPeerInfo, kCFBooleanFalse, error); - SOSFullPeerInfoUpdateTransportFragmentationPreference(trust.fullPeerInfo, kCFBooleanTrue, error); - SOSFullPeerInfoUpdateTransportAckModelPreference(trust.fullPeerInfo, kCFBooleanTrue, error); - return SOSCircleHasPeer(circle, trust.peerInfo, NULL); - }]; + trust.fullPeerInfo = NULL; + } } - else - result = false; + + success = SOSAccountJoinCircle(aTxn, user_key, use_cloud_identity, error); - // Initiate sync with all IDS peers, since we just learned we can talk that way. - SOSAccountForEachCirclePeerExceptMe(account, ^(SOSPeerInfoRef peer) { - if (SOSPeerInfoShouldUseIDSTransport(account.peerInfo, peer)) { - [txn requestSyncWith:(__bridge NSString*) SOSPeerInfoGetPeerID(peer)]; - } - }); + require_quiet(success, done); + + trust.departureCode = kSOSNeverLeftCircle; - account.deviceID = [[NSString alloc] initWithString:(__bridge NSString * _Nonnull)(IDS)]; - return result; +done: + return success; } -bool SOSAccountSendIDSTestMessage(SOSAccount* account, CFStringRef message, CFErrorRef *error){ - bool result = true; - //construct message dictionary, circle -> peerID -> message - - CFMutableDictionaryRef peerToMessage = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); +bool SOSAccountJoinCirclesWithAnalytics(SOSAccountTransaction* aTxn, NSData* parentEvent, CFErrorRef* error) { + secnotice("circleOps", "Normal path circle join (SOSAccountJoinCirclesWithAnalytics)"); + return SOSAccountJoinCirclesWithAnalytics_internal(aTxn, false, parentEvent, error); +} - CFStringRef operationString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), kIDSSendOneMessage); - CFDictionaryRef rawMessage = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, - kIDSOperationType, operationString, - kIDSMessageToSendKey, CFSTR("send IDS test message"), - NULL); +bool SOSAccountJoinCircles(SOSAccountTransaction* aTxn, CFErrorRef* error) { + secnotice("circleOps", "Normal path circle join (SOSAccountJoinCircles)"); + return SOSAccountJoinCircles_internal(aTxn, false, error); +} - SOSAccountForEachCirclePeerExceptMe(account, ^(SOSPeerInfoRef peer) { - CFDictionaryAddValue(peerToMessage, SOSPeerInfoGetPeerID(peer), rawMessage); - }); +bool SOSAccountJoinCirclesAfterRestore(SOSAccountTransaction* aTxn, CFErrorRef* error) { + secnotice("circleOps", "Joining after restore (SOSAccountJoinCirclesAfterRestore)"); + return SOSAccountJoinCircles_internal(aTxn, true, error); +} - result = [account.ids_message_transport SOSTransportMessageSendMessages:account.ids_message_transport pm:peerToMessage err:error]; - - CFReleaseNull(peerToMessage); - CFReleaseNull(operationString); - CFReleaseNull(rawMessage); - return result; +bool SOSAccountJoinCirclesAfterRestoreWithAnalytics(SOSAccountTransaction* aTxn, NSData* parentEvent, CFErrorRef* error) { + secnotice("circleOps", "Joining after restore (SOSAccountJoinCirclesAfterRestore)"); + return SOSAccountJoinCirclesWithAnalytics_internal(aTxn, true, parentEvent, error); } -bool SOSAccountStartPingTest(SOSAccount* account, CFStringRef message, CFErrorRef *error){ +bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFErrorRef* error) +{ bool result = false; - //construct message dictionary, circle -> peerID -> message - SOSAccountTrustClassic *trust = account.trust; - if(account.ids_message_transport == NULL) - account.ids_message_transport = [[SOSMessageIDS alloc] initWithAccount:account andName:(__bridge NSString *)(SOSCircleGetName(trust.trustedCircle))]; + CFMutableSetRef peersToRemove = NULL; + SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error); + if(!user_key){ + secnotice("circleOps", "Can't remove without userKey"); + return result; + } + SOSFullPeerInfoRef me_full = account.fullPeerInfo; + SOSPeerInfoRef me = account.peerInfo; + if(!(me_full && me)) + { + secnotice("circleOps", "Can't remove without being active peer"); + SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("Can't remove without being active peer")); + return result; + } - require_quiet(account.ids_message_transport, fail); - CFMutableDictionaryRef peerToMessage = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); + result = true; // beyond this point failures would be rolled up in AccountModifyCircle. - CFStringRef operationString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), kIDSStartPingTestMessage); - CFDictionaryRef rawMessage = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, - kIDSOperationType, operationString, - kIDSMessageToSendKey, CFSTR("send IDS test message"), - NULL); + peersToRemove = CFSetCreateMutableForSOSPeerInfosByIDWithArray(kCFAllocatorDefault, peers); + if(!peersToRemove) + { + CFReleaseNull(peersToRemove); + secnotice("circleOps", "No peerSet to remove"); + return result; + } - - SOSAccountForEachCirclePeerExceptMe(account, ^(SOSPeerInfoRef peer) { - CFDictionaryAddValue(peerToMessage, SOSPeerInfoGetPeerID(peer), rawMessage); - }); - - result = [account.ids_message_transport SOSTransportMessageSendMessages:account.ids_message_transport pm:peerToMessage err:error]; + // If we're one of the peers expected to leave - note that and then remove ourselves from the set (different handling). + bool leaveCircle = CFSetContainsValue(peersToRemove, me); + CFSetRemoveValue(peersToRemove, me); - CFReleaseNull(peerToMessage); - CFReleaseNull(rawMessage); - CFReleaseNull(operationString); -fail: - return result; -} + result &= [account.trust modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle) { + bool success = false; -bool SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(SOSAccount* account, CFErrorRef *error){ - bool result = true; - - __block bool success = true; - __block CFErrorRef localError = NULL; - dispatch_semaphore_t wait_for = dispatch_semaphore_create(0); + if(CFSetGetCount(peersToRemove) != 0) { + require_quiet(SOSCircleRemovePeers(circle, user_key, me_full, peersToRemove, error), done); + success = SOSAccountGenerationSignatureUpdate(account, error); + } else success = true; - SOSCloudKeychainGetIDSDeviceID(^(CFDictionaryRef returnedValues, CFErrorRef sync_error){ - success = (sync_error == NULL); - if (!success) { - CFRetainAssign(localError, sync_error); + if (success && leaveCircle) { + secnotice("circleOps", "Leaving circle by client request (SOSAccountRemovePeersFromCircle)"); + success = sosAccountLeaveCircle(account, circle, error); } - - dispatch_semaphore_signal(wait_for); - }); - - dispatch_semaphore_wait(wait_for, DISPATCH_TIME_FOREVER); - if(!success && localError != NULL && error != NULL){ - secerror("Could not ask KeychainSyncingOverIDSProxy for Device ID: %@", localError); - *error = localError; - result = false; - } - else{ - secdebug("IDS Transport", "Attempting to retrieve the IDS Device ID"); + done: + return success; + + }]; + + if(result) { + CFStringSetPerformWithDescription(peersToRemove, ^(CFStringRef description) { + secnotice("circleOps", "Removed Peers from circle %@", description); + }); } + + CFReleaseNull(peersToRemove); return result; } -bool SOSAccountJoinCirclesAfterRestore(SOSAccountTransaction* aTxn, CFErrorRef* error) { - secnotice("circleOps", "Joining after restore (SOSAccountJoinCirclesAfterRestore)"); - return SOSAccountJoinCircles_internal(aTxn, true, error); -} -bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFErrorRef* error) +bool SOSAccountRemovePeersFromCircleWithAnalytics(SOSAccount* account, CFArrayRef peers, NSData* parentEvent, CFErrorRef* error) { + + NSError* localError = nil; + SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + bool result = false; CFMutableSetRef peersToRemove = NULL; SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error); @@ -1519,7 +1640,7 @@ bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFE SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("Can't remove without being active peer")); return result; } - + result = true; // beyond this point failures would be rolled up in AccountModifyCircle. peersToRemove = CFSetCreateMutableForSOSPeerInfosByIDWithArray(kCFAllocatorDefault, peers); @@ -1539,19 +1660,25 @@ bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFE if(CFSetGetCount(peersToRemove) != 0) { require_quiet(SOSCircleRemovePeers(circle, user_key, me_full, peersToRemove, error), done); + SFSignInAnalytics *generationSignatureUpdateEvent = [parent newSubTaskForEvent:@"generationSignatureUpdateEvent"]; success = SOSAccountGenerationSignatureUpdate(account, error); + if(error && *error){ + NSError* signatureUpdateError = (__bridge NSError*)*error; + [generationSignatureUpdateEvent logUnrecoverableError:signatureUpdateError]; + } + [generationSignatureUpdateEvent stopWithAttributes:nil]; } else success = true; if (success && leaveCircle) { secnotice("circleOps", "Leaving circle by client request (SOSAccountRemovePeersFromCircle)"); - success = sosAccountLeaveCircle(account, circle, error); + success = sosAccountLeaveCircleWithAnalytics(account, circle, parentEvent, error); } done: return success; }]; - + if(result) { CFStringSetPerformWithDescription(peersToRemove, ^(CFStringRef description) { secnotice("circleOps", "Removed Peers from circle %@", description); @@ -1562,7 +1689,6 @@ bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFE return result; } - bool SOSAccountBail(SOSAccount* account, uint64_t limit_in_seconds, CFErrorRef* error) { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create(); @@ -1620,19 +1746,18 @@ bool SOSAccountAcceptApplicants(SOSAccount* account, CFArrayRef applicants, CFE if (!user_key) return false; - __block bool success = true; - __block int64_t num_peers = 0; + __block int64_t acceptedPeers = 0; for_each_applicant_in_each_circle(account, applicants, ^(SOSCircleRef circle, SOSFullPeerInfoRef myCirclePeer, SOSPeerInfoRef peer) { bool accepted = SOSCircleAcceptRequest(circle, user_key, myCirclePeer, peer, error); - if (!accepted) - success = false; - else - num_peers = MAX(num_peers, SOSCircleCountPeers(circle)); + if (accepted) + acceptedPeers++; return accepted; }); - return success; + if (acceptedPeers == CFArrayGetCount(applicants)) + return true; + return false; } bool SOSAccountRejectApplicants(SOSAccount* account, CFArrayRef applicants, CFErrorRef* error) { @@ -1696,12 +1821,19 @@ bool SOSAccountEnsurePeerRegistration(SOSAccount* account, CFErrorRef *error) { secnotice("updates", "Ensuring peer registration."); - if(!trust.trustedCircle || !trust.fullPeerInfo || !account.accountKeyIsTrusted) + if(!trust) { + secnotice("updates", "Failed to get trust object in Ensuring peer registration."); return result; - + } + + if([account getCircleStatus: NULL] != kSOSCCInCircle) { + return result; + } + // If we are not in the circle, there is no point in setting up peers - if(!SOSAccountIsMyPeerActive(account, NULL)) + if(!SOSAccountIsMyPeerActive(account, NULL)) { return result; + } // This code only uses the SOSFullPeerInfoRef for two things: // - Finding out if this device is in the trusted circle @@ -1713,18 +1845,13 @@ bool SOSAccountEnsurePeerRegistration(SOSAccount* account, CFErrorRef *error) { SOSCircleForEachValidSyncingPeer(trust.trustedCircle, account.accountKey, ^(SOSPeerInfoRef peer) { if (!SOSPeerInfoPeerIDEqual(peer, my_id)) { CFErrorRef localError = NULL; - - SOSMessage *messageTransport = SOSPeerInfoHasDeviceID(peer) ? account.ids_message_transport : account.kvs_message_transport; - SOSEngineInitializePeerCoder((SOSEngineRef)[messageTransport SOSTransportMessageGetEngine], trust.fullPeerInfo, peer, &localError); + SOSEngineInitializePeerCoder((SOSEngineRef)[account.kvs_message_transport SOSTransportMessageGetEngine], trust.fullPeerInfo, peer, &localError); if (localError) secnotice("updates", "can't initialize transport for peer %@ with %@ (%@)", peer, trust.fullPeerInfo, localError); CFReleaseSafe(localError); } }); - - //Initialize our device ID - [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account]; return result; } @@ -1772,66 +1899,10 @@ bool SOSAccountAddEscrowToPeerInfo(SOSAccount* account, SOSFullPeerInfoRef myPe return success; } -bool SOSAccountCheckPeerAvailability(SOSAccount* account, CFErrorRef *error) -{ - CFStringRef operationString = NULL; - CFDictionaryRef rawMessage = NULL; - CFMutableSetRef peers = NULL; - CFMutableDictionaryRef peerList = NULL; - char* message = NULL; - bool result = false; - SOSAccountTrustClassic* trust = account.trust; - if(account.ids_message_transport == NULL) - account.ids_message_transport = [[SOSMessageIDS alloc] initWithAccount:account andName:(__bridge NSString *)SOSCircleGetName(trust.trustedCircle)]; - - if(!account.ids_message_transport) - return result; - - //adding message type kIDSPeerAvailability so KeychainSyncingOverIDSProxy does not send this message as a keychain item - - operationString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), kIDSPeerAvailability); - rawMessage = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, - kIDSOperationType, operationString, - kIDSMessageToSendKey, CFSTR("checking peers"), - NULL); - - peerList = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - SOSCircleRef circle = trust.trustedCircle; - - //check each peer to make sure they have the right view set enabled - CFSetRef mySubSet = SOSViewsGetV0SubviewSet(); - SOSCircleForEachValidPeer(circle, account.accountKey, ^(SOSPeerInfoRef peer) { - if(!CFEqualSafe(peer, account.peerInfo)){ - CFMutableSetRef peerViews = SOSPeerInfoCopyEnabledViews(peer); - CFSetRef intersectSets = CFSetCreateIntersection(kCFAllocatorDefault, mySubSet, peerViews); - if(CFEqualSafe(intersectSets, mySubSet)){ - CFStringRef deviceID = SOSPeerInfoCopyDeviceID(peer); - if(deviceID != NULL) - CFDictionaryAddValue(peerList, SOSPeerInfoGetPeerID(peer), rawMessage); - CFReleaseNull(deviceID); - } - CFReleaseNull(peerViews); - CFReleaseNull(intersectSets); - } - }); - - require_quiet(CFDictionaryGetCount(peerList) > 0 , fail); - - result = [account.ids_message_transport SOSTransportMessageSendMessages:account.ids_message_transport pm:peerList err:error]; - -fail: - CFReleaseNull(rawMessage); - CFReleaseNull(operationString); - CFReleaseNull(peerList); - CFReleaseNull(peers); - free(message); - return result; -} - - void SOSAccountRecordRetiredPeersInCircle(SOSAccount* account) { - if (![account.trust isInCircle:NULL]) + if (![account isInCircle:NULL]) { return; + } SOSAccountTrustClassic *trust = account.trust; [trust modifyCircle:account.circle_transport err:NULL action:^bool (SOSCircleRef circle) { __block bool updated = false; @@ -1905,9 +1976,13 @@ static void SOSAccountRemoveKVSKeys(SOSAccount* account, NSArray* keysToRemove, static void SOSAccountWriteLastCleanupTimestampToKVS(SOSAccount* account) { + NSDate *now = [NSDate date]; + [account.settings setObject:now forKey:SOSAccountLastKVSCleanup]; + NSMutableDictionary *writeTimestamp = [NSMutableDictionary dictionary]; CFMutableStringRef timeDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("[")); + CFAbsoluteTime currentTimeAndDate = CFAbsoluteTimeGetCurrent(); withStringOfAbsoluteTime(currentTimeAndDate, ^(CFStringRef decription) { @@ -1933,9 +2008,21 @@ static void SOSAccountWriteLastCleanupTimestampToKVS(SOSAccount* account) dispatch_semaphore_wait(waitSemaphore, finishTime); } +// set the cleanup frequency to 3 days. +#define KVS_CLEANUP_FREQUENCY_LIMIT 60*60*24*3 + //Get all the key/values in KVS and remove old entries bool SOSAccountCleanupAllKVSKeys(SOSAccount* account, CFErrorRef* error) { + // This should only happen on some number of days + NSDate *lastKVSCleanup = [account.settings objectForKey:SOSAccountLastKVSCleanup]; + NSDate *now = [NSDate date]; + NSTimeInterval timeSinceCleanup = [now timeIntervalSinceDate:lastKVSCleanup]; + + if(timeSinceCleanup < KVS_CLEANUP_FREQUENCY_LIMIT) { + return true; + } + dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); NSDictionary *keysAndValues = (__bridge_transfer NSDictionary*)SOSAccountGetObjectsFromCloud(processQueue, error); @@ -2181,13 +2268,13 @@ static unsigned rank_type(NSString *view) { if ([view isEqualToString:@"Manatee"]) - return 4; + return 5; else if ([view isEqualToString:@"Engram"]) - return 3; + return 4; else if ([view isEqualToString:@"AutoUnlock"]) - return 2; + return 3; if ([view isEqualToString:@"Health"]) - return 1; + return 2; return 0; } @@ -2395,6 +2482,25 @@ CFDataRef SOSAccountCopyInitialSyncData(SOSAccount* account, CFErrorRef *error) return CFBridgingRetain(SOSPiggyCreateInitialSyncData(encodedIdenities, tlks)); } +static void pbNotice(CFStringRef operation, SOSAccount* account, SOSGenCountRef gencount, SecKeyRef pubKey, CFDataRef signature, PiggyBackProtocolVersion version) { + CFStringRef pkeyID = SOSCopyIDOfKey(pubKey, NULL); + if(pkeyID == NULL) pkeyID = CFStringCreateCopy(kCFAllocatorDefault, CFSTR("Unknown")); + CFStringRef sigID = SOSCopyIDOfDataBuffer(signature, NULL); + if(sigID == NULL) sigID = CFStringCreateCopy(kCFAllocatorDefault, CFSTR("No Signature")); + CFStringRef accountName = SOSAccountGetValue(account, kSOSAccountName, NULL); + if(accountName == NULL) { + accountName = CFSTR("Unavailable"); + } + CFStringRef circleHash = SOSCircleCopyHashString(account.trust.trustedCircle); + + secnotice("circleOps", + "%@: Joining blob for account: %@ for piggyback (V%d) gencount: %@ pubkey: %@ signatureID: %@ starting circle hash: %@", + operation, accountName, version, gencount, pkeyID, sigID, circleHash); + CFReleaseNull(pkeyID); + CFReleaseNull(sigID); + CFReleaseNull(circleHash); +} + CFDataRef SOSAccountCopyCircleJoiningBlob(SOSAccount* account, SOSPeerInfoRef applicant, CFErrorRef *error) { SOSGenCountRef gencount = NULL; CFDataRef signature = NULL; @@ -2403,13 +2509,20 @@ CFDataRef SOSAccountCopyCircleJoiningBlob(SOSAccount* account, SOSPeerInfoRef a CFDataRef pbblob = NULL; SOSCircleRef prunedCircle = NULL; - secnotice("circleOps", "Making circle joining blob as sponsor (SOSAccountCopyCircleJoiningBlob)"); + secnotice("circleOps", "Making circle joining piggyback blob as sponsor (SOSAccountCopyCircleJoiningBlob)"); + + SOSCCStatus circleStat = [account getCircleStatus:error]; + if(circleStat != kSOSCCInCircle) { + secnotice("circleOps", "Invalid circle status: %@ to accept piggyback as sponsor (SOSAccountCopyCircleJoiningBlob)", SOSCCGetStatusDescription(circleStat)); + return NULL; + } SecKeyRef userKey = SOSAccountGetTrustedPublicCredential(account, error); require_quiet(userKey, errOut); require_action_quiet(applicant, errOut, SOSCreateError(kSOSErrorProcessingFailure, CFSTR("No applicant provided"), (error != NULL) ? *error : NULL, error)); - require_quiet(SOSPeerInfoApplicationVerify(applicant, userKey, error), errOut); + require_action_quiet(SOSPeerInfoApplicationVerify(applicant, userKey, error), errOut, + secnotice("circleOps", "Peer application wasn't signed with the correct userKey")); { SOSFullPeerInfoRef fpi = account.fullPeerInfo; @@ -2428,7 +2541,7 @@ CFDataRef SOSAccountCopyCircleJoiningBlob(SOSAccount* account, SOSPeerInfoRef a signature = SOSCircleCopyNextGenSignatureWithPeerAdded(prunedCircle, applicant, ourKey, error); require_quiet(signature, errOut); - + pbNotice(CFSTR("Accepting"), account, gencount, ourKey, signature, kPiggyV1); pbblob = SOSPiggyBackBlobCopyEncodedData(gencount, ourKey, signature, error); errOut: @@ -2438,7 +2551,7 @@ errOut: CFReleaseNull(ourKey); if(!pbblob && error != NULL) { - secnotice("circleOps", "Failed to make circle joining blob as sponsor %@", *error); + secnotice("circleOps", "Failed to make circle joining piggyback blob as sponsor %@", *error); } return pbblob; @@ -2453,35 +2566,41 @@ bool SOSAccountJoinWithCircleJoiningBlob(SOSAccount* account, CFDataRef joining SecKeyRef pubKey = NULL; bool setInitialSyncTimeoutToV0 = false; - secnotice("circleOps", "Joining circles through piggy-back (SOSAccountCopyCircleJoiningBlob)"); + secnotice("circleOps", "Joining circles through piggyback (SOSAccountCopyCircleJoiningBlob)"); - if (!isData(joiningBlob)) + if (!isData(joiningBlob)) { + secnotice("circleOps", "Bad data blob: piggyback (SOSAccountCopyCircleJoiningBlob)"); return false; + } userKey = SOSAccountGetPrivateCredential(account, error); - if(!userKey) + if(!userKey) { + secnotice("circleOps", "Failed - no private credential %@: piggyback (SOSAccountCopyCircleJoiningBlob)", *error); return retval; + } - if (!SOSPiggyBackBlobCreateFromData(&gencount, &pubKey, &signature, joiningBlob, version, &setInitialSyncTimeoutToV0, error)) + if (!SOSPiggyBackBlobCreateFromData(&gencount, &pubKey, &signature, joiningBlob, version, &setInitialSyncTimeoutToV0, error)) { + secnotice("circleOps", "Failed - decoding blob %@: piggyback (SOSAccountCopyCircleJoiningBlob)", *error); return retval; + } if(setInitialSyncTimeoutToV0){ - secnotice("piggy", "setting flag in account for piggybacking v0"); + secnotice("circleOps", "setting flag in account for piggyback v0"); SOSAccountSetValue(account, kSOSInitialSyncTimeoutV0, kCFBooleanTrue, NULL); - } - else{ - secnotice("piggy", "setting flag in account for piggybacking v0"); + } else { + secnotice("circleOps", "clearing flag in account for piggyback v0"); SOSAccountClearValue(account, kSOSInitialSyncTimeoutV0, NULL); } SOSAccountSetValue(account, kSOSUnsyncedViewsKey, kCFBooleanTrue, NULL); + pbNotice(CFSTR("Joining"), account, gencount, pubKey, signature, version); + retval = [trust modifyCircle:account.circle_transport err:error action:^bool(SOSCircleRef copyOfCurrent) { return SOSCircleAcceptPeerFromHSA2(copyOfCurrent, userKey, gencount, pubKey, signature, trust.fullPeerInfo, error);; - }]; CFReleaseNull(gencount); @@ -2519,7 +2638,7 @@ void SOSAccountLogState(SOSAccount* account) { } void SOSAccountLogViewState(SOSAccount* account) { - bool isInCircle = [account.trust isInCircle:NULL]; + bool isInCircle = [account.trust isInCircleOnly:NULL]; require_quiet(isInCircle, imOut); SOSPeerInfoRef mpi = account.peerInfo; bool isInitialComplete = SOSAccountHasCompletedInitialSync(account); @@ -2605,7 +2724,7 @@ void SOSAccountTimerFiredSendNextMessage(SOSAccountTransaction* txn, NSString* p if(message){ secnotice("ratelimit","SOSPeerRateLimiter timer went off! sending:%@ \n to peer:%@", message, peer_id); - bool sendResult = [account.ids_message_transport SOSTransportMessageSendMessage:account.ids_message_transport id:(__bridge CFStringRef)peer_id messageToSend:(__bridge CFDataRef)message err:&error]; + bool sendResult = [account.kvs_message_transport SOSTransportMessageSendMessage:account.kvs_message_transport id:(__bridge CFStringRef)peer_id messageToSend:(__bridge CFDataRef)message err:&error]; if(!sendResult || error){ secnotice("ratelimit", "could not send message: %@", error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m index 4409403f..4e861bc1 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -212,23 +213,6 @@ bool SOSAccountIsBackupRingEmpty(SOSAccount* account, CFStringRef viewName) { return peercnt == 0; } -bool SOSAccountUpdatePeerInfo(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error, bool (^update)(SOSFullPeerInfoRef fpi, CFErrorRef *error)) { - - if (!account.hasPeerInfo) - return true; - - bool result = update(account.fullPeerInfo, error); - - if (result && SOSAccountHasCircle(account, NULL)) { - return [account.trust modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle_to_change) { - secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for %@", updateDescription); - return SOSCircleUpdatePeerInfo(circle_to_change, account.peerInfo); - }]; - } - - return result; -} - bool SOSAccountIsMyPeerInBackupAndCurrentInView(SOSAccount* account, CFStringRef viewname){ bool result = false; CFErrorRef bsError = NULL; @@ -393,17 +377,18 @@ bool SOSAccountSetBackupPublicKey(SOSAccountTransaction* aTxn, CFDataRef cfBacku { SOSAccount* account = aTxn.account; NSData* backupKey = [[NSData alloc]initWithData:(__bridge NSData * _Nonnull)(cfBackupKey)]; - __block bool result = false; + if(![account isInCircle:error]) { + return result; + } + CFDataPerformWithHexString((__bridge CFDataRef)(backupKey), ^(CFStringRef backupKeyString) { CFDataPerformWithHexString((__bridge CFDataRef)((account.backup_key)), ^(CFStringRef oldBackupKey) { secnotice("backup", "SetBackupPublic: %@ from %@", backupKeyString, oldBackupKey); }); }); - require_quiet([account.trust isInCircle:error], exit); - if ([backupKey isEqual:account.backup_key]) return true; @@ -413,7 +398,6 @@ bool SOSAccountSetBackupPublicKey(SOSAccountTransaction* aTxn, CFDataRef cfBacku result = true; -exit: if (!result) { secnotice("backupkey", "SetBackupPublic Failed: %@", error ? (CFTypeRef) *error : (CFTypeRef) CFSTR("No error space")); } @@ -495,7 +479,9 @@ bool SOSAccountSetBSKBagForAllSlices(SOSAccount* account, CFDataRef aks_bag, bo __block bool result = false; SOSBackupSliceKeyBagRef backup_slice = NULL; - require_quiet([account.trust isInCircle:error], exit); + if(![account isInCircle:error]) { + return result; + } if (setupV0Only) { result = SOSSaveV0Keybag(aks_bag, error); @@ -588,12 +574,16 @@ exit: bool SOSAccountIsLastBackupPeer(SOSAccount* account, CFErrorRef *error) { __block bool retval = false; SOSPeerInfoRef pi = account.peerInfo; + + if(![account isInCircle:error]) { + return retval; + } + if(!SOSPeerInfoHasBackupKey(pi)) return retval; SOSCircleRef circle = [account.trust getCircle:error]; - if(![account.trust isInCircle:error]) - return retval; + if(SOSCircleCountValidSyncingPeers(circle, SOSAccountGetTrustedPublicCredential(account, error)) == 1){ retval = true; return retval; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCircles.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCircles.m index 8c162a35..5a2418c6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCircles.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCircles.m @@ -7,7 +7,6 @@ #import #import #import -#import #import #import #import diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCredentials.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCredentials.m index ab12e928..39387635 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCredentials.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCredentials.m @@ -392,7 +392,7 @@ fail: -bool SOSAccountAssertUserCredentials(SOSAccount* account, CFStringRef user_account __unused, CFDataRef user_password, CFErrorRef *error) +bool SOSAccountAssertUserCredentials(SOSAccount* account, CFStringRef user_account, CFDataRef user_password, CFErrorRef *error) { bool public_was_trusted = account.accountKeyIsTrusted; account.accountKeyIsTrusted = false; @@ -423,6 +423,7 @@ bool SOSAccountAssertUserCredentials(SOSAccount* account, CFStringRef user_accou CFReleaseNull(publishError); recordCred: SOSAccountStashAccountKey(account); + SOSAccountSetValue(account, kSOSAccountName, user_account, NULL); errOut: CFReleaseNull(parameters); CFReleaseNull(user_private); @@ -432,10 +433,11 @@ errOut: } -bool SOSAccountTryUserCredentials(SOSAccount* account, CFStringRef user_account __unused, CFDataRef user_password, CFErrorRef *error) { +bool SOSAccountTryUserCredentials(SOSAccount* account, CFStringRef user_account, CFDataRef user_password, CFErrorRef *error) { bool success = sosAccountValidatePasswordOrFail(account, user_password, error); if(success) { SOSAccountStashAccountKey(account); + SOSAccountSetValue(account, kSOSAccountName, user_account, NULL); } secnotice("circleop", "Setting account.key_interests_need_updating to true in SOSAccountTryUserCredentials"); account.key_interests_need_updating = true; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountFullPeerInfo.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountFullPeerInfo.m index 46d9afb5..2acb59f7 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountFullPeerInfo.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountFullPeerInfo.m @@ -28,8 +28,13 @@ #include "SOSInternal.h" #include "SOSViews.h" #include "SOSPeerInfoV2.h" +#include "SOSPeerInfoPriv.h" +#import #import #import +#include +#include + static CFStringRef kicloud_identity_name = CFSTR("Cloud Identity"); @@ -192,3 +197,40 @@ fail: return cloud_peer; } + + +bool SOSAccountUpdatePeerInfo(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error, bool (^update)(SOSFullPeerInfoRef fpi, CFErrorRef *error)) { + + if (!account.hasPeerInfo) + return true; + + bool result = update(account.fullPeerInfo, error); + + if (result && SOSAccountHasCircle(account, NULL)) { + return [account.trust modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle_to_change) { + secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for %@", updateDescription); + return SOSCircleUpdatePeerInfo(circle_to_change, account.peerInfo); + }]; + } + + return result; +} + + +bool SOSAccountUpdatePeerInfoAndPush(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error, + bool (^update)(SOSPeerInfoRef pi, CFErrorRef *error)) { + return SOSAccountUpdatePeerInfo(account, updateDescription, error, ^bool(SOSFullPeerInfoRef fpi, CFErrorRef *localError) { + return SOSFullPeerInfoUpdate(fpi, localError, ^SOSPeerInfoRef(SOSPeerInfoRef pi, SecKeyRef peerPriv, CFErrorRef *localError) { + SOSPeerInfoRef newPI = SOSPeerInfoCreateCopy(kCFAllocatorDefault, pi, localError); + if(update(newPI, error)) { + if(peerPriv && SOSPeerInfoSign(peerPriv, newPI, localError)) { + secnotice("circleOp", "Signed Peerinfo to update"); + return newPI; + } + } + secnotice("circleOp", "Failed updating PeerInfo"); + CFReleaseNull(newPI); + return NULL; + }); + }); +} diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.m index 98d4b321..985db5c1 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.m @@ -135,6 +135,7 @@ CF_RETURNS_RETAINED SOSCircleRef SOSAccountCloneCircleWithoutMyGhosts(SOSAccount ![account.trust addiCloudIdentity:newCircle key:userPrivKey err:NULL]){ CFReleaseNull(newCircle); } + account.notifyBackupOnExit = true; } else { CFReleaseNull(newCircle); } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPeers.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPeers.m index 67a803ef..a64d5586 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPeers.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPeers.m @@ -21,13 +21,11 @@ * @APPLE_LICENSE_HEADER_END@ */ - -#include #include "SOSAccountPriv.h" +#include "SOSAccount.h" #include #include #include -#include #import #include @@ -264,17 +262,9 @@ CFBooleanRef SOSAccountPeersHaveViewsEnabled(SOSAccount* account, CFArrayRef vie CFMutableSetRef viewsRemaining = NULL; CFSetRef viewsToLookFor = NULL; - if(!SOSAccountHasPublicKey(account, error)) - { + if(![account isInCircle:error]) { CFReleaseNull(viewsToLookFor); CFReleaseNull(viewsRemaining); - - return result; - } - if(![account.trust isInCircle:error]){ - CFReleaseNull(viewsToLookFor); - CFReleaseNull(viewsRemaining); - return result; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.m index 66884133..24390737 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.m @@ -47,8 +47,6 @@ #import #import "Security/SecureObjectSync/SOSAccountTrustClassic.h" -#define kSecServerPeerInfoAvailable "com.apple.security.fpiAvailable" - @implementation SOSAccount (Persistence) @@ -441,17 +439,11 @@ static SOSAccount* SOSAccountCreateFromDER(CFAllocatorRef allocator, { SOSUnregisterTransportKeyParameter(account.key_transport); SOSUnregisterTransportCircle((SOSCircleStorageTransport*)account.circle_transport); - SOSUnregisterTransportMessage((SOSMessage*)account.ids_message_transport); SOSUnregisterTransportMessage(account.kvs_message_transport); secnotice("account", "No private key associated with my_identity, resetting"); return nil; } - notify_post(kSecServerPeerInfoAvailable); - if(account.deviceID && [account.deviceID length] != 0){ - SOSFullPeerInfoUpdateDeviceID(identity, (__bridge CFStringRef)(account.deviceID), error); - account.trust.fullPeerInfo = identity; - } } if (![account ensureFactoryCircles]) { @@ -462,15 +454,6 @@ static SOSAccount* SOSAccountCreateFromDER(CFAllocatorRef allocator, SOSPeerInfoRef oldPI = CFRetainSafe(account.peerInfo); if (oldPI) { SOSAccountCheckForAlwaysOnViews(account); - // if UpdateFullPeerInfo did something - we need to make sure we have the right Ref - SOSPeerInfoRef myPI = account.peerInfo; - CFStringRef transportTypeInflatedFromDER = SOSPeerInfoCopyTransportType(myPI); - - if(CFStringCompare(transportTypeInflatedFromDER, CFSTR("KVS"), 0) != 0){ - SOSFullPeerInfoUpdateTransportType(identity, SOSTransportMessageTypeKVS, NULL); - } - - CFReleaseNull(transportTypeInflatedFromDER); } CFReleaseNull(oldPI); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPriv.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPriv.h index 440d156a..7b033e99 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPriv.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPriv.h @@ -54,17 +54,15 @@ extern const CFStringRef kSOSAccountUUID; extern const CFStringRef kSOSAccountPeerNegotiationTimeouts; extern const CFStringRef kSOSRecoveryRing; extern const CFStringRef kSOSEscrowRecord; +extern const CFStringRef kSOSAccountName; extern const CFStringRef kSOSTestV2Settings; extern const CFStringRef kSOSRateLimitingCounters; extern const CFStringRef kSOSAccountPeerLastSentTimestamp; extern const CFStringRef kSOSAccountRenegotiationRetryCount; extern const CFStringRef kSOSInitialSyncTimeoutV0; -#define kSecServerPeerInfoAvailable "com.apple.security.fpiAvailable" - typedef void (^SOSAccountSaveBlock)(CFDataRef flattenedAccount, CFErrorRef flattenFailError); -@class SOSMessageIDS; @class SOSMessageKVS; @class CKKeyParameter; @class SOSAccountTrustClassic; @@ -92,7 +90,6 @@ typedef void (^SOSAccountSaveBlock)(CFDataRef flattenedAccount, CFErrorRef flatt @property (nonatomic, retain) CKKeyParameter* key_transport; @property (nonatomic) SOSKVSCircleStorageTransport* circle_transport; @property (nonatomic, retain) SOSMessageKVS* kvs_message_transport; -@property (nonatomic, retain) SOSMessageIDS* ids_message_transport; @property (nonatomic, retain) SOSCKCircleStorage* ck_storage; @@ -120,6 +117,13 @@ typedef void (^SOSAccountSaveBlock)(CFDataRef flattenedAccount, CFErrorRef flatt @property (readonly, nonatomic) SOSFullPeerInfoRef fullPeerInfo; @property (readonly, nonatomic) NSString* peerID; +@property (nonatomic, assign) BOOL notifyCircleChangeOnExit; +@property (nonatomic, assign) BOOL notifyViewChangeOnExit; +@property (nonatomic, assign) BOOL notifyBackupOnExit; + +@property (nonatomic, retain) NSUserDefaults* settings; + + -(id) init; -(id) initWithGestalt:(CFDictionaryRef)gestalt factory:(SOSDataSourceFactoryRef)factory; @@ -181,6 +185,7 @@ const uint8_t* der_decode_public_bytes(CFAllocatorRef allocator, CFIndex algorit // Update -(SOSCCStatus) getCircleStatus:(CFErrorRef*) error; +-(bool) isInCircle:(CFErrorRef *)error; bool SOSAccountHandleCircleMessage(SOSAccount* account, CFStringRef circleName, CFDataRef encodedCircleMessage, CFErrorRef *error); @@ -205,6 +210,8 @@ bool SOSAccountIsPeerInBackupAndCurrentInView(SOSAccount* account, SOSPeerInfoRe bool SOSDeleteV0Keybag(CFErrorRef *error); void SOSAccountForEachBackupView(SOSAccount* account, void (^operation)(const void *value)); bool SOSAccountUpdatePeerInfo(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error, bool (^update)(SOSFullPeerInfoRef fpi, CFErrorRef *error)); +bool SOSAccountUpdatePeerInfoAndPush(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error, + bool (^update)(SOSPeerInfoRef pi, CFErrorRef *error)); // Currently permitted backup rings. void SOSAccountForEachBackupRingName(SOSAccount* account, void (^operation)(CFStringRef value)); @@ -249,6 +256,8 @@ void SOSAccountSetUserPublicTrustedForTesting(SOSAccount* account); void SOSAccountPurgeIdentity(SOSAccount*); bool sosAccountLeaveCircle(SOSAccount* account, SOSCircleRef circle, CFErrorRef* error); +bool sosAccountLeaveCircleWithAnalytics(SOSAccount* account, SOSCircleRef circle, NSData* parentData, CFErrorRef* error); + bool sosAccountLeaveRing(SOSAccount* account, SOSRingRef ring, CFErrorRef* error); bool SOSAccountForEachRing(SOSAccount* account, SOSRingRef (^action)(CFStringRef name, SOSRingRef ring)); bool SOSAccountUpdateBackUp(SOSAccount* account, CFStringRef viewname, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRecovery.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRecovery.m index 56b76d7b..b93c6b5e 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRecovery.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRecovery.m @@ -144,7 +144,7 @@ bool SOSAccountSetRecoveryKey(SOSAccount* account, CFDataRef pubData, CFErrorRef CFDataRef oldRecoveryKey = NULL; SOSRecoveryKeyBagRef rkbg = NULL; - require_quiet([account.trust isInCircle:error], exit); + require_quiet([account isInCircle:error], exit); oldRecoveryKey = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL); // ok to fail here. don't collect error require_action_quiet(!CFEqualSafe(pubData, oldRecoveryKey), exit, result = true); @@ -224,22 +224,26 @@ static void sosRecoveryAlertAndNotify(SOSAccount* account, SOSRecoveryKeyBagRef void SOSAccountEnsureRecoveryRing(SOSAccount* account) { static SOSRecoveryKeyBagRef oldRingRKBG = NULL; - bool inCircle = [account.trust isInCircle:NULL]; + + if(![account isInCircle:NULL]) { + return; + } + CFStringRef accountDSID = SOSAccountGetValue(account, kSOSDSIDKey, NULL); // murfxxx this needs to be consulted still SOSRecoveryKeyBagRef acctRKBG = SOSAccountCopyRecoveryKeyBagEntry(kCFAllocatorDefault, account, NULL); SOSRecoveryKeyBagRef ringRKBG = SOSAccountCopyRecoveryKeyBag(kCFAllocatorDefault, account, NULL); if(!SOSRecoveryKeyBagDSIDIs(ringRKBG, accountDSID)) CFReleaseNull(ringRKBG); if(!SOSRecoveryKeyBagDSIDIs(acctRKBG, accountDSID)) CFReleaseNull(acctRKBG); - if(inCircle && acctRKBG == NULL && ringRKBG == NULL) { + if(acctRKBG == NULL && ringRKBG == NULL) { // Nothing to do at this time - notify if this is a change down below. - } else if(inCircle && acctRKBG == NULL) { // then we have a ringRKBG + } else if(acctRKBG == NULL) { // then we have a ringRKBG secnotice("recovery", "Harvesting account recovery key from ring"); SOSAccountSetRecoveryKeyBagEntry(kCFAllocatorDefault, account, ringRKBG, NULL); } else if(ringRKBG == NULL) { // Nothing to do at this time - notify if this is a change down below. secnotice("recovery", "Account has a recovery key, but none found in recovery ring"); - } else if(!CFEqual(acctRKBG, ringRKBG)) { + } else if(!CFEqualSafe(acctRKBG, ringRKBG)) { secnotice("recovery", "Harvesting account recovery key from ring"); SOSAccountSetRecoveryKeyBagEntry(kCFAllocatorDefault, account, ringRKBG, NULL); } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m index 80b9c440..73321514 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -16,7 +15,6 @@ #import #import #import -#import "Security/SecureObjectSync/SOSTransportMessageIDS.h" #import #include #include @@ -50,8 +48,6 @@ bool SOSAccountInflateTransports(SOSAccount* account, CFStringRef circleName, CF SOSUnregisterTransportKeyParameter(account.key_transport); if(account.circle_transport) SOSUnregisterTransportCircle(account.circle_transport); - if(account.ids_message_transport) - SOSUnregisterTransportMessage((SOSMessage*)account.ids_message_transport); if(account.kvs_message_transport) SOSUnregisterTransportMessage((SOSMessage*)account.kvs_message_transport); @@ -60,10 +56,7 @@ bool SOSAccountInflateTransports(SOSAccount* account, CFStringRef circleName, CF require_quiet(account.key_transport, fail); require_quiet(account.circle_transport, fail); - - account.ids_message_transport = [[SOSMessageIDS alloc] initWithAccount:account andName:(__bridge NSString *)(circleName)]; - require_quiet(account.ids_message_transport, fail); - + account.kvs_message_transport = [[SOSMessageKVS alloc] initWithAccount:account andName:(__bridge NSString*)circleName]; require_quiet(account.kvs_message_transport, fail); @@ -73,72 +66,6 @@ fail: return success; } -static bool SOSAccountIsThisPeerIDMe(SOSAccount* account, CFStringRef peerID) { - NSString* myPeerID = account.peerID; - - return myPeerID && [myPeerID isEqualToString: (__bridge NSString*) peerID]; -} - -bool SOSAccountSendIKSPSyncList(SOSAccount* account, CFErrorRef *error){ - bool result = true; - __block CFErrorRef localError = NULL; - __block CFMutableArrayRef ids = NULL; - SOSCircleRef circle = NULL; - SOSFullPeerInfoRef identity = NULL; - - if(![account.trust isInCircle:NULL]) - { - SOSCreateError(kSOSErrorNoCircle, CFSTR("This device is not in circle"), NULL, &localError); - if(error && *error != NULL) - secerror("SOSAccountSendIKSPSyncList had an error: %@", *error); - - if(localError) - secerror("SOSAccountSendIKSPSyncList had an error: %@", localError); - - CFReleaseNull(ids); - CFReleaseNull(localError); - - return result; - } - - circle = account.trust.trustedCircle; - identity = account.fullPeerInfo; - ids = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); - - SOSCircleForEachValidPeer(circle, account.accountKey, ^(SOSPeerInfoRef peer) { - if (!SOSAccountIsThisPeerIDMe(account, SOSPeerInfoGetPeerID(peer))) { - if(SOSPeerInfoShouldUseIDSTransport(SOSFullPeerInfoGetPeerInfo(identity), peer) && - SOSPeerInfoShouldUseIDSMessageFragmentation(SOSFullPeerInfoGetPeerInfo(identity), peer) && - !SOSPeerInfoShouldUseACKModel(SOSFullPeerInfoGetPeerInfo(identity), peer)){ - [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref:kCFBooleanTrue]; - CFStringRef deviceID = SOSPeerInfoCopyDeviceID(peer); - if(deviceID != NULL){ - CFArrayAppendValue(ids, deviceID); - } - CFReleaseNull(deviceID); - } - } - }); - require_quiet(CFArrayGetCount(ids) != 0, xit); - secnotice("IDS Transport", "List of IDS Peers to ping: %@", ids); - - SOSCloudKeychainGetIDSDeviceAvailability(ids, (__bridge CFStringRef)(account.peerID), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef returnedValues, CFErrorRef sync_error) { - bool success = (sync_error == NULL); - if(!success) - secerror("Failed to send list of IDS peers to IDSKSP: %@", sync_error); - }); -xit: - if(error && *error != NULL) - secerror("SOSAccountSendIKSPSyncList had an error: %@", *error); - - if(localError) - secerror("SOSAccountSendIKSPSyncList had an error: %@", localError); - - CFReleaseNull(ids); - CFReleaseNull(localError); - - return result; -} // // MARK: KVS Syncing // @@ -148,7 +75,7 @@ static bool SOSAccountSyncWithKVSPeers(SOSAccountTransaction* txn, CFSetRef peer CFErrorRef localError = NULL; bool result = false; - require_quiet([account.trust isInCircle:error], xit); + require_quiet([account isInCircle:error], xit); result =[account.kvs_message_transport SOSTransportMessageSyncWithPeers:account.kvs_message_transport p:peerIDs err:&localError]; @@ -215,60 +142,6 @@ static bool SOSAccountSyncWithKVSPeer(SOSAccountTransaction* txn, CFStringRef pe return result; } -static CFMutableArrayRef SOSAccountCopyPeerIDsForDSID(SOSAccount* account, CFStringRef deviceID, CFErrorRef* error) { - CFMutableArrayRef peerIDs = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); - - SOSCircleForEachValidPeer(account.trust.trustedCircle, account.accountKey, ^(SOSPeerInfoRef peer) { - CFStringRef peerDeviceID = SOSPeerInfoCopyDeviceID(peer); - if(peerDeviceID != NULL && CFStringCompare(peerDeviceID, deviceID, 0) == 0){ - CFArrayAppendValue(peerIDs, SOSPeerInfoGetPeerID(peer)); - } - CFReleaseNull(peerDeviceID); - }); - - if (peerIDs == NULL || CFArrayGetCount(peerIDs) == 0) { - CFReleaseNull(peerIDs); - SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("No peer with DSID: %@"), deviceID); - } - - return peerIDs; -} - -static bool SOSAccountSyncWithKVSPeerFromPing(SOSAccount* account, CFArrayRef peerIDs, CFErrorRef *error) { - - CFErrorRef localError = NULL; - bool result = false; - - CFSetRef peerSet = CFSetCreateCopyOfArrayForCFTypes(peerIDs); - result = [account.kvs_message_transport SOSTransportMessageSyncWithPeers:account.kvs_message_transport p:peerSet err:&localError]; - - CFReleaseNull(peerSet); - - return result; -} - -bool SOSAccountSyncWithKVSUsingIDSID(SOSAccount* account, CFStringRef deviceID, CFErrorRef *error) { - bool result = false; - CFErrorRef localError = NULL; - - secnotice("KVS Transport","Syncing with KVS capable peer via DSID: %@", deviceID); - - CFArrayRef peerIDs = SOSAccountCopyPeerIDsForDSID(account, deviceID, &localError); - require_quiet(peerIDs, xit); - - CFStringArrayPerfromWithDescription(peerIDs, ^(CFStringRef peerIDList) { - secnotice("KVS Transport", "Syncing with KVS capable peers: %@", peerIDList); - }); - - result = SOSAccountSyncWithKVSPeerFromPing(account, peerIDs, &localError); - secerror("KVS sync %s. (%@)", result ? "succeeded" : "failed", localError); - -xit: - CFReleaseNull(peerIDs); - CFErrorPropagate(localError, error); - - return result; -} CFSetRef SOSAccountSyncWithPeersOverKVS(SOSAccountTransaction* txn, CFSetRef peers) { CFMutableSetRef handled = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); @@ -287,50 +160,28 @@ CFSetRef SOSAccountSyncWithPeersOverKVS(SOSAccountTransaction* txn, CFSetRef pee return handled; } -CF_RETURNS_RETAINED CFSetRef SOSAccountSyncWithPeersOverIDS(SOSAccountTransaction* txn, CFSetRef peers) { - CFErrorRef localError = NULL; - SOSAccount* account = txn.account; - - CFStringSetPerformWithDescription(peers, ^(CFStringRef peerDescription) { - secnotice("IDS Transport","Syncing with IDS capable peers: %@", peerDescription); - }); - - // We should change this to return a set of peers we succeeded with, but for now assume they all worked. - bool result = [account.ids_message_transport SOSTransportMessageSyncWithPeers:account.ids_message_transport p:peers err:&localError]; - secnotice("IDS Transport", "IDS Sync result: %d", result); - - return CFSetCreateCopy(kCFAllocatorDefault, peers); -} - CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransaction* txn, CFSetRef /* CFStringRef */ peerIDs, CFErrorRef *error) { CFMutableSetRef notMePeers = NULL; CFMutableSetRef handledPeerIDs = NULL; - CFMutableSetRef peersForIDS = NULL; CFMutableSetRef peersForKVS = NULL; SOSAccount* account = txn.account; - // Kick getting our device ID if we don't have it, and find out if we're setup to use IDS. - bool canUseIDS = [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account]; - - if(![account.trust isInCircle:error]) + if(![account isInCircle:error]) { handledPeerIDs = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, peerIDs); CFReleaseNull(notMePeers); - CFReleaseNull(peersForIDS); CFReleaseNull(peersForKVS); return handledPeerIDs; } handledPeerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - peersForIDS = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); peersForKVS = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); SOSPeerInfoRef myPeerInfo = account.peerInfo; if(!myPeerInfo) { CFReleaseNull(notMePeers); - CFReleaseNull(peersForIDS); CFReleaseNull(peersForKVS); return handledPeerIDs; @@ -339,11 +190,6 @@ CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransactio notMePeers = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, peerIDs); CFSetRemoveValue(notMePeers, myPeerID); - - if(!SOSAccountSendIKSPSyncList(account, error)){ - if(error != NULL) - secnotice("IDS Transport", "Did not send list of peers to ping (pre-E): %@", *error); - } CFSetForEach(notMePeers, ^(const void *value) { CFErrorRef localError = NULL; @@ -355,12 +201,8 @@ CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransactio require_quiet(peerID, skip); peerInfo = SOSCircleCopyPeerWithID(circle, peerID, NULL); - if (peerInfo && SOSCircleHasValidSyncingPeer(circle, peerInfo, account.accountKey, NULL)) { - if (ENABLE_IDS && canUseIDS && SOSPeerInfoShouldUseIDSTransport(myPeerInfo, peerInfo) && SOSPeerInfoShouldUseACKModel(myPeerInfo, peerInfo)) { - CFSetAddValue(peersForIDS, peerID); - } else { - CFSetAddValue(peersForKVS, peerID); - } + if (peerInfo && SOSCircleHasValidSyncingPeer(circle, peerInfo, account.accountKey, NULL)){ + CFSetAddValue(peersForKVS, peerID); } else { CFSetAddValue(handledPeerIDs, peerID); } @@ -373,10 +215,6 @@ CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransactio CFReleaseNull(localError); }); - CFSetRef handledIDSPeerIDs = SOSAccountSyncWithPeersOverIDS(txn, peersForIDS); - CFSetUnion(handledPeerIDs, handledIDSPeerIDs); - CFReleaseNull(handledIDSPeerIDs); - CFSetRef handledKVSPeerIDs = SOSAccountSyncWithPeersOverKVS(txn, peersForKVS); CFSetUnion(handledPeerIDs, handledKVSPeerIDs); CFReleaseNull(handledKVSPeerIDs); @@ -384,43 +222,10 @@ CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransactio SOSAccountConsiderLoggingEngineState(txn); CFReleaseNull(notMePeers); - CFReleaseNull(peersForIDS); CFReleaseNull(peersForKVS); return handledPeerIDs; } -bool SOSAccountClearPeerMessageKey(SOSAccountTransaction* txn, CFStringRef peerID, CFErrorRef *error) -{ - if (peerID == NULL) { - return false; - } - - SOSAccount* account = txn.account; - - secnotice("IDS Transport", "clearing peer message for %@", peerID); - CFTypeRef dsid = SOSAccountGetValue(account, kSOSDSIDKey, error); - - if(dsid == NULL) - dsid = kCFNull; - - CFStringRef myID = (__bridge CFStringRef)(account.peerID); - CFStringRef message_to_peer_key = SOSMessageKeyCreateFromTransportToPeer(account.kvs_message_transport, myID, peerID); - CFDictionaryRef a_message_to_a_peer = CFDictionaryCreateForCFTypes(NULL, message_to_peer_key, kCFNull, kSOSKVSRequiredKey, dsid, NULL); - - CloudKeychainReplyBlock log_error = ^(CFDictionaryRef returnedValues __unused, CFErrorRef block_error) { - if (block_error) { - secerror("Error putting: %@", block_error); - } - }; - - SOSCloudKeychainPutObjectsInCloud(a_message_to_a_peer, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), log_error); - - CFReleaseNull(a_message_to_a_peer); - CFReleaseNull(message_to_peer_key); - - return true; -} - CF_RETURNS_RETAINED CFSetRef SOSAccountProcessSyncWithPeers(SOSAccountTransaction* txn, CFSetRef /* CFStringRef */ peers, CFSetRef /* CFStringRef */ backupPeers, CFErrorRef *error) { CFErrorRef localError = NULL; @@ -428,8 +233,6 @@ CF_RETURNS_RETAINED CFSetRef SOSAccountProcessSyncWithPeers(SOSAccountTransactio CFMutableSetRef handled = SOSAccountSyncWithPeers(txn, peers, &localError); - [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account]; - if (!handled) { secnotice("account-sync", "Peer Sync failed: %@", localError); handled = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); @@ -464,15 +267,12 @@ bool SOSAccountRequestSyncWithAllPeers(SOSAccountTransaction* txn, CFErrorRef *e SOSAccount* account = txn.account; SOSAccountTrustClassic *trust = account.trust; - if (![account.trust isInCircle:error]) + if (![account isInCircle:error]) return false; NSMutableSet* allSyncingPeers = [NSMutableSet set]; SOSCircleRef circle = trust.trustedCircle; - // Tickle IDS in case we haven't even tried when we're syncing. - [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account]; - SOSCircleForEachValidSyncingPeer(circle, account.accountKey, ^(SOSPeerInfoRef peer) { [allSyncingPeers addObject: (__bridge NSString*) SOSPeerInfoGetPeerID(peer)]; }); @@ -488,7 +288,7 @@ bool SOSAccountRequestSyncWithAllPeers(SOSAccountTransaction* txn, CFErrorRef *e bool SOSAccountMessageFromPeerIsPending(SOSAccountTransaction* txn, SOSPeerInfoRef peer, CFErrorRef *error) { bool success = false; SOSAccount* account = txn.account; - require_quiet([account.trust isInCircle:error], xit); + require_quiet([account isInCircle:error], xit); // This translation belongs inside KVS..way down in CKD, but for now we reach over and do it here. CFStringRef peerMessage = SOSMessageKeyCreateFromPeerToTransport([account kvs_message_transport], (__bridge CFStringRef)(account.peerID), SOSPeerInfoGetPeerID(peer)); @@ -503,7 +303,7 @@ xit: bool SOSAccountSendToPeerIsPending(SOSAccountTransaction* txn, SOSPeerInfoRef peer, CFErrorRef *error) { bool success = false; SOSAccount* account = txn.account; - require_quiet([account.trust isInCircle:error], xit); + require_quiet([account isInCircle:error], xit); success = SOSCCIsSyncPendingFor(SOSPeerInfoGetPeerID(peer), error); xit: diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m index f1003698..e256e359 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m @@ -19,6 +19,7 @@ #import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #import "Security/SecureObjectSync/SOSAccountTrustClassic.h" #import "Security/SecureObjectSync/SOSTransportMessageKVS.h" +#import "Security/SecItemBackup.h" #include @@ -39,6 +40,8 @@ @property BOOL initialTrusted; @property NSData* initialKeyParameters; +@property uint initialCirclePeerCount; + @property bool quiet; @property NSMutableSet* peersToRequestSync; @@ -51,6 +54,66 @@ @implementation SOSAccountTransaction +static void SOSCircleSetCachedStatus(SOSAccount *account) { + static SOSCCStatus lastStatus = -2; + SOSCCStatus currentStatus = [account getCircleStatus:NULL]; + + if(lastStatus != currentStatus) { + lastStatus = currentStatus; + account.notifyCircleChangeOnExit = true; + } + + if(account.notifyCircleChangeOnExit) { + __block uint64_t circleStatus = [account.trust getCircleStatusOnly:NULL] | CC_STATISVALID; + if(account.accountKeyIsTrusted) { + circleStatus |= CC_UKEY_TRUSTED; + if(account.accountPrivateKey) { + circleStatus |= CC_CAN_AUTH; + } + } + // we might be in circle, but invalid - let client see this in bitmask. + if([account.trust isInCircleOnly:NULL]) { + circleStatus |= CC_PEER_IS_IN; + } + + SOSCachedNotificationOperation(kSOSCCCircleChangedNotification, ^bool(int token, bool gtg) { + if(gtg) { + uint32_t status = notify_set_state(token, circleStatus); + if(status == NOTIFY_STATUS_OK) { + notify_post(kSOSCCCircleChangedNotification); + account.notifyCircleChangeOnExit = false; + } + return true; + } + return false; + }); + } +} + +static void SOSViewsSetCachedStatus(SOSAccount *account) { + static uint64_t lastViewBitmask = 0; + __block uint64_t viewBitMask = ([account getCircleStatus:NULL] == kSOSCCInCircle) ? SOSPeerInfoViewBitMask(account.peerInfo) :0; + + if(viewBitMask != lastViewBitmask) { + lastViewBitmask = viewBitMask; + account.notifyViewChangeOnExit = true; // this is also set within operations and might want the notification for other reasons. + } + + if(account.notifyViewChangeOnExit) { + SOSCachedNotificationOperation(kSOSCCViewMembershipChangedNotification, ^bool(int token, bool gtg) { + if(gtg) { + uint32_t status = notify_set_state(token, viewBitMask); + if(status == NOTIFY_STATUS_OK) { + notify_post(kSOSCCViewMembershipChangedNotification); + account.notifyViewChangeOnExit = false; + } + return true; + } + return false; + }); + } +} + - (NSString*) description { return [NSString stringWithFormat:@"", self, (unsigned long)(self.initialViews ? [self.initialViews count] : 0)]; @@ -66,8 +129,15 @@ } - (void) start { - self.initialInCircle = [self.account.trust isInCircle:NULL]; + SOSCircleSetCachedStatus(_account); + SOSViewsSetCachedStatus(_account); + + self.initialInCircle = [self.account isInCircle:NULL]; self.initialTrusted = self.account.accountKeyIsTrusted; + self.initialCirclePeerCount = 0; + if(self.initialInCircle) { + self.initialCirclePeerCount = SOSCircleCountPeers(self.account.trust.trustedCircle); + } if (self.initialInCircle) { SOSAccountEnsureSyncChecking(self.account); @@ -107,7 +177,7 @@ SOSPeerInfoRef mpi = self.account.peerInfo; - bool isInCircle = [self.account.trust isInCircle:NULL]; + bool isInCircle = [self.account isInCircle:NULL]; if (isInCircle && self.peersToRequestSync) { SOSCCRequestSyncWithPeers((__bridge CFSetRef)(self.peersToRequestSync)); @@ -184,7 +254,16 @@ [self.account flattenToSaveBlock]; // Refresh isInCircle since we could have changed our mind - isInCircle = [self.account.trust isInCircle:NULL]; + isInCircle = [self.account isInCircle:NULL]; + + uint finalCirclePeerCount = 0; + if(isInCircle) { + finalCirclePeerCount = SOSCircleCountPeers(self.account.trust.trustedCircle); + } + + if(isInCircle && (finalCirclePeerCount < self.initialCirclePeerCount)) { + (void) SOSAccountCleanupAllKVSKeys(_account, NULL); + } mpi = self.account.peerInfo; CFSetRef views = mpi ? SOSPeerInfoCopyEnabledViews(mpi) : NULL; @@ -242,8 +321,17 @@ doViewChanged = true; } - if(doCircleChanged) notify_post(kSOSCCCircleChangedNotification); - if(doViewChanged) notify_post(kSOSCCViewMembershipChangedNotification); + if(doCircleChanged) { + SOSCircleSetCachedStatus(_account); + } + if(doViewChanged) { + SOSViewsSetCachedStatus(_account); + } + if(self.account.notifyBackupOnExit) { + notify_post(kSecItemBackupNotification); + self.account.notifyBackupOnExit = false; + } + if(do_account_state_at_zero <= 0) { SOSAccountLogState(self.account); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.h index 9b45a2c0..8da930bc 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.h @@ -11,24 +11,28 @@ @interface SOSAccountTrustClassic (Circle) //Circle --(SOSCCStatus) getCircleStatus:(CFErrorRef*) error; +-(SOSCCStatus) getCircleStatusOnly:(CFErrorRef*) error; -(SOSCircleRef) ensureCircle:(SOSAccount*)account name:(CFStringRef)name err:(CFErrorRef *)error; -(bool) modifyCircle:(SOSCircleStorageTransport*)circleTransport err:(CFErrorRef*)error action:(SOSModifyCircleBlock)block; -(SOSCircleRef) getCircle:(CFErrorRef *)error; -(bool) hasCircle:(CFErrorRef*) error; -(void) generationSignatureUpdateWith:(SOSAccount*)account key:(SecKeyRef) privKey; --(bool) isInCircle:(CFErrorRef *)error; +-(bool) isInCircleOnly:(CFErrorRef *)error; -(void) forEachCirclePeerExceptMe:(SOSIteratePeerBlock)block; -(bool) leaveCircle:(SOSAccount*)account err:(CFErrorRef*) error; +-(bool) leaveCircleWithAccount:(SOSAccount*)account withAnalytics:(NSData*)parentEvent err:(CFErrorRef*) error; -(bool) resetToOffering:(SOSAccountTransaction*) aTxn key:(SecKeyRef)userKey err:(CFErrorRef*) error; -(bool) resetCircleToOffering:(SOSAccountTransaction*) aTxn userKey:(SecKeyRef) user_key err:(CFErrorRef *)error; -(SOSCCStatus) thisDeviceStatusInCircle:(SOSCircleRef) circle peer:(SOSPeerInfoRef) this_peer; -(bool) updateCircle:(SOSCircleStorageTransport*)circleTransport newCircle:(SOSCircleRef) newCircle err:(CFErrorRef*)error; +-(bool) updateCircleWithAnalytics:(SOSCircleStorageTransport*)circleTransport newCircle:(SOSCircleRef) newCircle parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error; + -(bool) updateCircleFromRemote:(SOSCircleStorageTransport*)circleTransport newCircle:(SOSCircleRef)newCircle err:(CFErrorRef*)error; -(CFArrayRef) copySortedPeerArray:(CFErrorRef *)error action:(SOSModifyPeersInCircleBlock)block; -(bool) handleUpdateCircle:(SOSCircleRef) prospective_circle transport:(SOSCircleStorageTransport*)circleTransport update:(bool) writeUpdate err:(CFErrorRef*)error; +-(bool) handleUpdateCircleWithAnalytics:(SOSCircleRef) prospective_circle transport:(SOSCircleStorageTransport*)circleTransport update:(bool) writeUpdate parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error; -(bool) joinCircle:(SOSAccountTransaction*) aTxn userKey:(SecKeyRef)user_key useCloudPeer:(bool)use_cloud_peer err:(CFErrorRef*) error; @end diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m index 662d5dd2..6dcdf812 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m @@ -18,9 +18,9 @@ @implementation SOSAccountTrustClassic (Circle) --(bool) isInCircle:(CFErrorRef *)error +-(bool) isInCircleOnly:(CFErrorRef *)error { - SOSCCStatus result = [self getCircleStatus:error]; + SOSCCStatus result = [self getCircleStatusOnly:error]; if (result != kSOSCCInCircle) { SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("Not in circle")); @@ -60,7 +60,7 @@ return kSOSCCNotInCircle; } --(SOSCCStatus) getCircleStatus:(CFErrorRef*) error +-(SOSCCStatus) getCircleStatusOnly:(CFErrorRef*) error { return [self thisDeviceStatusInCircle:self.trustedCircle peer:self.peerInfo]; } @@ -222,6 +222,415 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO return hasUpdated; } +-(bool) handleUpdateCircleWithAnalytics:(SOSCircleRef) prospective_circle transport:(SOSCircleStorageTransport*)circleTransport update:(bool) writeUpdate parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error +{ + bool success = true; + bool haveOldCircle = true; + const char *local_remote = writeUpdate ? "local": "remote"; + + NSError* localError = nil; + SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + + SOSAccount* account = [circleTransport getAccount]; + + secnotice("signing", "start:[%s]", local_remote); + if (!account.accountKey || !account.accountKeyIsTrusted) { + SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("Can't handle updates with no trusted public key here"), NULL, error); + return false; + } + + if (!prospective_circle) { + secerror("##### Can't update to a NULL circle ######"); + return false; // Can't update one we don't have. + } + + // If this is a remote circle, check to see if this is our first opportunity to trust a circle where we + // sponsored the only signer. + if(!writeUpdate && [ self checkForSponsorshipTrust: prospective_circle ]){ + SOSCCEnsurePeerRegistration(); + secnotice("circleop", "Setting key_interests_need_updating to true in handleUpdateCircle"); + account.key_interests_need_updating = true; + return true; + + } + + CFStringRef newCircleName = SOSCircleGetName(prospective_circle); + + SOSCircleRef oldCircle = self.trustedCircle; + SOSCircleRef emptyCircle = NULL; + + if(oldCircle == NULL) { + SOSCreateErrorWithFormat(kSOSErrorIncompatibleCircle, NULL, error, NULL, CFSTR("Current Entry is NULL; rejecting %@"), prospective_circle); + secerror("##### Can't replace circle - we don't care about it ######"); + return false; + } + if (CFGetTypeID(oldCircle) != SOSCircleGetTypeID()) { + secdebug("signing", ">>>>>>>>>>>>>>> Non-Circle Circle found <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); + // We don't know what is in our table, likely it was kCFNull indicating we didn't + // understand a circle that came by. We seem to like this one lets make our entry be empty circle + emptyCircle = SOSCircleCreate(kCFAllocatorDefault, newCircleName, NULL); + oldCircle = emptyCircle; + haveOldCircle = false; + // And we're paranoid, drop our old peer info if for some reason we didn't before. + // SOSAccountDestroyCirclePeerInfo(account, oldCircle, NULL); + } + + CFErrorRef retiredError = NULL; + SFSignInAnalytics *scanForRetiredEvent = [parent newSubTaskForEvent:@"scanForRetiredEvent"]; + SOSAccountScanForRetired(account, prospective_circle, &retiredError); + if(retiredError){ + [scanForRetiredEvent logRecoverableError:(__bridge NSError*)retiredError]; + secerror("scan for retired error: %@", retiredError); + if(error){ + *error = retiredError; + }else{ + CFReleaseNull(retiredError); + } + } + [scanForRetiredEvent stopWithAttributes:nil]; + + SOSCircleRef newCircle = SOSAccountCloneCircleWithRetirement(account, prospective_circle, error); + if(!newCircle) return false; + + SFSignInAnalytics *ghostBustingEvent = [parent newSubTaskForEvent:@"ghostBustingEvent"]; + if([self ghostBustingOK: oldCircle updatingTo:newCircle]) { + SOSCircleRef ghostCleaned = SOSAccountCloneCircleWithoutMyGhosts(account, newCircle); + if(ghostCleaned) { + CFRetainAssign(newCircle, ghostCleaned); + writeUpdate = true; + } + } + [ghostBustingEvent stopWithAttributes:nil]; + + SOSFullPeerInfoRef me_full = self.fullPeerInfo; + SOSPeerInfoRef me = SOSFullPeerInfoGetPeerInfo(me_full); + CFStringRef myPeerID = SOSPeerInfoGetPeerID(me); + myPeerID = (myPeerID) ? myPeerID: CFSTR("No Peer"); + + if (me && SOSCircleUpdatePeerInfo(newCircle, me)) { + writeUpdate = true; // If we update our peer in the new circle we should write it if we accept it. + } + + typedef enum { + accept, + countersign, + leave, + revert, + ignore + } circle_action_t; + + static const char *actionstring[] = { + "accept", "countersign", "leave", "revert", "ignore", + }; + + circle_action_t circle_action = ignore; + enum DepartureReason leave_reason = kSOSNeverLeftCircle; + + SecKeyRef old_circle_key = NULL; + + CFErrorRef verifyCircleError = NULL; + SFSignInAnalytics *verifyCircleEvent = [parent newSubTaskForEvent:@"verifyCircleEvent"]; + if(SOSCircleVerify(oldCircle, account.accountKey, &verifyCircleError)){ + old_circle_key = account.accountKey; + } + else if(account.previousAccountKey && SOSCircleVerify(oldCircle, account.previousAccountKey, &verifyCircleError)){ + old_circle_key = account.previousAccountKey; + } + if(verifyCircleError){ + [verifyCircleEvent logRecoverableError:(__bridge NSError*)verifyCircleError]; + secerror("verifyCircle error: %@", verifyCircleError); + if(error){ + *error = verifyCircleError; + }else{ + CFReleaseNull(verifyCircleError); + } + } + [verifyCircleEvent stopWithAttributes:nil]; + + bool userTrustedOldCircle = (old_circle_key != NULL) && haveOldCircle; + + SFSignInAnalytics *concordanceTrustEvent = [parent newSubTaskForEvent:@"concordanceTrustEvent"]; + CFErrorRef concordanceError = NULL; + SOSConcordanceStatus concstat = + SOSCircleConcordanceTrust(oldCircle, newCircle, + old_circle_key, account.accountKey, + me, &concordanceError); + if(concordanceError){ + [concordanceTrustEvent logRecoverableError:(__bridge NSError*)concordanceError]; + secerror("concordance trust error: %@", concordanceError); + if(error){ + *error = concordanceError; + }else{ + CFReleaseNull(concordanceError); + } + } + [concordanceTrustEvent stopWithAttributes:nil]; + + CFStringRef concStr = NULL; + switch(concstat) { + case kSOSConcordanceTrusted: + circle_action = countersign; + concStr = CFSTR("Trusted"); + break; + case kSOSConcordanceGenOld: + circle_action = userTrustedOldCircle ? revert : ignore; + concStr = CFSTR("Generation Old"); + break; + case kSOSConcordanceBadUserSig: + case kSOSConcordanceBadPeerSig: + circle_action = userTrustedOldCircle ? revert : accept; + concStr = CFSTR("Bad Signature"); + break; + case kSOSConcordanceNoUserSig: + circle_action = userTrustedOldCircle ? revert : accept; + concStr = CFSTR("No User Signature"); + break; + case kSOSConcordanceNoPeerSig: + circle_action = accept; // We might like this one eventually but don't countersign. + concStr = CFSTR("No trusted peer signature"); + secnotice("signing", "##### No trusted peer signature found, accepting hoping for concordance later"); + break; + case kSOSConcordanceNoPeer: + circle_action = leave; + leave_reason = kSOSLeftUntrustedCircle; + concStr = CFSTR("No trusted peer left"); + break; + case kSOSConcordanceNoUserKey: + secerror("##### No User Public Key Available, this shouldn't ever happen!!!"); + abort(); + break; + default: + secerror("##### Bad Error Return from ConcordanceTrust"); + abort(); + break; + } + + secnotice("signing", "Decided on action [%s] based on concordance state [%@] and [%s] circle. My PeerID is %@", actionstring[circle_action], concStr, userTrustedOldCircle ? "trusted" : "untrusted", myPeerID); + + SOSCircleRef circleToPush = NULL; + + if (circle_action == leave) { + circle_action = ignore; (void) circle_action; // Acknowledge this is a dead store. + + if (me && SOSCircleHasPeer(oldCircle, me, NULL)) { + secnotice("account", "Leaving circle with peer %@", me); + debugDumpCircle(CFSTR("oldCircle"), oldCircle); + debugDumpCircle(CFSTR("newCircle"), newCircle); + debugDumpCircle(CFSTR("prospective_circle"), prospective_circle); + secnotice("account", "Key state: accountKey %@, previousAccountKey %@, old_circle_key %@", + account.accountKey, account.previousAccountKey, old_circle_key); + + if (sosAccountLeaveCircleWithAnalytics(account, newCircle, parentEvent, error)) { + secnotice("circleOps", "Leaving circle by newcircle state"); + circleToPush = newCircle; + } else { + secnotice("signing", "Can't leave circle, but dumping identities"); + success = false; + } + self.departureCode = leave_reason; + circle_action = accept; + me = NULL; + me_full = NULL; + } else { + // We are not in this circle, but we need to update account with it, since we got it from cloud + secnotice("signing", "We are not in this circle, but we need to update account with it"); + debugDumpCircle(CFSTR("oldCircle"), oldCircle); + debugDumpCircle(CFSTR("newCircle"), newCircle); + debugDumpCircle(CFSTR("prospective_circle"), prospective_circle); + circle_action = accept; + } + } + + if (circle_action == countersign) { + if (me && SOSCircleHasPeer(newCircle, me, NULL)) { + SFSignInAnalytics *verifyPeerSignedEvent = [parent newSubTaskForEvent:@"verifyPeerSignedEvent"]; + CFErrorRef verifyPeerSignedError = NULL; + if (SOSCircleVerifyPeerSigned(newCircle, me, &verifyPeerSignedError)) { + secnotice("signing", "Already concur with the new circle"); + } else { + CFErrorRef signing_error = NULL; + SFSignInAnalytics *circleConcordanceSignEvent = [parent newSubTaskForEvent:@"circleConcordanceSignEvent"]; + if (me_full && SOSCircleConcordanceSign(newCircle, me_full, &signing_error)) { + circleToPush = newCircle; + secnotice("signing", "Concurred with new circle"); + } else { + secerror("Failed to concurrence sign, error: %@", signing_error); + success = false; + } + if(signing_error){ + [circleConcordanceSignEvent logRecoverableError:(__bridge NSError*)signing_error]; + secerror("circle concordance sign error: %@", signing_error); + if(error){ + *error = signing_error; + }else{ + CFReleaseNull(signing_error); + } + } + [circleConcordanceSignEvent stopWithAttributes:nil]; + CFReleaseSafe(signing_error); + } + if(verifyPeerSignedError){ + [verifyPeerSignedEvent logRecoverableError:(__bridge NSError*)verifyPeerSignedError]; + secerror("verify peer signed error: %@", verifyPeerSignedError); + if(error){ + *error = verifyPeerSignedError; + }else{ + CFReleaseNull(verifyPeerSignedError); + } + } + [verifyPeerSignedEvent stopWithAttributes:nil]; + } else { + secnotice("signing", "Not countersigning, not in new circle"); + } + circle_action = accept; + } + + if (circle_action == accept) { + if(SOSCircleHasUpdatedPeerInfoWithOctagonKey(oldCircle, newCircle)){ + notify_post(kSOSCCCircleOctagonKeysChangedNotification); + } + if (me && SOSCircleHasActivePeer(oldCircle, me, NULL) && !SOSCircleHasPeer(newCircle, me, NULL)) { + // Don't destroy evidence of other code determining reason for leaving. + if(![self hasLeft]) self.departureCode = kSOSMembershipRevoked; + secnotice("circleOps", "Member of old circle but not of new circle (%d)", self.departureCode); + debugDumpCircle(CFSTR("oldCircle"), oldCircle); + debugDumpCircle(CFSTR("newCircle"), newCircle); + } + + if (me + && SOSCircleHasActivePeer(oldCircle, me, NULL) + && !(SOSCircleCountPeers(oldCircle) == 1 && SOSCircleHasPeer(oldCircle, me, NULL)) // If it was our offering, don't change ID to avoid ghosts + && !SOSCircleHasPeer(newCircle, me, NULL) && !SOSCircleHasApplicant(newCircle, me, NULL)) { + secnotice("circle", "Purging my peer (ID: %@) for circle '%@'!!!", SOSPeerInfoGetPeerID(me), SOSCircleGetName(oldCircle)); + if (self.fullPeerInfo) + SOSFullPeerInfoPurgePersistentKey(self.fullPeerInfo, NULL); + me = NULL; + me_full = NULL; + } + + if (me && SOSCircleHasRejectedApplicant(newCircle, me, NULL)) { + SOSPeerInfoRef reject = SOSCircleCopyRejectedApplicant(newCircle, me, NULL); + if(CFEqualSafe(reject, me) && SOSPeerInfoApplicationVerify(me, account.accountKey, NULL)) { + secnotice("circle", "Rejected, Purging my applicant peer (ID: %@) for circle '%@'", SOSPeerInfoGetPeerID(me), SOSCircleGetName(oldCircle)); + debugDumpCircle(CFSTR("oldCircle"), oldCircle); + debugDumpCircle(CFSTR("newCircle"), newCircle); + if (self.fullPeerInfo) + SOSFullPeerInfoPurgePersistentKey(self.fullPeerInfo, NULL); + me = NULL; + me_full = NULL; + } else { + secnotice("circle", "Rejected, Reapplying (ID: %@) for circle '%@'", SOSPeerInfoGetPeerID(me), SOSCircleGetName(oldCircle)); + debugDumpCircle(CFSTR("oldCircle"), oldCircle); + debugDumpCircle(CFSTR("newCircle"), newCircle); + SOSCircleRequestReadmission(newCircle, account.accountKey, me, NULL); + writeUpdate = true; + } + CFReleaseNull(reject); + } + + CFRetainSafe(oldCircle); + account.previousAccountKey = account.accountKey; + + secnotice("signing", "%@, Accepting new circle", concStr); + if (circle_action == accept) { + [self setTrustedCircle:newCircle]; + } + + if (me && account.accountKeyIsTrusted + && SOSCircleHasApplicant(oldCircle, me, NULL) + && SOSCircleCountPeers(newCircle) > 0 + && !SOSCircleHasPeer(newCircle, me, NULL) && !SOSCircleHasApplicant(newCircle, me, NULL)) { + // We weren't rejected (above would have set me to NULL. + // We were applying and we weren't accepted. + // Our application is declared lost, let us reapply. + + secnotice("signing", "requesting readmission to new circle"); + if (SOSCircleRequestReadmission(newCircle, account.accountKey, me, NULL)) + writeUpdate = true; + } + + if (me && SOSCircleHasActivePeer(oldCircle, me, NULL)) { + SFSignInAnalytics *cleanupRetirementTicketsEvent = [parent newSubTaskForEvent:@"cleanupRetirementTicketsEvent"]; + CFErrorRef cleanupError = NULL; + [account.trust cleanupRetirementTickets:account circle:oldCircle time:RETIREMENT_FINALIZATION_SECONDS err:&cleanupError]; + if(cleanupError){ + [cleanupRetirementTicketsEvent logRecoverableError:(__bridge NSError*)cleanupError]; + secerror("cleanup retirement tickets error: %@", cleanupError); + if(error){ + *error = cleanupError; + }else{ + CFReleaseNull(cleanupError); + } + } + [cleanupRetirementTicketsEvent stopWithAttributes:nil]; + } + + SFSignInAnalytics *notifyOfChangeEvent = [parent newSubTaskForEvent:@"notifyOfChangeEvent"]; + SOSAccountNotifyOfChange(account, oldCircle, newCircle); + [notifyOfChangeEvent stopWithAttributes:nil]; + + CFReleaseNull(oldCircle); + + if (writeUpdate) + circleToPush = newCircle; + secnotice("circleop", "Setting key_interests_need_updating to true in handleUpdateCircle"); + account.key_interests_need_updating = true; + } + + /* + * In the revert section we'll guard the KVS idea of circles by rejecting "bad" new circles + * and pushing our current view of the circle (oldCircle). We'll only do this if we actually + * are a member of oldCircle - never for an empty circle. + */ + + if (circle_action == revert) { + if(haveOldCircle && me && SOSCircleHasActivePeer(oldCircle, me, NULL)) { + secnotice("signing", "%@, Rejecting new circle, re-publishing old circle", concStr); + circleToPush = oldCircle; + [self setTrustedCircle:oldCircle]; + } else { + secnotice("canary", "%@, Rejecting: new circle Have no old circle - would reset", concStr); + } + } + + if (circleToPush != NULL) { + secnotice("signing", "Pushing:[%s]", local_remote); + CFDataRef circle_data = SOSCircleCopyEncodedData(circleToPush, kCFAllocatorDefault, error); + + if (circle_data) { + // Ensure we flush changes + account.circle_rings_retirements_need_attention = true; + + //posting new circle to peers + SFSignInAnalytics *postCircleEvent = [parent newSubTaskForEvent:@"postCircleEvent"]; + CFErrorRef postCircleError = NULL; + success &= [circleTransport postCircle:SOSCircleGetName(circleToPush) circleData:circle_data err:&postCircleError]; + if(postCircleError){ + [postCircleEvent logRecoverableError:(__bridge NSError*)postCircleError]; + secerror("posting circle failed: %@", postCircleError); + if(error){ + *error = postCircleError; + }else{ + CFReleaseNull(postCircleError); + } + } + [postCircleEvent stopWithAttributes:nil]; + } else { + success = false; + } + CFReleaseNull(circle_data); + } + CFReleaseSafe(newCircle); + CFReleaseNull(emptyCircle); + + // There are errors collected above that are soft (worked around) + if(success && error && *error) { + CFReleaseNull(*error); + } + + return success; +} + -(bool) handleUpdateCircle:(SOSCircleRef) prospective_circle transport:(SOSKVSCircleStorageTransport*)circleTransport update:(bool) writeUpdate err:(CFErrorRef*)error { bool success = true; @@ -416,7 +825,6 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO } } else { secnotice("signing", "Not countersigning, not in new circle"); - debugDumpCircle(CFSTR("circle to countersign"), newCircle); } circle_action = accept; } @@ -508,8 +916,6 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO if (circle_action == revert) { if(haveOldCircle && me && SOSCircleHasActivePeer(oldCircle, me, NULL)) { secnotice("signing", "%@, Rejecting new circle, re-publishing old circle", concStr); - debugDumpCircle(CFSTR("oldCircle"), oldCircle); - debugDumpCircle(CFSTR("newCircle"), newCircle); circleToPush = oldCircle; [self setTrustedCircle:oldCircle]; } else { @@ -528,8 +934,6 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO //posting new circle to peers success &= [circleTransport postCircle:SOSCircleGetName(circleToPush) circleData:circle_data err:error]; - //cleanup old KVS keys - (void) SOSAccountCleanupAllKVSKeys(account, NULL); } else { success = false; } @@ -556,6 +960,30 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO return [self handleUpdateCircle:newCircle transport:circleTransport update:true err:error]; } +-(bool) updateCircleWithAnalytics:(SOSKVSCircleStorageTransport*)circleTransport newCircle:(SOSCircleRef) newCircle parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error +{ + return [self handleUpdateCircle:newCircle transport:circleTransport update:true err:error]; +} + +-(bool) modifyCircleWithAnalytics:(SOSKVSCircleStorageTransport*)circleTransport parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error action:(SOSModifyCircleBlock)block +{ + bool success = false; + SOSCircleRef circleCopy = NULL; + require_action_quiet(self.trustedCircle, fail, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to get peer key from"))); + + circleCopy = SOSCircleCopyCircle(kCFAllocatorDefault, self.trustedCircle, error); + require_quiet(circleCopy, fail); + + success = true; + require_quiet(block(circleCopy), fail); + + success = [self updateCircleWithAnalytics:circleTransport newCircle:circleCopy parentEvent:parentEvent err:error]; + +fail: + CFReleaseSafe(circleCopy); + return success; +} + -(bool) modifyCircle:(SOSKVSCircleStorageTransport*)circleTransport err:(CFErrorRef*)error action:(SOSModifyCircleBlock)block { bool success = false; @@ -592,7 +1020,11 @@ fail: SOSFullPeerInfoRef icfpi = SOSCircleCopyiCloudFullPeerInfoRef(circle, NULL); if(!icfpi) { SOSAccountRemoveIncompleteiCloudIdentities(account, circle, privKey, NULL); - change |= [self addiCloudIdentity:circle key:privKey err:NULL]; + bool identityAdded = [self addiCloudIdentity:circle key:privKey err:NULL]; + if(identityAdded) { + account.notifyBackupOnExit = true; + } + change |= identityAdded; } else { CFReleaseNull(icfpi); } @@ -615,6 +1047,20 @@ fail: }); } } + +-(bool) leaveCircleWithAccount:(SOSAccount*)account withAnalytics:(NSData*)parentEvent err:(CFErrorRef*) error +{ + bool result = true; + secnotice("circleOps", "leaveCircleWithAccount: Leaving circle by client request"); + result &= [self modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle) { + return sosAccountLeaveCircleWithAnalytics(account, circle, parentEvent, error); + }]; + + self.departureCode = kSOSWithdrewMembership; + + return result; +} + -(bool) leaveCircle:(SOSAccount*)account err:(CFErrorRef*) error { bool result = true; @@ -666,7 +1112,8 @@ fail: require_quiet([self addiCloudIdentity:circle key:user_key err:error], err_out); result = true; SOSAccountPublishCloudParameters(account, NULL); - + account.notifyBackupOnExit = true; + err_out: if (result == false) secerror("error resetting circle (%@) to offering: %@", circle, localError); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.h index 9a2e38d1..88ccec8b 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.h @@ -22,6 +22,8 @@ -(bool) resetRing:(SOSAccount*)account ringName:(CFStringRef) ringName err:(CFErrorRef *)error; -(bool) leaveRing:(SOSKVSCircleStorageTransport*)circle_transport ring:(SOSRingRef) ring err:(CFErrorRef*) error; -(bool) resetAccountToEmpty:(SOSAccount*)account transport: (SOSCircleStorageTransport*)circleTransport err:(CFErrorRef*) error; +-(bool) resetAccountToEmptyWithAnalytics:(SOSAccount*)account transport: (SOSCircleStorageTransport*)circleTransport parentEvent:(NSData*)parentEvent err:(CFErrorRef*) error; + -(SOSRingRef) copyRing:(CFStringRef) ringName err:(CFErrorRef *)error; -(CFMutableDictionaryRef) getRings:(CFErrorRef *)error; -(bool) forEachRing:(RingNameBlock)block; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m index f59341ab..fbf71a27 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m @@ -13,6 +13,7 @@ #import "Security/SecureObjectSync/SOSViews.h" #import "Security/SecureObjectSync/SOSPeerInfoV2.h" #import "Security/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/Signin Metrics/SFSignInAnalytics.h" @implementation SOSAccountTrustClassic (Expansion) typedef enum { @@ -204,9 +205,9 @@ errOut: { __block bool result = true; - + result &= [self resetAllRings:account err:error]; - + self.fullPeerInfo = nil; self.departureCode = kSOSWithdrewMembership; @@ -223,6 +224,45 @@ errOut: return result; } +-(bool) resetAccountToEmptyWithAnalytics:(SOSAccount*)account transport: (SOSCircleStorageTransport*)circleTransport parentEvent:(NSData*)parentEvent err:(CFErrorRef*) error +{ + __block bool result = true; + + NSError* localError = nil; + SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + + CFErrorRef resetError = NULL; + SFSignInAnalytics *resetAllRingsEvent = [parent newSubTaskForEvent:@"resetAllRingsEvent"]; + result &= [self resetAllRings:account err:&resetError]; + if(resetError){ + [resetAllRingsEvent logRecoverableError:(__bridge NSError*)resetError]; + secerror("reset all rings error: %@", resetError); + if(error){ + *error = resetError; + }else{ + CFReleaseNull(resetError); + } + } + [resetAllRingsEvent stopWithAttributes:nil]; + + self.fullPeerInfo = nil; + + self.departureCode = kSOSWithdrewMembership; + secnotice("circleOps", "Reset Circle to empty by client request"); + + SFSignInAnalytics *resetCircleToEmptyEvent = [parent newSubTaskForEvent:@"resetCircleToEmptyEvent"]; + result &= [self modifyCircle:circleTransport err:error action:^bool(SOSCircleRef circle) { + result = SOSCircleResetToEmpty(circle, error); + return result; + }]; + [resetCircleToEmptyEvent stopWithAttributes:nil]; + + if (!result) { + secerror("error: %@", error ? *error : NULL); + } + return result; +} + -(void) setRings:(CFMutableDictionaryRef) newrings { [self.expansion setObject:(__bridge NSMutableDictionary*)newrings forKey:(kSOSRingKey)]; @@ -303,13 +343,14 @@ static bool SOSAccountBackupSliceKeyBagNeedsFix(SOSAccount* account, SOSBackupSl SOSFullPeerInfoRef fpi = self.fullPeerInfo; SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fpi); CFStringRef peerID = SOSPeerInfoGetPeerID(pi); - bool peerActive = (fpi && pi && peerID && [self isInCircle:NULL]); + bool peerActive = (fpi && pi && peerID && [self isInCircleOnly:NULL]); SOSRingRef newRing = NULL; SOSRingRef oldRing = NULL; - + + require_quiet(SOSAccountHasPublicKey(account, error), errOut); + secdebug("ringSigning", "start:[%s] %@", localRemote, prospectiveRing); - require_quiet(SOSAccountHasPublicKey(account, error), errOut); require_action_quiet(prospectiveRing, errOut, SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("No Ring to work with"), NULL, error)); @@ -553,7 +594,7 @@ errOut: CFMutableDictionaryRef rings = [self getRings:error]; require_action_quiet(rings, errOut, SOSCreateError(kSOSErrorNoRing, CFSTR("No Rings found"), NULL, error)); CFTypeRef ringder = CFDictionaryGetValue(rings, ringName); - require_action_quiet(ringder, errOut, SOSCreateError(kSOSErrorNoRing, CFSTR("No Ring found"), NULL, error)); + require_action_quiet(ringder, errOut, SOSCreateErrorWithFormat(kSOSErrorNoRing, NULL, error, NULL, CFSTR("No Ring found %@"), ringName)); SOSRingRef ring = SOSRingCreateFromData(NULL, ringder); return (SOSRingRef) ring; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m index 1d22def5..16b29cf6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m @@ -251,16 +251,6 @@ CFReleaseNull(pendingDefaultViews); [self setValueInExpansion:kSOSUnsyncedViewsKey value:kCFBooleanTrue err:NULL]; - - if (!self.fullPeerInfo) { - secerror("Can't make FullPeerInfo for %@-%@ (%@) - is AKS ok?", SOSPeerGestaltGetName(gestalt), SOSCircleGetName(self.trustedCircle), error ? (void*)*error : (void*)CFSTR("-")); - } - else{ - secnotice("fpi", "alert KeychainSyncingOverIDSProxy the fpi is available"); - notify_post(kSecServerPeerInfoAvailable); - if(deviceID) - SOSFullPeerInfoUpdateDeviceID(self.fullPeerInfo, deviceID, error); - } } else { secerror("No full_key: %@:", error ? *error : NULL); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h index 6b6895bd..fe1c260e 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h @@ -16,11 +16,6 @@ +(instancetype)trustClassic; - -//Security Properties --(SOSSecurityPropertyResultCode) UpdateSecurityProperty:(SOSAccount*)account property:(CFStringRef)property code:(SOSSecurityPropertyActionCode)actionCode err:(CFErrorRef*)error; --(SOSSecurityPropertyResultCode) SecurityPropertyStatus:(CFStringRef)property err:(CFErrorRef *)error; - //Gestalt Dictionary -(bool) updateGestalt:(SOSAccount*)account newGestalt:(CFDictionaryRef) new_gestalt; @@ -38,6 +33,8 @@ -(SOSViewResultCode) updateView:(SOSAccount*)account name:(CFStringRef) viewname code:(SOSViewActionCode) actionCode err:(CFErrorRef *)error; -(SOSViewResultCode) viewStatus:(SOSAccount*)account name:(CFStringRef) viewname err:(CFErrorRef *)error; -(bool) updateViewSets:(SOSAccount*)account enabled:(CFSetRef) origEnabledViews disabled:(CFSetRef) origDisabledViews; +-(bool) updateViewSetsWithAnalytics:(SOSAccount*)account enabled:(CFSetRef) origEnabledViews disabled:(CFSetRef) origDisabledViews parentEvent:(NSData*)parentEvent; + -(CFSetRef) copyPeerSetForView:(CFStringRef) viewName; //DER diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m index 0fa63766..93d9df08 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m @@ -15,7 +15,6 @@ #import "Security/SecureObjectSync/SOSPeerInfoV2.h" #import "Security/SecureObjectSync/SOSPeerInfoCollections.h" #import "Security/SecureObjectSync/SOSTransportMessageKVS.h" -#import "Security/SecureObjectSync/SOSTransportMessageIDS.h" #include #include @@ -68,44 +67,6 @@ extern CFStringRef kSOSAccountDebugScope; } --(SOSSecurityPropertyResultCode) UpdateSecurityProperty:(SOSAccount*)account property:(CFStringRef)property code:(SOSSecurityPropertyActionCode)actionCode err:(CFErrorRef*)error -{ - SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError; - bool updateCircle = false; - - require_action_quiet(self.trustedCircle, errOut, SOSCreateError(kSOSErrorNoCircle, CFSTR("No Trusted Circle"), NULL, error)); - require_action_quiet(self.fullPeerInfo, errOut, SOSCreateError(kSOSErrorPeerNotFound, CFSTR("No Peer for Account"), NULL, error)); - retval = SOSFullPeerInfoUpdateSecurityProperty(self.fullPeerInfo, actionCode, property, error); - - if(actionCode == kSOSCCSecurityPropertyEnable && retval == kSOSCCSecurityPropertyValid) { - updateCircle = true; - } else if(actionCode == kSOSCCSecurityPropertyDisable && retval == kSOSCCSecurityPropertyNotValid) { - updateCircle = true; - } else if(actionCode == kSOSCCSecurityPropertyPending) { - updateCircle = true; - } - - if (updateCircle) { - [self modifyCircle:account.circle_transport err:NULL action:^(SOSCircleRef circle_to_change) { - secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for security property change"); - return SOSCircleUpdatePeerInfo(circle_to_change, self.peerInfo); - }]; - } - -errOut: - return retval; -} - --(SOSSecurityPropertyResultCode) SecurityPropertyStatus:(CFStringRef)property err:(CFErrorRef *)error -{ - SOSSecurityPropertyResultCode retval = kSOSCCGeneralViewError; - require_action_quiet(self.trustedCircle, errOut, SOSCreateError(kSOSErrorNoCircle, CFSTR("No Trusted Circle"), NULL, error)); - require_action_quiet(self.fullPeerInfo, errOut, SOSCreateError(kSOSErrorPeerNotFound, CFSTR("No Peer for Account"), NULL, error)); - retval = SOSFullPeerInfoSecurityPropertyStatus(self.fullPeerInfo, property, error); -errOut: - return retval; -} - -(bool) updateGestalt:(SOSAccount*)account newGestalt:(CFDictionaryRef)new_gestalt { @@ -124,6 +85,8 @@ errOut: return true; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-value" -(SOSViewResultCode) updateView:(SOSAccount*)account name:(CFStringRef) viewname code:(SOSViewActionCode) actionCode err:(CFErrorRef *)error { SOSViewResultCode retval = kSOSCCGeneralViewError; @@ -181,6 +144,7 @@ errOut: errOut: return retval; } +#pragma clang diagnostic pop -(bool) activeValidInCircle:(SOSAccount*) account err:(CFErrorRef *)error { return SOSCircleHasActiveValidPeer(self.trustedCircle, SOSFullPeerInfoGetPeerInfo(self.fullPeerInfo), SOSAccountGetTrustedPublicCredential(account, error), error); @@ -190,6 +154,7 @@ errOut: { SOSViewResultCode retval = kSOSCCGeneralViewError; + require_action_quiet(SOSAccountGetTrustedPublicCredential(account, error), errOut, SOSCreateError(kSOSErrorNoKey, CFSTR("No Trusted UserKey"), NULL, error)); require_action_quiet(self.trustedCircle, errOut, SOSCreateError(kSOSErrorNoCircle, CFSTR("No Trusted Circle"), NULL, error)); require_action_quiet(self.fullPeerInfo, errOut, SOSCreateError(kSOSErrorPeerNotFound, CFSTR("No Peer for Account"), NULL, error)); require_action_quiet([self activeValidInCircle: account err: error ], @@ -242,6 +207,87 @@ static bool SOSAccountScreenViewListForValidV0(SOSAccount* account, CFMutableSe return retval; } +-(bool) updateViewSetsWithAnalytics:(SOSAccount*)account enabled:(CFSetRef) origEnabledViews disabled:(CFSetRef) origDisabledViews parentEvent:(NSData*)parentEvent +{ + bool retval = false; + bool updateCircle = false; + SOSPeerInfoRef pi = NULL; + NSError* localError = nil; + SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + + SFSignInAnalytics *hasCompletedInitialSyncEvent = nil; + SFSignInAnalytics *updatePeerInCircleEvent = nil; + + CFMutableSetRef enabledViews = NULL; + CFMutableSetRef disabledViews = NULL; + if(origEnabledViews) enabledViews = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, origEnabledViews); + if(origDisabledViews) disabledViews = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, origDisabledViews); + dumpViewSet(CFSTR("Enabled"), enabledViews); + dumpViewSet(CFSTR("Disabled"), disabledViews); + + require_action_quiet(self.trustedCircle, errOut, secnotice("views", "Attempt to set viewsets with no trusted circle")); + + // Make sure we have a peerInfo capable of supporting views. + SOSFullPeerInfoRef fpi = self.fullPeerInfo; + require_action_quiet(fpi, errOut, secnotice("views", "Attempt to set viewsets with no fullPeerInfo")); + require_action_quiet(enabledViews || disabledViews, errOut, secnotice("views", "No work to do")); + + pi = SOSPeerInfoCreateCopy(kCFAllocatorDefault, SOSFullPeerInfoGetPeerInfo(fpi), NULL); + + require_action_quiet(pi, errOut, secnotice("views", "Couldn't copy PeerInfoRef")); + + if(!SOSPeerInfoVersionIsCurrent(pi)) { + CFErrorRef updateFailure = NULL; + require_action_quiet(SOSPeerInfoUpdateToV2(pi, &updateFailure), errOut, + (secnotice("views", "Unable to update peer to V2- can't update views: %@", updateFailure), (void) CFReleaseNull(updateFailure))); + secnotice("V2update", "Updating PeerInfo to V2 within SOSAccountUpdateViewSets"); + updateCircle = true; + } + + CFStringSetPerformWithDescription(enabledViews, ^(CFStringRef description) { + secnotice("viewChange", "Enabling %@", description); + }); + + CFStringSetPerformWithDescription(disabledViews, ^(CFStringRef description) { + secnotice("viewChange", "Disabling %@", description); + }); + + require_action_quiet(SOSAccountScreenViewListForValidV0(account, enabledViews, kSOSCCViewEnable), errOut, secnotice("viewChange", "Bad view change (enable) with kSOSViewKeychainV0")); + require_action_quiet(SOSAccountScreenViewListForValidV0(account, disabledViews, kSOSCCViewDisable), errOut, secnotice("viewChange", "Bad view change (disable) with kSOSViewKeychainV0")); + + hasCompletedInitialSyncEvent = [parent newSubTaskForEvent:@"hasCompletedInitialSyncEvent"]; + if(SOSAccountHasCompletedInitialSync(account)) { + if(enabledViews) updateCircle |= SOSViewSetEnable(pi, enabledViews); + if(disabledViews) updateCircle |= SOSViewSetDisable(pi, disabledViews); + retval = true; + } else { + //hold on to the views and enable them later + if(enabledViews) [self pendEnableViewSet:enabledViews]; + if(disabledViews) SOSAccountPendDisableViewSet(account, disabledViews); + retval = true; + } + [hasCompletedInitialSyncEvent stopWithAttributes:nil]; + if(updateCircle) { + /* UPDATE FULLPEERINFO VIEWS */ + require_quiet(SOSFullPeerInfoUpdateToThisPeer(fpi, pi, NULL), errOut); + updatePeerInCircleEvent = [parent newSubTaskForEvent:@"updatePeerInCircleEvent"]; + require_quiet([self modifyCircle:account.circle_transport err:NULL action:^(SOSCircleRef circle_to_change) { + secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for views or peerInfo change"); + bool updated= SOSCircleUpdatePeerInfo(circle_to_change, self.peerInfo); + return updated; + }], errOut); + [updatePeerInCircleEvent stopWithAttributes:nil]; + // Make sure we update the engine + account.circle_rings_retirements_need_attention = true; + } + +errOut: + [updatePeerInCircleEvent stopWithAttributes:nil]; + CFReleaseNull(enabledViews); + CFReleaseNull(disabledViews); + CFReleaseNull(pi); + return retval; +} -(bool) updateViewSets:(SOSAccount*)account enabled:(CFSetRef) origEnabledViews disabled:(CFSetRef) origDisabledViews { bool retval = false; @@ -328,7 +374,7 @@ static inline void CFArrayAppendValueIfNot(CFMutableArrayRef array, CFTypeRef va if (!changeBlock) return; SOSAccount* account = txn.account; CFRetainSafe(ds_name); - SOSAccountCircleMembershipChangeBlock block_to_register = ^void (SOSCircleRef new_circle, + SOSAccountCircleMembershipChangeBlock block_to_register = ^void (SOSAccount *account, SOSCircleRef new_circle, CFSetRef added_peers, CFSetRef removed_peers, CFSetRef added_applicants, CFSetRef removed_applicants) { @@ -368,7 +414,7 @@ static inline void CFArrayAppendValueIfNot(CFMutableArrayRef array, CFTypeRef va CFSetRef empty = CFSetCreateMutableForSOSPeerInfosByID(kCFAllocatorDefault); if (self.trustedCircle && CFEqualSafe(ds_name, SOSCircleGetName(self.trustedCircle))) { - block_to_register(self.trustedCircle, empty, empty, empty, empty); + block_to_register(account, self.trustedCircle, empty, empty, empty, empty); } CFReleaseSafe(empty); } @@ -635,34 +681,25 @@ static uint8_t* der_encode_data_optional(CFDataRef data, CFErrorRef *error, { CFMutableSetRef notMePeers = NULL; CFMutableSetRef handledPeerIDs = NULL; - CFMutableSetRef peersForIDS = NULL; CFMutableSetRef peersForKVS = NULL; SOSAccount* account = txn.account; - - // Kick getting our device ID if we don't have it, and find out if we're setup to use IDS. - [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account]; - bool canUseIDS = [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account]; - - if(![self isInCircle:error]) + if(![account isInCircle:error]) { handledPeerIDs = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, peerIDs); CFReleaseNull(notMePeers); - CFReleaseNull(peersForIDS); CFReleaseNull(peersForKVS); return handledPeerIDs; } handledPeerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - peersForIDS = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); peersForKVS = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); SOSPeerInfoRef myPeerInfo = account.peerInfo; if(!myPeerInfo) { CFReleaseNull(notMePeers); - CFReleaseNull(peersForIDS); CFReleaseNull(peersForKVS); return handledPeerIDs; @@ -680,11 +717,7 @@ static uint8_t* der_encode_data_optional(CFDataRef data, CFErrorRef *error, peerInfo = SOSCircleCopyPeerWithID(self.trustedCircle, peerID, NULL); if (peerInfo && SOSCircleHasValidSyncingPeer(self.trustedCircle, peerInfo, account.accountKey, NULL)) { - if (ENABLE_IDS && canUseIDS && SOSPeerInfoShouldUseIDSTransport(myPeerInfo, peerInfo)) { - CFSetAddValue(peersForIDS, peerID); - } else { - CFSetAddValue(peersForKVS, peerID); - } + CFSetAddValue(peersForKVS, peerID); } else { CFSetAddValue(handledPeerIDs, peerID); } @@ -696,11 +729,7 @@ static uint8_t* der_encode_data_optional(CFDataRef data, CFErrorRef *error, } CFReleaseNull(localError); }); - - CFSetRef handledIDSPeerIDs = SOSAccountSyncWithPeersOverIDS(txn, peersForIDS); - CFSetUnion(handledPeerIDs, handledIDSPeerIDs); - CFReleaseNull(handledIDSPeerIDs); - + CFSetRef handledKVSPeerIDs = SOSAccountSyncWithPeersOverKVS(txn, peersForKVS); CFSetUnion(handledPeerIDs, handledKVSPeerIDs); CFReleaseNull(handledKVSPeerIDs); @@ -708,14 +737,13 @@ static uint8_t* der_encode_data_optional(CFDataRef data, CFErrorRef *error, SOSAccountConsiderLoggingEngineState(txn); CFReleaseNull(notMePeers); - CFReleaseNull(peersForIDS); CFReleaseNull(peersForKVS); return handledPeerIDs; } -(bool) requestSyncWithAllPeers:(SOSAccountTransaction*) txn key:(SecKeyRef)userPublic err:(CFErrorRef *)error { - if (![self isInCircle: error]) { + if (![txn.account isInCircle: error]) { return false; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustOctagon.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustOctagon.h deleted file mode 100644 index 82b0ae5c..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustOctagon.h +++ /dev/null @@ -1,11 +0,0 @@ -// -// SOSAccountTrustOctagon_h -// Security -// - -#ifndef SOSAccountTrustOctagon_h -#define SOSAccountTrustOctagon_h - -#import "Security/SecureObjectSync/SOSAccountTrust.h" - -#endif /* SOSAccountTrustOctagon_h */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustOctagon.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustOctagon.m deleted file mode 100644 index 81cc3883..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustOctagon.m +++ /dev/null @@ -1,6 +0,0 @@ -// -// SOSAccountTrustOctagon.m -// Security -// - -#import diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m index d5ac122f..e8f7de9d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m @@ -253,7 +253,7 @@ void SOSAccountNotifyOfChange(SOSAccount* account, SOSCircleRef oldCircle, SOSCi DifferenceAndCall(old_applicants, new_applicants, ^(CFSetRef added_applicants, CFSetRef removed_applicants) { CFArrayForEach((__bridge CFArrayRef)(account.change_blocks), ^(const void * notificationBlock) { secnotice("updates", "calling change block"); - ((__bridge SOSAccountCircleMembershipChangeBlock) notificationBlock)(newCircle, added_members, removed_members, added_applicants, removed_applicants); + ((__bridge SOSAccountCircleMembershipChangeBlock) notificationBlock)(account, newCircle, added_members, removed_members, added_applicants, removed_applicants); }); }); }); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountViewSync.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountViewSync.m index 1eba28b7..34ea0992 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountViewSync.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountViewSync.m @@ -313,7 +313,7 @@ void SOSAccountPeerGotInSync(SOSAccountTransaction* aTxn, CFStringRef peerID, CF SOSCircleRef circle = NULL; SOSAccountTrustClassic* trust = account.trust; circle = trust.trustedCircle; - if (circle && [account.trust isInCircle:NULL] && SOSCircleHasActivePeerWithID(circle, peerID, NULL)) { + if (circle && [account isInCircle:NULL] && SOSCircleHasActivePeerWithID(circle, peerID, NULL)) { SOSAccountUpdateOutOfSyncViews(aTxn, views); } } @@ -356,7 +356,7 @@ bool SOSAccountCheckForAlwaysOnViews(SOSAccount* account) { bool changed = false; SOSPeerInfoRef myPI = account.peerInfo; require_quiet(myPI, done); - require_quiet([account.trust isInCircle:NULL], done); + require_quiet([account isInCircle:NULL], done); require_quiet(SOSAccountHasCompletedInitialSync(account), done); CFMutableSetRef viewsToEnsure = SOSViewCopyViewSet(kViewSetAlwaysOn); // Previous version PeerInfo if we were syncing legacy keychain, ensure we include those legacy views. diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.h new file mode 100644 index 00000000..4652f047 --- /dev/null +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.h @@ -0,0 +1,25 @@ +// +// SOSAuthKitHelpers.h +// Security +// + +#ifndef SOSAuthKitHelpers_h +#define SOSAuthKitHelpers_h + +#include + +NS_ASSUME_NONNULL_BEGIN + +@interface SOSAuthKitHelpers : NSObject ++ (NSString * _Nullable)machineID; ++ (bool) updateMIDInPeerInfo: (SOSAccount *) account; ++ (bool) peerinfoHasMID: (SOSAccount *) account; + +// activeMIDs might block on network ++ (void)activeMIDs:(void(^_Nonnull)(NSSet * _Nullable activeMIDs, NSError * _Nullable error))complete; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* SOSAuthKitHelpers_h */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.m new file mode 100644 index 00000000..7eb82fb2 --- /dev/null +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.m @@ -0,0 +1,165 @@ +// +// SOSAuthKitHelpers.m +// Security +// +// Created by murf on 6/19/18. +// + +#import +#import "SOSAuthKitHelpers.h" +#import +#import +#import +#import +#import +#import + +#if !TARGET_OS_BRIDGE && !TARGET_OS_SIMULATOR +#import +#import +#import + +#define SUPPORT_MID 1 +#endif + +@implementation SOSAuthKitHelpers + +#if SUPPORT_MID + +SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit); +SOFT_LINK_FRAMEWORK(Frameworks, Accounts); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wstrict-prototypes" +SOFT_LINK_CLASS(AuthKit, AKAccountManager); +SOFT_LINK_CLASS(AuthKit, AKAnisetteProvisioningController); +SOFT_LINK_CLASS(AuthKit, AKAppleIDAuthenticationController); +SOFT_LINK_CLASS(AuthKit, AKDeviceListRequestContext); +SOFT_LINK_CLASS(Accounts, Accounts); +SOFT_LINK_CLASS(Accounts, ACAccountStore); +SOFT_LINK_CONSTANT(AuthKit, AKServiceNameiCloud, const NSString *); +#pragma clang diagnostic pop + + + ++ (NSString *) machineID { + NSError *error = nil; + NSString *retval = nil; + secnotice("sosauthkit", "Entering machineID"); + + AKAnisetteProvisioningController *anisetteController = [getAKAnisetteProvisioningControllerClass() new]; + if(anisetteController) { + AKAnisetteData *anisetteData = [anisetteController anisetteDataWithError:&error]; + if (anisetteData) { + retval = [anisetteData.machineID copy]; + if(retval) { + secnotice("sosauthkit", "machineID is %@", retval); + } else { + secnotice("sosauthkit", "Failed to get machineID"); + } + } else { + secnotice("sosauthkit", "can't get mID: %@", error); + } + } else { + secnotice("sosauthkit", "can't get controller"); + } + return retval; +} + ++ (bool) peerinfoHasMID: (SOSAccount *) account { + SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(account.fullPeerInfo); + if(!pi) return false; + return SOSPeerInfoV2DictionaryHasString(pi, sMachineIDKey); +} + ++ (bool) updateMIDInPeerInfo: (SOSAccount *) account { + NSString *mid = [SOSAuthKitHelpers machineID]; + if(!mid) return true; + CFErrorRef error = NULL; + SOSAccountSetValue(account, sMachineIDKey, (__bridge CFStringRef)mid, &error); + bool peerUpdated = SOSAccountUpdatePeerInfoAndPush(account, CFSTR("Add Machine ID"), &error, ^bool(SOSPeerInfoRef pi, CFErrorRef *error) { + if(SOSPeerInfoV2DictionaryHasString(pi, sMachineIDKey)) { + return false; + } + secnotice("sosauthkit", "Setting PeerInfo MID to %@", mid); + SOSPeerInfoV2DictionarySetValue(pi, sMachineIDKey, (__bridge CFStringRef)mid); + return true; + }); + if(!peerUpdated) { + secnotice("sosauthkit", "Failed to record MID in PeerInfo: %@", error); + } + CFReleaseNull(error); + return peerUpdated; +} + ++ (void)activeMIDs:(void(^_Nonnull)(NSSet *activeMIDs, NSError *error))complete { + AKDeviceListRequestContext *context; + ACAccount *primaryAccount; + + ACAccountStore *store = [getACAccountStoreClass() new]; + if(!store) { + complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get store"}]); + return; + } + primaryAccount = [store aa_primaryAppleAccount]; + if(!primaryAccount) { + secnotice("sosauthkit", "can't get account"); + complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"no primary account"}]); + return; + } + + context = [getAKDeviceListRequestContextClass() new]; + if (context == NULL) { + complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get AKDeviceListRequestContextClass"}]); + return; + } + context.altDSID = primaryAccount.aa_altDSID; + context.services = @[ getAKServiceNameiCloud() ]; + + AKAppleIDAuthenticationController *authController = [getAKAppleIDAuthenticationControllerClass() new]; + if(!authController) { + complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get authController"}]); + return; + } + + [authController fetchDeviceListWithContext:context completion:^(NSArray *deviceList, NSError *error) { + NSMutableSet *mids = [[NSMutableSet alloc] init]; + if (deviceList != nil) { + for (AKRemoteDevice *device in deviceList) { + [mids addObject:device.machineId]; + } + } else { + secnotice("sosauthkit", "got no mIDs: %@", error); + } + if([mids count] == 0) { + secnotice("sosauthkit", "found not devices in account"); + mids = nil; + } + + complete(mids, error); + }]; +} + + +#else /* TARGET_OS_BRIDGE || TARGET_OS_SIMULATOR */ + ++ (NSString *) machineID { + return nil; +} + ++ (void)activeMIDs:(void(^_Nonnull)(NSSet *activeMIDs, NSError *error))complete { + complete(NULL, NULL); +} + ++ (bool) updateMIDInPeerInfo: (SOSAccount *) account { + return true; +} + ++ (bool) peerinfoHasMID: (SOSAccount *) account { + return false; +} + +#endif + +@end + diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.m index bfd2686a..e89c54e5 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.m @@ -444,7 +444,7 @@ CFSetRef SOSBSKBGetPeers(SOSBackupSliceKeyBagRef backupSliceKeyBag){ } int SOSBSKBCountPeers(SOSBackupSliceKeyBagRef backupSliceKeyBag) { - return (int) CFSetGetCount(backupSliceKeyBag->peers); + return (backupSliceKeyBag->peers) ? (int) CFSetGetCount(backupSliceKeyBag->peers): 0; } bool SOSBSKBPeerIsInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, SOSPeerInfoRef pi) { @@ -703,9 +703,10 @@ CFDataRef SOSBSKBCopyRecoveryKey(SOSBackupSliceKeyBagRef bskb) { } bool SOSBSKBHasRecoveryKey(SOSBackupSliceKeyBagRef bskb) { + if(!bskb) return false; if(SOSBSKBHasPrefixedKey(bskb, bskbRkbgPrefix)) return true; // old way for RecoveryKeys - int keyCount = (int) CFDictionaryGetCount(bskb->wrapped_keys); + int keyCount = (bskb->wrapped_keys != NULL) ? (int) CFDictionaryGetCount(bskb->wrapped_keys): 0; int peerCount = SOSBSKBCountPeers(bskb); return !SOSBSKBIsDirect(bskb) && ((keyCount - peerCount) > 0); } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c b/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c index 8df24f6d..b715e1ef 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c @@ -149,7 +149,7 @@ static bool SOSCircleDigestArray(const struct ccdigest_info *di, CFMutableArrayR void * a_digest = (void * )array_digest; ccdigest_init(di, array_digest); - CFArraySortValues(array, CFRangeMake(0, CFArrayGetCount(array)), SOSPeerInfoCompareByID, SOSPeerCmpPubKeyHash); + CFArraySortValues(array, CFRangeMake(0, CFArrayGetCount(array)), SOSPeerInfoCompareByID, (void *)SOSPeerCmpPubKeyHash); CFArrayForEach(array, ^(const void *peer) { if (!SOSPeerInfoUpdateDigestWithPublicKeyBytes((SOSPeerInfoRef)peer, di, a_digest, error)) success = false; @@ -187,12 +187,18 @@ static bool SOSCircleHash(const struct ccdigest_info *di, SOSCircleRef circle, v } static bool SOSCircleHashNextGenWithAdditionalPeer(const struct ccdigest_info *di, SOSCircleRef circle, SOSPeerInfoRef additionalPeer, void *hash_result, CFErrorRef *error) { + bool result = false; CFMutableSetRef peers = CFSetCreateMutableCopy(NULL, 0, circle->peers); CFSetAddValue(peers, additionalPeer); SOSGenCountRef nextGen = SOSGenerationIncrementAndCreate(circle->generation); - return SOSCircleHashGenAndPeers(di, nextGen, peers, hash_result, error); + result = SOSCircleHashGenAndPeers(di, nextGen, peers, hash_result, error); + + CFReleaseNull(nextGen); + CFReleaseNull(peers); + + return result; } bool SOSCircleSetSignature(SOSCircleRef circle, SecKeyRef pubkey, CFDataRef signature, CFErrorRef *error) { @@ -299,7 +305,6 @@ static bool SOSCircleConcordanceRingSign(SOSCircleRef circle, SecKeyRef privKey, bool SOSCircleVerifySignatureExists(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error) { if(!pubKey) { - // TODO ErrorRef secerror("SOSCircleVerifySignatureExists no pubKey"); SOSCreateError(kSOSErrorBadFormat, CFSTR("SOSCircleVerifySignatureExists no pubKey"), (error != NULL) ? *error : NULL, error); return false; @@ -308,6 +313,13 @@ bool SOSCircleVerifySignatureExists(SOSCircleRef circle, SecKeyRef pubKey, CFErr return NULL != signature; } +CFStringRef SOSCircleCopyHashString(SOSCircleRef circle) { + const struct ccdigest_info *di = ccsha256_di(); + uint8_t hash_result[di->output_size]; + SOSCircleHash(di, circle, hash_result, NULL); + return SOSCopyHashBufAsString(hash_result, sizeof(hash_result)); +} + bool SOSCircleVerify(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error) { const struct ccdigest_info *di = ccsha256_di(); uint8_t hash_result[di->output_size]; @@ -321,11 +333,21 @@ bool SOSCircleVerify(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error) { CFDataGetBytePtr(signature), CFDataGetLength(signature)), error, CFSTR("Signature verification failed."));; } +bool SOSCircleVerifyPeerSignatureExists(SOSCircleRef circle, SOSPeerInfoRef peer) { + bool result = false; + SecKeyRef pub_key = SOSPeerInfoCopyPubKey(peer, NULL); + require_quiet(pub_key, fail); + result = SOSCircleVerifySignatureExists(circle, pub_key, NULL); +fail: + CFReleaseSafe(pub_key); + return result; +} + bool SOSCircleVerifyPeerSigned(SOSCircleRef circle, SOSPeerInfoRef peer, CFErrorRef *error) { bool result = false; SecKeyRef pub_key = SOSPeerInfoCopyPubKey(peer, error); require_quiet(pub_key, fail); - + result = SOSCircleVerify(circle, pub_key, error); fail: CFReleaseSafe(pub_key); @@ -1463,7 +1485,7 @@ bool SOSCircleAcceptPeerFromHSA2(SOSCircleRef circle, SecKeyRef userKey, SOSGenC static inline void logPeerInfo(char *category, SOSCircleRef circle, SecKeyRef pubKey, CFStringRef myPID, SOSPeerInfoRef peer) { char sigchr = 'v'; - if (SOSCircleVerifyPeerSigned(circle, peer, NULL)) { + if (SOSCircleVerifyPeerSignatureExists(circle, peer)) { sigchr = 'V'; } SOSPeerInfoLogState(category, peer, pubKey, myPID, sigchr); @@ -1473,7 +1495,7 @@ void SOSCircleLogState(char *category, SOSCircleRef circle, SecKeyRef pubKey, CF if(!circle) return; CFStringRef genString = SOSGenerationCountCopyDescription(SOSCircleGetGeneration(circle)); char sigchr = 'v'; - if(pubKey && SOSCircleVerify(circle, pubKey, NULL)) { + if(pubKey && SOSCircleVerifySignatureExists(circle, pubKey, NULL)) { sigchr = 'V'; } secnotice(category, "CIRCLE: [%20@] UserSigned: %c", genString, sigchr); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h index 9de6fb18..4ef6fddd 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h @@ -52,11 +52,14 @@ SOSCircleRef SOSCircleCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error, SOSCircleRef SOSCircleCreateFromData(CFAllocatorRef allocator, CFDataRef circleData, CFErrorRef *error); SOSCircleRef SOSCircleCopyCircle(CFAllocatorRef allocator, SOSCircleRef otherCircle, CFErrorRef *error); +CFStringRef SOSCircleCopyHashString(SOSCircleRef circle); + bool SOSCircleSetSignature(SOSCircleRef circle, SecKeyRef pubkey, CFDataRef signature, CFErrorRef *error); CFDataRef SOSCircleGetSignature(SOSCircleRef circle, SecKeyRef pubkey, CFErrorRef *error); CFDictionaryRef SOSCircleCopyAllSignatures(SOSCircleRef circle); bool SOSCircleSign(SOSCircleRef circle, SecKeyRef privkey, CFErrorRef *error); bool SOSCircleVerifySignatureExists(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error); +bool SOSCircleVerifyPeerSignatureExists(SOSCircleRef circle, SOSPeerInfoRef peer); bool SOSCircleVerify(SOSCircleRef circle, SecKeyRef pubkey, CFErrorRef *error); bool SOSCircleVerifyPeerSigned(SOSCircleRef circle, SOSPeerInfoRef peer, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h index ba1ecd99..6a03d184 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h @@ -39,6 +39,7 @@ #include #include +#import __BEGIN_DECLS @@ -117,6 +118,7 @@ bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CF */ bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); +bool SOSCCSetUserCredentialsAndDSIDWithAnalytics(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentevent, CFErrorRef *error); /*! @function SOSCCTryUserCredentials @@ -134,20 +136,6 @@ bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CF */ bool SOSCCTryUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); -/*! - @function SOSCCCopyDeviceID - @abstract Retrieves this device's IDS device ID - @param error What went wrong if we returned false - */ -CFStringRef SOSCCCopyDeviceID(CFErrorRef* error); - -/*! - @function SOSCCSetDeviceID - @abstract Sets this device's IDS device ID - @param IDS The ID to set - @param error What went wrong if we returned false - */ -bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error); /*! @function SOSCCRegisterUserCredentials @@ -162,6 +150,7 @@ bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_passwor @return if we waited successfully */ bool SOSCCWaitForInitialSync(CFErrorRef* error); +bool SOSCCWaitForInitialSyncWithAnalytics(CFDataRef parentEvent, CFErrorRef* error); /*! @function SOSCCCopyYetToSyncViewsList @@ -188,6 +177,15 @@ bool SOSCCCanAuthenticate(CFErrorRef *error); */ SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef* error); +/*! + @function SOSCCThisDeviceIsInCircleNonCached + @abstract Finds and returns if this devices status in the user's circle. This call is added explicitly for CDP. + @param error What went wrong if we returned kSOSCCError. + @result kSOSCCInCircle if we're in the circle. + @discussion If we have an error figuring out if we're in the circle we return false and the error. + */ +SOSCCStatus SOSCCThisDeviceIsInCircleNonCached(CFErrorRef* error); + /*! @function SOSCCIsIcloudKeychainSyncing @abstract determines whether baseline keychain syncing is occuring (V0/V2) @@ -249,6 +247,8 @@ bool SOSCCIsContinuityUnlockSyncing(void); @discussion Requests to join the user's circle or all the pending circles (other than his) if there are multiple pending circles. */ bool SOSCCRequestToJoinCircle(CFErrorRef* error); +bool SOSCCRequestToJoinCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error); + /*! @function SOSCCRequestToJoinCircleAfterRestore @@ -258,6 +258,7 @@ bool SOSCCRequestToJoinCircle(CFErrorRef* error); @discussion Uses the cloud identity to get in the circle if it can. If it cannot it falls back on simple application. */ bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error); +bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics(CFDataRef parentEvent, CFErrorRef* error); /*! @function SOSCCRequestEnsureFreshParameters @@ -290,6 +291,7 @@ bool SOSCCResetToOffering(CFErrorRef* error); @result true if we posted the circle successfully. False if there was an error. */ bool SOSCCResetToEmpty(CFErrorRef* error); +bool SOSCCResetToEmptyWithAnalytics(CFDataRef parentEvent, CFErrorRef* error); /*! @function SOSCCRemoveThisDeviceFromCircle @@ -300,6 +302,8 @@ bool SOSCCResetToEmpty(CFErrorRef* error); */ bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error); +bool SOSCCRemoveThisDeviceFromCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error); + /*! @function SOSCCRemoveThisDeviceFromCircle @abstract Removes a list of peers from the circle. @@ -310,6 +314,7 @@ bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error); that we don't have the user credentail (need to prompt for password) */ bool SOSCCRemovePeersFromCircle(CFArrayRef peerList, CFErrorRef* error); +bool SOSCCRemovePeersFromCircleWithAnalytics(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error); /*! @function SOSCCRemoveThisDeviceFromCircle @@ -444,14 +449,6 @@ bool SOSCCRejectApplicants(CFArrayRef applicants, CFErrorRef *error); */ CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error); -/*! - @function SOSCCCheckPeerAvailability - @abstract Prompts KeychainSyncingOverIDSProxy to query all devices in the circle with the same view. - @param error What went wrong. - @result true if the operation succeeded, otherwise false. - */ -bool SOSCCCheckPeerAvailability(CFErrorRef *error); - /* * Return values for SOSCCGetLastDepartureReason */ @@ -564,6 +561,7 @@ extern const CFStringRef kCKKSViewManatee; extern const CFStringRef kCKKSViewAutoUnlock; extern const CFStringRef kCKKSViewHealth; extern const CFStringRef kCKKSViewApplePay; +extern const CFStringRef kCKKSViewHome; /*! @@ -607,44 +605,13 @@ SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode action, CFErrorR */ bool SOSCCViewSet(CFSetRef enabledviews, CFSetRef disabledviews); - +bool SOSCCViewSetWithAnalytics(CFSetRef enabledviews, CFSetRef disabledviews, CFDataRef parentEvent); /* Security Attributes for PeerInfos Initial View List - To be expanded */ -extern const CFStringRef kSOSSecPropertyHasEntropy; -extern const CFStringRef kSOSSecPropertyScreenLock; -extern const CFStringRef kSOSSecPropertySEP; -extern const CFStringRef kSOSSecPropertyIOS; - - -/*! - @function SOSCCSecurityProperty - @abstract Enable, disable or query status of a SecurityProperty for this peer. - @param property The SecurityProperty for which the action should be performed. - @param action The action code to take with the SecurityProperty - @param error More description of the error if one occurred. - @discussion - For all actions any error return can fallback to kSOSCCGeneralSecurityPropertyError. - For kSOSCCSecurityPropertyEnable actions other possible return codes are: - kSOSCCSecurityPropertyValid if the operation was successful and the peer's SecurityProperty is valid - kSOSCCSecurityPropertyNotValid if the operation was unsuccessful - kSOSCCSecurityPropertyNotQualified if the device can't support prerequisite security capabilities - kSOSCCNoSuchSecurityProperty if the CFStringRef doesn't match one of the known SecurityProperties - - For kSOSCCSecurityPropertyDisable actions other possible return codes are: - kSOSCCSecurityPropertyNotMember for successfully disabling the SecurityProperty - kSOSCCNoSuchSecurityProperty if the CFStringRef doesn't match one of the known SecurityProperties - - For kSOSCCSecurityPropertyQuery actions other possible return codes are: - kSOSCCSecurityPropertyValid or kSOSCCDSNotValidMember for successful querying of the status for a SecurityProperty for this peer - kSOSCCNoSuchSecurityProperty if the CFStringRef doesn't match one of the known SecurityProperties - - */ - -SOSSecurityPropertyResultCode SOSCCSecurityProperty(CFStringRef property, SOSSecurityPropertyActionCode action, CFErrorRef *error); // // Backup APIs diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m index 1e006242..266de197 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m @@ -85,23 +85,34 @@ static bool xpc_dictionary_entry_is_type(xpc_object_t dictionary, const char *ke } SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef *error) +{ + SOSCCStatus retval = SOSGetCachedCircleStatus(error); + if(retval != kSOSNoCachedValue) { + secnotice("circleOps", "Retrieved cached circle value %d", retval); + return retval; + } + return SOSCCThisDeviceIsInCircleNonCached(error); +} + + +SOSCCStatus SOSCCThisDeviceIsInCircleNonCached(CFErrorRef *error) { sec_trace_enter_api(NULL); sec_trace_return_api(SOSCCStatus, ^{ SOSCCStatus result = kSOSCCError; - + do_if_registered(soscc_ThisDeviceIsInCircle, error); - + xpc_object_t message = securityd_create_message(kSecXPCOpDeviceInCircle, error); if (message) { xpc_object_t response = securityd_message_with_reply_sync(message, error); - + if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) { result = (SOSCCStatus) xpc_dictionary_get_int64(response, kSecXPCKeyResult); } else { result = kSOSCCError; } - + if (result < 0) { if (response && securityd_message_no_error(response, error)) { @@ -111,11 +122,26 @@ SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef *error) } } } - + secnotice("circleOps", "Retrieved non-cached circle value %d", result); + return result; }, CFSTR("SOSCCStatus=%d")) } +static bool sfsigninanalytics_bool_error_request(enum SecXPCOperation op, CFDataRef parentEvent, CFErrorRef* error) +{ + __block bool result = false; + + secdebug("sosops","enter - operation: %d", op); + securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { + return SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error); + }, ^bool(xpc_object_t response, __unused CFErrorRef *error) { + result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); + return result; + }); + return result; +} + static bool cfstring_to_error_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error) { __block bool result = false; @@ -137,25 +163,6 @@ static bool cfstring_to_error_request(enum SecXPCOperation op, CFStringRef strin return result; } -static bool deviceid_to_bool_error_request(enum SecXPCOperation op, - CFStringRef IDS, - CFErrorRef* error) -{ - __block bool result = false; - - securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { - CFStringPerformWithCString(IDS, ^(const char *utf8Str) { - xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str); - }); - return true; - }, ^bool(xpc_object_t response, CFErrorRef *error) { - result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); - return result; - }); - - return result; -} - static SOSRingStatus cfstring_to_uint64_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error) { __block bool result = false; @@ -523,6 +530,24 @@ static bool info_array_to_bool_error_request(enum SecXPCOperation op, CFArrayRef return result; } +static bool info_array_data_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFDataRef parentEvent, CFErrorRef* error) +{ + __block bool result = false; + + secdebug("sosops", "enter - operation: %d", op); + securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { + SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error); + xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error); + if (encoded_peers) + xpc_dictionary_set_value(message, kSecXPCKeyPeerInfoArray, encoded_peers); + return encoded_peers != NULL; + }, ^bool(xpc_object_t response, __unused CFErrorRef *error) { + result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); + return result; + }); + return result; +} + static bool uint64_t_to_bool_error_request(enum SecXPCOperation op, uint64_t number, CFErrorRef* error) @@ -640,6 +665,16 @@ bool SOSCCRequestToJoinCircle(CFErrorRef* error) }, NULL) } +bool SOSCCRequestToJoinCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error) +{ + sec_trace_enter_api(NULL); + sec_trace_return_bool_api(^{ + do_if_registered(soscc_RequestToJoinCircleWithAnalytics, parentEvent, error); + + return sfsigninanalytics_bool_error_request(kSecXPCOpRequestToJoinWithAnalytics, parentEvent, error); + }, NULL) +} + bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error) { sec_trace_enter_api(NULL); @@ -650,9 +685,19 @@ bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error) }, NULL) } +bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics(CFDataRef parentEvent, CFErrorRef* error) +{ + sec_trace_enter_api(NULL); + sec_trace_return_bool_api(^{ + do_if_registered(soscc_RequestToJoinCircleAfterRestoreWithAnalytics, parentEvent, error); + + return sfsigninanalytics_bool_error_request(kSecXPCOpRequestToJoinAfterRestoreWithAnalytics, parentEvent, error); + }, NULL) +} + bool SOSCCAccountHasPublicKey(CFErrorRef *error) { - + // murfxx sec_trace_enter_api(NULL); sec_trace_return_bool_api(^{ do_if_registered(soscc_AccountHasPublicKey, error); @@ -672,6 +717,16 @@ bool SOSCCAccountIsNew(CFErrorRef *error) }, NULL) } +bool SOSCCWaitForInitialSyncWithAnalytics(CFDataRef parentEvent, CFErrorRef* error) +{ + sec_trace_enter_api(NULL); + sec_trace_return_bool_api(^{ + do_if_registered(soscc_WaitForInitialSyncWithAnalytics, parentEvent, error); + + return sfsigninanalytics_bool_error_request(kSecXPCOpWaitForInitialSyncWithAnalytics, parentEvent, error); + }, NULL) +} + bool SOSCCWaitForInitialSync(CFErrorRef* error) { sec_trace_enter_api(NULL); @@ -783,6 +838,16 @@ bool SOSCCResetToEmpty(CFErrorRef* error) }, NULL) } +bool SOSCCResetToEmptyWithAnalytics(CFDataRef parentEvent, CFErrorRef* error) +{ + secwarning("SOSCCResetToEmptyWithAnalytics called"); + sec_trace_enter_api(NULL); + sec_trace_return_bool_api(^{ + do_if_registered(soscc_ResetToEmptyWithAnalytics, parentEvent, error); + + return sfsigninanalytics_bool_error_request(kSecXPCOpResetToEmptyWithAnalytics, parentEvent, error); + }, NULL) +} bool SOSCCRemovePeersFromCircle(CFArrayRef peers, CFErrorRef* error) { sec_trace_enter_api(NULL); @@ -793,6 +858,26 @@ bool SOSCCRemovePeersFromCircle(CFArrayRef peers, CFErrorRef* error) }, NULL) } +bool SOSCCRemovePeersFromCircleWithAnalytics(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error) +{ + sec_trace_enter_api(NULL); + sec_trace_return_bool_api(^{ + do_if_registered(soscc_RemovePeersFromCircleWithAnalytics, peers, parentEvent, error); + + return info_array_data_to_bool_error_request(kSecXPCOpRemovePeersFromCircleWithAnalytics, peers, parentEvent, error); + }, NULL) +} + +bool SOSCCRemoveThisDeviceFromCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error) +{ + sec_trace_enter_api(NULL); + sec_trace_return_bool_api(^{ + do_if_registered(soscc_RemoveThisDeviceFromCircleWithAnalytics, parentEvent, error); + + return sfsigninanalytics_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics, parentEvent, error); + }, NULL) +} + bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error) { sec_trace_enter_api(NULL); @@ -1133,7 +1218,7 @@ static bool label_and_password_to_bool_error_request(enum SecXPCOperation op, static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op, CFStringRef user_label, CFDataRef user_password, - CFStringRef dsid, CFErrorRef* error) + CFStringRef dsid, CFDataRef parentEvent, CFErrorRef* error) { __block bool result = false; @@ -1145,82 +1230,10 @@ static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperati xpc_dictionary_set_string(message, kSecXPCKeyDSID, utr8StrDSID); }); xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password)); - return true; - }, ^bool(xpc_object_t response, __unused CFErrorRef *error) { - result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); - return result; - }); - - return result; -} - -static bool cfstring_to_bool_error_request(enum SecXPCOperation op, - CFStringRef string, - CFErrorRef* error) -{ - __block bool result = false; - - securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { - CFStringPerformWithCString(string, ^(const char *utf8Str) { - xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str); - }); - return true; - }, ^bool(xpc_object_t response, CFErrorRef *error) { - result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); - return result; - }); - - return result; -} - -static int idsDict_to_int_error_request(enum SecXPCOperation op, - CFDictionaryRef IDS, - CFErrorRef* error) -{ - __block int result = 0; - - securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { - SecXPCDictionarySetPListOptional(message, kSecXPCKeyIDSMessage, IDS, error); - return true; - }, ^bool(xpc_object_t response, __unused CFErrorRef *error) { - int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult); - if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) { - result = (int)temp_result; + if(parentEvent){ + SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error); } return true; - }); - - return result; -} - -static bool idsData_peerID_to_bool_error_request(enum SecXPCOperation op, CFStringRef peerID, - CFDataRef IDSMessage, - CFErrorRef* error) -{ - __block bool result = 0; - - securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { - SecXPCDictionarySetData(message, kSecXPCKeyIDSMessage, IDSMessage, error); - SecXPCDictionarySetString(message, kSecXPCKeyDeviceID, peerID, error); - return true; - }, ^bool(xpc_object_t response, CFErrorRef *error) { - result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); - return result; - }); - return result; -} - -static bool idscommand_to_bool_error_request(enum SecXPCOperation op, - CFStringRef idsMessage, - CFErrorRef* error) -{ - __block bool result = false; - - securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { - CFStringPerformWithCString(idsMessage, ^(const char *utf8Str) { - xpc_dictionary_set_string(message, kSecXPCKeySendIDSMessage, utf8Str); - }); - return true; }, ^bool(xpc_object_t response, __unused CFErrorRef *error) { result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); return result; @@ -1262,93 +1275,33 @@ bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_passw if(account_dsid == NULL){ account_dsid = CFSTR(""); } - return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, account_dsid, error); + return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, account_dsid, nil, error); out: return result; }, NULL) } - -bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error) -{ - secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS); - sec_trace_enter_api(NULL); - sec_trace_return_bool_api(^{ - do_if_registered(soscc_SetDeviceID, IDS, error); - bool result = cfstring_to_bool_error_request(kSecXPCOpSetDeviceID, IDS, error); - return result; - }, NULL) -} - -bool SOSCCIDSServiceRegistrationTest(CFStringRef message, CFErrorRef *error) -{ - secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message); - sec_trace_enter_api(NULL); - sec_trace_return_bool_api(^{ - do_if_registered(soscc_CheckIDSRegistration, message, error); - return idscommand_to_bool_error_request(kSecXPCOpSendIDSMessage, message, error); - }, NULL) -} - -bool SOSCCIDSPingTest(CFStringRef message, CFErrorRef *error) -{ - secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message); - sec_trace_enter_api(NULL); - sec_trace_return_bool_api(^{ - do_if_registered(soscc_PingTest, message, error); - return idscommand_to_bool_error_request(kSecXPCOpPingTest, message, error); - }, NULL) -} - -bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef *error) +bool SOSCCSetUserCredentialsAndDSIDWithAnalytics(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error) { - secnotice("sosops", "SOSCCIDSDeviceIDIsAvailableTest!!\n"); - sec_trace_enter_api(NULL); + secnotice("circleOps", "SOSCCSetUserCredentialsAndDSIDWithAnalytics for %@\n", user_label); + sec_trace_enter_api(CFSTR("user_label=%@"), user_label); sec_trace_return_bool_api(^{ - do_if_registered(soscc_GetIDSIDFromIDS, error); - return simple_bool_error_request(kSecXPCOpIDSDeviceID, error); - }, NULL) -} - -HandleIDSMessageReason SOSCCHandleIDSMessage(CFDictionaryRef IDS, CFErrorRef* error) -{ - secnotice("sosops", "SOSCCHandleIDSMessage!! %@\n", IDS); - sec_trace_enter_api(NULL); - sec_trace_return_api(HandleIDSMessageReason, ^{ - do_if_registered(soscc_HandleIDSMessage, IDS, error); - return (HandleIDSMessageReason) idsDict_to_int_error_request(kSecXPCOpHandleIDSMessage, IDS, error); - }, NULL) -} + do_if_registered(soscc_SetUserCredentialsAndDSIDWithAnalytics, user_label, user_password, dsid, parentEvent, error); -bool SOSCCClearPeerMessageKeyInKVS(CFStringRef peerID, CFErrorRef *error) -{ - secnotice("sosops", "SOSCCClearPeerMessageKeyInKVS!! %@\n", peerID); - sec_trace_enter_api(NULL); - sec_trace_return_bool_api(^{ - do_if_registered(socc_clearPeerMessageKeyInKVS, peerID, error); - return cfstring_to_bool_error_request(kSecXPCOpClearKVSPeerMessage, peerID, error); - }, NULL) + bool result = false; + __block CFStringRef account_dsid = dsid; -} + require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil"))); + require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil"))); -bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(CFStringRef peerID, CFErrorRef *error) -{ - secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVSUsingIDOnly!! %@\n", peerID); - sec_trace_enter_api(NULL); - sec_trace_return_bool_api(^{ - do_if_registered(soscc_requestSyncWithPeerOverKVSIDOnly, peerID, error); - return deviceid_to_bool_error_request(kSecXPCOpSyncWithKVSPeerIDOnly, peerID, error); - }, NULL) -} + if(account_dsid == NULL){ + account_dsid = CFSTR(""); + } + return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics, user_label, user_password, account_dsid, parentEvent, error); + out: + return result; -bool SOSCCRequestSyncWithPeerOverKVS(CFStringRef peerID, CFDataRef message, CFErrorRef *error) -{ - secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVS!! %@\n", peerID); - sec_trace_enter_api(NULL); - sec_trace_return_bool_api(^{ - do_if_registered(soscc_requestSyncWithPeerOverKVS, peerID, message, error); - return idsData_peerID_to_bool_error_request(kSecXPCOpSyncWithKVSPeer, peerID, message, error); }, NULL) } @@ -1366,7 +1319,7 @@ static bool SOSCCTryUserCredentialsAndDSID_internal(CFStringRef user_label, CFDa account_dsid = CFSTR(""); } - return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, account_dsid, error); + return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, account_dsid, nil, error); out: return result; @@ -1442,16 +1395,6 @@ CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef* error) { }, NULL) } -CFStringRef SOSCCCopyDeviceID(CFErrorRef* error) -{ - sec_trace_enter_api(NULL); - sec_trace_return_api(CFStringRef, ^{ - do_if_registered(soscc_CopyDeviceID, error); - CFStringRef deviceID = simple_cfstring_error_request(kSecXPCOpRequestDeviceID, error); - return deviceID; - }, NULL) -} - bool SOSCCProcessEnsurePeerRegistration(CFErrorRef* error){ secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration"); sec_trace_enter_api(NULL); @@ -1551,6 +1494,22 @@ static int64_t name_action_to_code_request(enum SecXPCOperation op, uint16_t err } SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode actionCode, CFErrorRef *error) { + if(actionCode == kSOSCCViewQuery) { + uint64_t circleStat = SOSGetCachedCircleBitmask(); + if(circleStat & CC_STATISVALID) { + SOSViewResultCode retval = kSOSCCViewNotMember; + CFSetRef enabledViews = SOSCreateCachedViewStatus(); + if(enabledViews) { + if(CFSetContainsValue(enabledViews, view)) { + retval = kSOSCCViewMember; + } else { + retval = kSOSCCViewNotMember; + } + CFReleaseNull(enabledViews); + } + return retval; + } + } sec_trace_enter_api(NULL); sec_trace_return_api(SOSViewResultCode, ^{ do_if_registered(soscc_View, view, actionCode, error); @@ -1580,38 +1539,25 @@ bool SOSCCViewSet(CFSetRef enabledViews, CFSetRef disabledViews) { }, NULL) } -SOSSecurityPropertyResultCode SOSCCSecurityProperty(CFStringRef property, SOSSecurityPropertyActionCode actionCode, CFErrorRef *error) { +bool SOSCCViewSetWithAnalytics(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent) { + CFErrorRef *error = NULL; + __block bool result = false; + sec_trace_enter_api(NULL); - sec_trace_return_api(SOSSecurityPropertyResultCode, ^{ - SOSSecurityPropertyResultCode result = kSOSCCGeneralSecurityPropertyError; - do_if_registered(soscc_SecurityProperty, property, actionCode, error); - xpc_object_t message = securityd_create_message(kSecXPCOpSecurityProperty, error); - if (message) { - int64_t bigac = actionCode; - xpc_dictionary_set_string(message, kSecXPCKeyViewName, CFStringGetCStringPtr(property, kCFStringEncodingUTF8)); - xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, bigac); - - xpc_object_t response = securityd_message_with_reply_sync(message, error); - - if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) { - result = (SOSSecurityPropertyResultCode) xpc_dictionary_get_int64(response, kSecXPCKeyResult); - } - - if (result == kSOSCCGeneralSecurityPropertyError) { - if (response && securityd_message_no_error(response, error)) { - char *desc = xpc_copy_description(response); - SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc); - free((void *)desc); - } - } - if(response) - response = nil; - if(message) - message = nil; - } - - return result; - }, CFSTR("SOSSecurityPropertyResultCode=%d")) + sec_trace_return_bool_api(^{ + do_if_registered(soscc_ViewSetWithAnalytics, enabledViews, disabledViews, parentEvent); + return securityd_send_sync_and_do(kSecXPCOpViewSetWithAnalytics, error, ^bool(xpc_object_t message, CFErrorRef *error) { + xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error); + xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error); + if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc); + if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc); + if(parentEvent) SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error); + return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ; + }, ^bool(xpc_object_t response, __unused CFErrorRef *error) { + result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); + return result; + }); + }, NULL) } static CFStringRef copyViewNames(size_t n, CFStringRef *views) { @@ -1638,6 +1584,24 @@ static bool sosIsViewSetSyncing(size_t n, CFStringRef *views) { } if(retval == true) { + //murfxx + // use cached values if valid + uint64_t circleStat = SOSGetCachedCircleBitmask(); + if(circleStat & CC_STATISVALID) { + CFSetRef enabledViews = SOSCreateCachedViewStatus(); + if(enabledViews) { + for(size_t i = 0; i < n; i++) { + if(!CFSetContainsValue(enabledViews, views[i])) { + retval = false; + } + } + CFReleaseNull(enabledViews); + CFReleaseNull(viewString); + return retval; + } + } + + // make the individual calls otherwise. for(size_t i = 0; i < n; i++) { SOSViewResultCode vstatus = SOSCCView(views[i], kSOSCCViewQuery, &error); if(vstatus != kSOSCCViewMember) { @@ -1717,18 +1681,6 @@ CFDictionaryRef SOSCCCopyBackupInformation(CFErrorRef *error) { }, CFSTR("return=%@")) } -bool SOSCCCheckPeerAvailability(CFErrorRef *error){ - secnotice("peer", "enter SOSCCCheckPeerAvailability"); - sec_trace_enter_api(NULL); - sec_trace_return_bool_api(^{ - do_if_registered(soscc_PeerAvailability, error); - - return simple_bool_error_request(kSecXPCOpCheckPeerAvailability, error); - }, NULL) - -} - - bool SOSWrapToBackupSliceKeyBagForView(CFStringRef viewName, CFDataRef input, CFDataRef* output, CFDataRef* bskbEncoded, CFErrorRef* error) { sec_trace_enter_api(NULL); sec_trace_return_bool_api(^{ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h index 5a0e01f0..1ed5dde6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h @@ -58,14 +58,6 @@ CFStringRef SOSCCGetViewResultDescription(SOSViewResultCode vrc); bool SOSCCAccountHasPublicKey(CFErrorRef *error); bool SOSCCAccountIsNew(CFErrorRef *error); -/*! - @function SOSCCHandleIDSMessage - @abstract Handles an IDS message from KeychainSyncingOverIDSProxy - @param IDS The incoming IDS message - @param error What went wrong if we returned false - */ -HandleIDSMessageReason SOSCCHandleIDSMessage(CFDictionaryRef IDS, CFErrorRef* error); - /*! @function SOSCCProcessSyncWithPeers @abstract Returns the peers for whom we handled syncing from the list send to us. @@ -101,29 +93,6 @@ bool SOSCCCleanupKVSKeys(CFErrorRef *error); */ SOSPeerInfoRef SOSCCCopyMyPeerInfo(CFErrorRef *error); -/*! - @function SOSCCIDSServiceRegistrationTest - @abstract Attempts to send a message over IDS to test IDS service set up - @param message The message to send over IDS - @param error What went wrong if we returned false - */ -bool SOSCCIDSServiceRegistrationTest(CFStringRef message, CFErrorRef *error); - -/*! - @function SOSCCIDSPingTest - @abstract Attempts to ping devices within an IDS Account, check device availability - @param message The message to send over IDS - @param error What went wrong if we returned false - */ -bool SOSCCIDSPingTest(CFStringRef message, CFErrorRef *error); - -/*! - @function SOSCCIDSDeviceIDIsAvailableTest - @abstract Attempts to communicate with KeychainSyncingOverIDSProxy to retrieve the device ID using IDS framework - @param error What went wrong if we returned false - */ -bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef *error); - /*! @function SOSWrapToBackupSliceKeyBagForView @abstract Encrypts the given plaintext, and wraps the encryption key to the backup slice keybag for this view @@ -142,11 +111,8 @@ CFDataRef SOSCCCopyAccountState(CFErrorRef* error); bool SOSCCDeleteAccountState(CFErrorRef *error); CFDataRef SOSCCCopyEngineData(CFErrorRef* error); bool SOSCCDeleteEngineState(CFErrorRef *error); -bool SOSCCRequestSyncWithPeerOverKVS( CFStringRef peerID, CFDataRef message, CFErrorRef *error); -bool SOSCCClearPeerMessageKeyInKVS(CFStringRef peerID, CFErrorRef *error); CFDataRef SOSCCCopyRecoveryPublicKey(CFErrorRef *error); CFDictionaryRef SOSCCCopyBackupInformation(CFErrorRef *error); -bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(CFStringRef peerID, CFErrorRef *error); bool SOSCCTestPopulateKVSWithBadKeys(CFErrorRef *error); CFDataRef SOSCCCopyInitialSyncData(CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m index 237e7b13..c6e92c90 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m @@ -78,11 +78,6 @@ [self.account kvsPerformanceCounters:reply]; } -- (void)idsPerformanceCounters:(void(^)(NSDictionary *))reply -{ - [self.account idsPerformanceCounters:reply]; -} - - (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary *))reply { [self.account rateLimitingPerformanceCounters:reply]; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.c b/OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.c index cf9749a6..41449d59 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.c +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.c @@ -104,11 +104,14 @@ static void SOSDigestVectorUnique(struct SOSDigestVector *dv) { dest += prev - source; // 2) Skip remaining dupes if (cur < end) { - while (cur += SOSDigestSize, cur < end) { + cur += SOSDigestSize; + while (cur < end) { int delta = SOSDigestCompare(prev, cur); assert(delta <= 0); - if (delta != 0) + if (delta != 0) { break; + } + cur += SOSDigestSize; } } // cur now points to the first new element that hasn't yet been copied diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c b/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c index 0730e7f9..672ebed2 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c @@ -545,6 +545,8 @@ static CFDataRef SOSEngineCopyCoders(SOSEngineRef engine, CFErrorRef *error) { return der; } +#pragma clang diagnostic push +#pragma clang diagnostic fatal "-Wshadow" static bool SOSEngineSaveCoders(SOSEngineRef engine, SOSTransactionRef txn, CFErrorRef *error) { // MUST hold engine lock // Device must be unlocked for this to succeed @@ -556,7 +558,7 @@ static bool SOSEngineSaveCoders(SOSEngineRef engine, SOSTransactionRef txn, CFEr bool ok = true; if (engine->codersNeedSaving) { CFDataRef derCoders = SOSEngineCopyCoders(engine, error); - bool ok = derCoders && SOSDataSourceSetStateWithKey(engine->dataSource, txn, kSOSEngineCoders, + ok = derCoders && SOSDataSourceSetStateWithKey(engine->dataSource, txn, kSOSEngineCoders, kSOSEngineProtectionDomainClassA, derCoders, error); if (ok) { engine->codersNeedSaving = false; @@ -566,6 +568,7 @@ static bool SOSEngineSaveCoders(SOSEngineRef engine, SOSTransactionRef txn, CFEr } return ok; } +#pragma clang diagnostic pop bool SOSTestEngineSaveCoders(CFTypeRef engine, SOSTransactionRef txn, CFErrorRef *error){ return SOSEngineSaveCoders((SOSEngineRef)engine, txn, error); @@ -1461,7 +1464,7 @@ static void SOSEngineReferenceTrustedPeer(SOSEngineRef engine, SOSPeerMetaRef pe } } -static CFDataRef SOSEngineLoadV0KeyBag(SOSEngineRef engine, CFErrorRef *error) { +static CFDataRef SOSEngineCopyV0KeyBag(SOSEngineRef engine, CFErrorRef *error) { // Return the keybag for the given peerID. /* Values for V0 are: @@ -1489,15 +1492,17 @@ static void SOSEngineReferenceBackupV0Peer(SOSEngineRef engine, CFMutableDiction SOSPeerRef backupPeer = (SOSPeerRef)CFDictionaryGetValue(engine->peerMap, kSOSViewKeychainV0_tomb); CFDataRef bag = NULL; if (backupPeer && CFGetTypeID(backupPeer) == SOSPeerGetTypeID()) { - bag = SOSPeerGetKeyBag(backupPeer); + bag = CFRetainSafe(SOSPeerGetKeyBag(backupPeer)); } else { CFErrorRef localError = NULL; - if (!(bag = SOSEngineLoadV0KeyBag(engine, &localError))) { + bag = SOSEngineCopyV0KeyBag(engine, &localError); + if (!bag) { secnotice("engine", "No keybag found for v0 backup peer: %@", localError); CFReleaseSafe(localError); } } SOSEngineReferenceBackupPeer(engine, kSOSViewKeychainV0_tomb, SOSViewsGetV0BackupViewSet(), bag, newViewNameSet2ChangeTracker, newPeerMap); + CFReleaseNull(bag); } static void SOSEngineReferenceTrustedPeers(SOSEngineRef engine, CFMutableDictionaryRef newViewNameSet2ChangeTracker, CFMutableDictionaryRef newPeerMap, CFMutableArrayRef newPeerIDs, CFArrayRef trustedPeerMetas, CFMutableStringRef desc) { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m index b32f3e01..be8a73fc 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m @@ -29,8 +29,6 @@ #import "keychain/ckks/CKKSLockStateTracker.h" #import "keychain/ckks/NSOperationCategories.h" #include -#import -#import "keychain/analytics/awd/AWDMetricIds_Keychain.h" static NSOperationQueue *backupOperationQueue; static CKKSLockStateTracker *lockStateTracker; @@ -66,7 +64,6 @@ void SOSEnsureBackupWhileUnlocked(void) { }]; [backupOperation addNullableDependency:lockStateTracker.unlockDependency]; [backupOperationQueue addOperation:backupOperation]; - AWDPostSimpleMetric(AWDMetricId_Keychain_SOSKeychainBackupFailed); } } } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in b/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in index d55aa5a2..0de67ba6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in @@ -14,15 +14,12 @@ _SOSCCAccountIsNew _SOSCCAccountSetToNew _SOSCCBailFromCircle_BestEffort _SOSCCCanAuthenticate -_SOSCCCheckPeerAvailability -_SOSCCClearPeerMessageKeyInKVS _SOSCCCopyAccountState _SOSCCCopyApplicantPeerInfo _SOSCCCopyApplication _SOSCCCopyBackupInformation _SOSCCCopyCircleJoiningBlob _SOSCCCopyConcurringPeerPeerInfo -_SOSCCCopyDeviceID _SOSCCCopyEngineData _SOSCCCopyEscrowRecord _SOSCCCopyGenerationPeerInfo @@ -45,12 +42,6 @@ _SOSCCForEachEngineStateAsStringFromArray _SOSCCGetLastDepartureReason _SOSCCGetStatusDescription _SOSCCGetViewResultDescription -_SOSCCHandleIDSMessage -_SOSCCRequestSyncWithPeerOverKVS -_SOSCCRequestSyncWithPeerOverKVSUsingIDOnly -_SOSCCIDSDeviceIDIsAvailableTest -_SOSCCIDSPingTest -_SOSCCIDSServiceRegistrationTest _SOSCCIsAppleTVSyncing _SOSCCIsContinuityUnlockSyncing _SOSCCIsHomeKitSyncing @@ -70,28 +61,34 @@ _SOSCCRegisterSingleRecoverySecret _SOSCCRegisterUserCredentials _SOSCCRejectApplicants _SOSCCRemovePeersFromCircle +_SOSCCRemovePeersFromCircleWithAnalytics _SOSCCRemoveThisDeviceFromCircle +_SOSCCRemoveThisDeviceFromCircleWithAnalytics _SOSCCRequestEnsureFreshParameters -_SOSCCRequestSyncWithPeerOverKVS _SOSCCRequestToJoinCircle +_SOSCCRequestToJoinCircleWithAnalytics _SOSCCRequestToJoinCircleAfterRestore +_SOSCCRequestToJoinCircleAfterRestoreWithAnalytics _SOSCCResetToEmpty +_SOSCCResetToEmptyWithAnalytics _SOSCCResetToOffering -_SOSCCSecurityProperty _SOSCCSendToPeerIsPending -_SOSCCSetDeviceID _SOSCCSetEscrowRecord _SOSCCSetLastDepartureReason _SOSCCSetUserCredentials _SOSCCSetUserCredentialsAndDSID +_SOSCCSetUserCredentialsAndDSIDWithAnalytics _SOSCCSignedOut _SOSCCThisDeviceIsInCircle +_SOSCCThisDeviceIsInCircleNonCached _SOSCCTryUserCredentials _SOSCCTryUserCredentialsAndDSID _SOSCCValidateUserPublic _SOSCCView _SOSCCViewSet +_SOSCCViewSetWithAnalytics _SOSCCWaitForInitialSync +_SOSCCWaitForInitialSyncWithAnalytics _SOSCCCopyInitialSyncData _kSOSCCEngineStateCoderKey @@ -123,9 +120,6 @@ _SOSPeerInfoCopyDeviceID _SOSPeerInfoCopyEnabledViews _SOSPeerInfoCopyEncodedData _SOSPeerInfoCopyEscrowRecord -_SOSPeerInfoCopyIDSACKModelPreference -_SOSPeerInfoCopyIDSFragmentationPreference -_SOSPeerInfoCopyIDSPreference _SOSPeerInfoCopyOctagonSigningPublicKey _SOSPeerInfoCopyOctagonEncryptionPublicKey _SOSPeerInfoCopyPeerGestalt @@ -136,9 +130,7 @@ _SOSPeerInfoCopyWithEscrowRecordUpdate _SOSPeerInfoCopyWithGestaltUpdate _SOSPeerInfoCopyWithPing _SOSPeerInfoCopyWithReplacedEscrowRecords -_SOSPeerInfoCopyWithSecurityPropertyChange _SOSPeerInfoCopyWithViewsChange -_SOSPeerInfoCopyTransportType _SOSPeerInfoCopySerialNumber _SOSPeerInfoCopyOSVersion _SOSPeerInfoCreate @@ -165,7 +157,6 @@ _SOSPeerInfoGetRetirementDate _SOSPeerInfoGetTypeID _SOSPeerInfoGetVersion _SOSPeerInfoHasBackupKey -_SOSPeerInfoHasDeviceID _SOSPeerInfoHasOctagonEncryptionPubKey _SOSPeerInfoHasOctagonSigningPubKey _SOSPeerInfoInspectRetirementTicket @@ -177,18 +168,8 @@ _SOSPeerInfoLogState _SOSPeerInfoLookupGestaltValue _SOSPeerInfoPeerIDEqual _SOSPeerInfoRetireRetirementTicket -_SOSPeerInfoSecurityPropertyStatus -_SOSPeerInfoSetDeviceID -_SOSPeerInfoSetIDSACKModelPreference -_SOSPeerInfoSetIDSFragmentationPreference -_SOSPeerInfoSetIDSPreference _SOSPeerInfoSetOctagonEncryptionKey _SOSPeerInfoSetOctagonSigningKey -_SOSPeerInfoSetTransportType -_SOSPeerInfoShouldUseACKModel -_SOSPeerInfoShouldUseIDSMessageFragmentation -_SOSPeerInfoShouldUseIDSTransport -_SOSPeerInfoTransportTypeIs _SOSPeerInfoUpdateDigestWithDescription _SOSPeerInfoUpdateDigestWithPublicKeyBytes _SOSPeerInfoUpgradeSignatures @@ -197,18 +178,12 @@ _SOSPeerInfoVersionIsCurrent _SOSPeerInfoViewStatus _SOSPeerInfoWithEnabledViewSet - _SOSFullPeerInfoCreate _SOSFullPeerInfoPromoteToApplication _SOSFullPeerInfoGetPeerInfo _SOSCircleAcceptPeerFromHSA2 +_SOSFullPeerInfoUpdate -_SOSCCSetDeviceID -_SOSCCHandleIDSMessage - -_SOSCCIDSServiceRegistrationTest -_SOSCCIDSPingTest -_SOSCCIDSDeviceIDIsAvailableTest _SOSCCGetAllTheRings _SOSCCApplyToARing _SOSCCWithdrawlFromARing @@ -216,9 +191,9 @@ _SOSCCRingStatus _SOSCCEnableRing _SOSCCIsThisDeviceLastBackup -_SOSCloudKeychainSendIDSMessage _SOSCloudKeychainRemoveKeys -_SOSCloudKeychainRetrieveCountersFromIDSProxy + +_SOSCloudTransportSetDefaultTransport _CFArrayOfSOSPeerInfosSortByID _CFSetCreateMutableForSOSPeerInfosByID @@ -427,6 +402,7 @@ _SOSCircleUpdatePeerInfo _SOSCircleVerify _SOSCircleVerifyPeerSigned _SOSCircleVerifySignatureExists +_SOSCircleVerifyPeerSignatureExists _SOSCircleWithdrawRequest _debugDumpCircle @@ -451,19 +427,12 @@ _SOSFullPeerInfoPrivKeyExists _SOSFullPeerInfoPromoteToRetiredAndCopy _SOSFullPeerInfoPurgePersistentKey _SOSFullPeerInfoReplaceEscrowRecords -_SOSFullPeerInfoSecurityPropertyStatus _SOSFullPeerInfoUpdateBackupKey -_SOSFullPeerInfoUpdateDeviceID _SOSFullPeerInfoUpdateGestalt _SOSFullPeerInfoUpdateOctagonEncryptionKey _SOSFullPeerInfoUpdateOctagonSigningKey -_SOSFullPeerInfoUpdateSecurityProperty _SOSFullPeerInfoUpdateToCurrent _SOSFullPeerInfoUpdateToThisPeer -_SOSFullPeerInfoUpdateTransportAckModelPreference -_SOSFullPeerInfoUpdateTransportFragmentationPreference -_SOSFullPeerInfoUpdateTransportPreference -_SOSFullPeerInfoUpdateTransportType _SOSFullPeerInfoUpdateV2Dictionary _SOSFullPeerInfoUpdateViews _SOSFullPeerInfoUpgradeSignatures @@ -475,7 +444,6 @@ _SOSPiggyBackBlobCreateFromData _SOSPiggyBackBlobCopyEncodedData _SOSPiggyBackAddToKeychain -_SOSCloudKeychainRetrievePendingMessageFromProxy _SOSCloudKeychainClearAll _SOSCloudKeychainGetAllObjectsFromCloud _SOSCloudKeychainGetObjectsFromCloud @@ -485,8 +453,6 @@ _SOSCloudKeychainSynchronizeAndWait _SOSCloudKeychainUpdateKeys _SOSCloudCopyKVSState _SOSCloudKeychainFlush -_SOSCloudKeychainGetIDSDeviceAvailability -_SOSCloudKeychainGetIDSDeviceID _SOSCloudKeychainHandleUpdateMessage _SOSCloudKeychainHasPendingKey _SOSCloudKeychainHasPendingSyncWithPeer @@ -511,7 +477,6 @@ _SOSMessageKeyCreateFromTransportToPeer _SOSMessageKeyCreateWithCircleAndPeerInfos _SOSMessageKeyCreateWithCircleAndPeerNames _SOSMessageKeyCreateWithCircleNameAndPeerNames -_SOSMessageKeyCreateWithCircleNameAndTransportType _SOSRetirementKeyCreateWithCircleAndPeer _SOSRetirementKeyCreateWithCircleNameAndPeer _SOSRingKeyCreateWithName @@ -530,6 +495,7 @@ _GeneratePermanentECPair _SOSCopyDeviceBackupPublicKey _SOSCopyECUnwrappedData _SOSCopyECWrappedData +_SOSCopyHashBufAsString _SOSCopyIDOfDataBuffer _SOSCopyIDOfDataBufferWithLength _SOSCopyIDOfKey @@ -547,6 +513,7 @@ _SOSPerformWithUnwrappedData _SOSTransportMessageTypeIDSV2 _SOSTransportMessageTypeKVS _kSOSDSIDKey +_kSOSNoCachedValue _SOSPeerGestaltGetAnswer @@ -558,7 +525,6 @@ _SecCreateXPCObjectWithCFError _CreateXPCObjectWithCFSetRef _kSOSErrorDomain -_kSecIDSErrorDomain _kSOSKVSAccountChangedKey _kSOSKVSInitialSyncKey @@ -570,10 +536,6 @@ _kSOSKVSWroteLastKeyParams _SOSKVSKeyGetKeyType -_kSOSSecPropertyHasEntropy -_kSOSSecPropertyScreenLock -_kSOSSecPropertySEP -_kSOSSecPropertyIOS _SOSPeerInfoV2DictionaryCopyData _SOSPeerInfoV2DictionaryCopyBoolean @@ -581,6 +543,7 @@ _SOSPeerInfoV2DictionaryCopyString _SOSPeerInfoV2DictionaryCopySet _sViewsKey _sSerialNumberKey +_sMachineIDKey _sPreferIDS _sPreferIDSFragmentation _sPreferIDSACKModel @@ -590,15 +553,7 @@ _sV2DictionaryKey _sBackupKeyKey _sEscrowRecord _sTransportType -_sSecurityPropertiesKey -_kIDSOperationType -_kIDSMessageToSendKey -_kIDSMessageUniqueID -_kIDSMessageRecipientPeerID -_kIDSMessageRecipientDeviceID -_kIDSMessageUsesAckModel _SOSGenerationCountCopyDescription -_kIDSMessageSenderDeviceID _kSOSHsaCrKeyDictionary _SOSPeerInfoCopySerialNumber @@ -624,6 +579,34 @@ _der_sizeof_data_or_null _der_encode_data_or_null _der_decode_data_or_null +// Notification-based caching for clients +#if __OBJC2__ +_OBJC_CLASS_$_SOSCachedNotification +_OBJC_METACLASS_$_SOSCachedNotification +#else +.objc_class_name_SOSCachedNotification +#endif +_SOSCachedNotificationOperation +_SOSGetCachedCircleStatus +_SOSCreateCachedViewStatus +_SOSCachedViewBitmask +_SOSGetCachedCircleBitmask +_SOSPeerInfoViewBitMask +_SOSViewCreateSetFromBitmask + +_SOSCircleCopyHashString + +_kPIUserDefinedDeviceNameKey +_kPIDeviceModelNameKey +_kPIMessageProtocolVersionKey +_kPIOSVersionKey + +_sGestaltKey +_sVersionKey +_SOSGestaltSerial + +__SOSControlSetupInterface + #if !(TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h index 096c0128..83cdfcdf 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h @@ -109,19 +109,13 @@ uint8_t* SOSFullPeerInfoEncodeToDER(SOSFullPeerInfoRef peer, CFErrorRef* erro CFDataRef SOSFullPeerInfoCopyEncodedData(SOSFullPeerInfoRef peer, CFAllocatorRef allocator, CFErrorRef *error); -bool SOSFullPeerInfoUpdateTransportType(SOSFullPeerInfoRef peer, CFStringRef transportType, CFErrorRef* error); -bool SOSFullPeerInfoUpdateDeviceID(SOSFullPeerInfoRef peer, CFStringRef deviceID, CFErrorRef* error); -bool SOSFullPeerInfoUpdateTransportPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error); -bool SOSFullPeerInfoUpdateTransportFragmentationPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error); -bool SOSFullPeerInfoUpdateTransportAckModelPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error); - bool SOSFullPeerInfoUpdateOctagonSigningKey(SOSFullPeerInfoRef peer, SecKeyRef octagonSigningKey, CFErrorRef* error); bool SOSFullPeerInfoUpdateOctagonEncryptionKey(SOSFullPeerInfoRef peer, SecKeyRef octagonEncryptionKey, CFErrorRef* error); -SOSSecurityPropertyResultCode SOSFullPeerInfoUpdateSecurityProperty(SOSFullPeerInfoRef peer, SOSViewActionCode action, CFStringRef property, CFErrorRef* error); -SOSSecurityPropertyResultCode SOSFullPeerInfoSecurityPropertyStatus(SOSFullPeerInfoRef peer, CFStringRef property, CFErrorRef *error); CFDataRef SOSPeerInfoCopyData(SOSPeerInfoRef fpi, CFErrorRef *error); +bool SOSFullPeerInfoUpdate(SOSFullPeerInfoRef fullPeerInfo, CFErrorRef *error, SOSPeerInfoRef (^create_modification)(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error)); + __END_DECLS #endif diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m index fe1416c2..86b33c54 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m @@ -93,7 +93,7 @@ CFStringRef kSOSFullPeerInfoSignatureKey = CFSTR("SOSFullPeerInfoSignature"); CFStringRef kSOSFullPeerInfoNameKey = CFSTR("SOSFullPeerInfoName"); -static bool SOSFullPeerInfoUpdate(SOSFullPeerInfoRef fullPeerInfo, CFErrorRef *error, SOSPeerInfoRef (^create_modification)(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error)) { +bool SOSFullPeerInfoUpdate(SOSFullPeerInfoRef fullPeerInfo, CFErrorRef *error, SOSPeerInfoRef (^create_modification)(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error)) { bool result = false; SOSPeerInfoRef newPeer = NULL; @@ -182,37 +182,6 @@ errOut: return retval; } -bool SOSFullPeerInfoUpdateTransportType(SOSFullPeerInfoRef peer, CFStringRef transportType, CFErrorRef* error) -{ - return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) { - return SOSPeerInfoSetTransportType(kCFAllocatorDefault, peer, transportType, key, error); - }); -} - -bool SOSFullPeerInfoUpdateDeviceID(SOSFullPeerInfoRef peer, CFStringRef deviceID, CFErrorRef* error){ - return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) { - return SOSPeerInfoSetDeviceID(kCFAllocatorDefault, peer, deviceID, key, error); - }); -} - -bool SOSFullPeerInfoUpdateTransportPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error){ - return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) { - return SOSPeerInfoSetIDSPreference(kCFAllocatorDefault, peer, preference, key, error); - }); -} - -bool SOSFullPeerInfoUpdateTransportFragmentationPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error){ - return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) { - return SOSPeerInfoSetIDSFragmentationPreference(kCFAllocatorDefault, peer, preference, key, error); - }); -} - -bool SOSFullPeerInfoUpdateTransportAckModelPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error){ - return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) { - return SOSPeerInfoSetIDSACKModelPreference(kCFAllocatorDefault, peer, preference, key, error); - }); -} - bool SOSFullPeerInfoUpdateOctagonSigningKey(SOSFullPeerInfoRef peer, SecKeyRef octagonSigningKey, CFErrorRef* error){ return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) { return SOSPeerInfoSetOctagonSigningKey(kCFAllocatorDefault, peer, octagonSigningKey, key, error); @@ -434,11 +403,6 @@ static bool sosFullPeerInfoRequiresUpdate(SOSFullPeerInfoRef peer, CFSetRef mini if(!SOSPeerInfoVersionIsCurrent(peer->peer_info)) return true; if(!SOSPeerInfoSerialNumberIsSet(peer->peer_info)) return true; - if(!(SOSPeerInfoV2DictionaryHasString(peer->peer_info, sDeviceID)))return true; - if(!(SOSPeerInfoV2DictionaryHasString(peer->peer_info, sTransportType))) return true; - if(!(SOSPeerInfoV2DictionaryHasBoolean(peer->peer_info, sPreferIDS))) return true; - if(!(SOSPeerInfoV2DictionaryHasBoolean(peer->peer_info, sPreferIDSFragmentation))) return true; - if(!(SOSPeerInfoV2DictionaryHasBoolean(peer->peer_info, sPreferIDSACKModel))) return true; if(SOSFullPeerInfoNeedsViewUpdate(peer, minimumViews, excludedViews)) return true; return false; @@ -486,35 +450,6 @@ SOSViewResultCode SOSFullPeerInfoViewStatus(SOSFullPeerInfoRef peer, CFStringRef return SOSPeerInfoViewStatus(pi, viewname, error); } - -SOSSecurityPropertyResultCode SOSFullPeerInfoUpdateSecurityProperty(SOSFullPeerInfoRef peer, SOSViewActionCode action, CFStringRef property, CFErrorRef* error) -{ - SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError; - SecKeyRef device_key = SOSFullPeerInfoCopyDeviceKey(peer, error); - require_quiet(device_key, fail); - - SOSPeerInfoRef newPeer = SOSPeerInfoCopyWithSecurityPropertyChange(kCFAllocatorDefault, peer->peer_info, action, property, &retval, device_key, error); - - require_quiet(newPeer, fail); - - CFReleaseNull(peer->peer_info); - peer->peer_info = newPeer; - newPeer = NULL; - -fail: - CFReleaseNull(device_key); - return retval; -} - -SOSSecurityPropertyResultCode SOSFullPeerInfoSecurityPropertyStatus(SOSFullPeerInfoRef peer, CFStringRef property, CFErrorRef *error) -{ - SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(peer); - secnotice("secprop", "have pi %s", (pi)? "true": "false"); - if(!pi) return kSOSCCGeneralSecurityPropertyError; - return SOSPeerInfoSecurityPropertyStatus(pi, property, error); -} - - SOSPeerInfoRef SOSFullPeerInfoGetPeerInfo(SOSFullPeerInfoRef fullPeer) { return fullPeer?fullPeer->peer_info:NULL; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h index f665f2c2..77249c8d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h @@ -40,6 +40,11 @@ __BEGIN_DECLS #define ENABLE_IDS 0 #define kSOSPeerIDLengthMax (26) +#define CC_STATISVALID 0x8000000000000000 +#define CC_UKEY_TRUSTED 0x4000000000000000 +#define CC_CAN_AUTH 0x2000000000000000 +#define CC_PEER_IS_IN 0x1000000000000000 +#define CC_MASK 0x0fffffffffffffff enum { // Public errors are first (See SOSCloudCircle) @@ -76,20 +81,10 @@ enum { kSOSErrorNotInCircle = 1046, }; -typedef enum { - kSecIDSErrorNoDeviceID = -1, //default case - kSecIDSErrorNotRegistered = -2, - kSecIDSErrorFailedToSend=-3, - kSecIDSErrorCouldNotFindMatchingAuthToken = -4, - kSecIDSErrorDeviceIsLocked = -5, - kSecIDSErrorNoPeersAvailable = -6 - -} idsError; - - extern const CFStringRef SOSTransportMessageTypeIDSV2; extern const CFStringRef SOSTransportMessageTypeKVS; extern const CFStringRef kSOSDSIDKey; +extern const SOSCCStatus kSOSNoCachedValue; // Returns false unless errorCode is 0. bool SOSErrorCreate(CFIndex errorCode, CFErrorRef *error, CFDictionaryRef formatOptions, CFStringRef descriptionString, ...); @@ -142,6 +137,7 @@ OSStatus GeneratePermanentECPair(int keySize, SecKeyRef* public, SecKeyRef *full CFStringRef SOSItemsChangedCopyDescription(CFDictionaryRef changes, bool is_sender); +CFStringRef SOSCopyHashBufAsString(uint8_t *digest, size_t len); CFStringRef SOSCopyIDOfDataBuffer(CFDataRef data, CFErrorRef *error); CFStringRef SOSCopyIDOfDataBufferWithLength(CFDataRef data, CFIndex len, CFErrorRef *error); @@ -161,14 +157,22 @@ CFDataRef SOSDateCreate(void); CFDataRef CFDataCreateWithDER(CFAllocatorRef allocator, CFIndex size, uint8_t*(^operation)(size_t size, uint8_t *buffer)); -extern const CFStringRef kSecIDSErrorDomain; -extern const CFStringRef kIDSOperationType; -extern const CFStringRef kIDSMessageToSendKey; -extern const CFStringRef kIDSMessageUniqueID; -extern const CFStringRef kIDSMessageRecipientPeerID; -extern const CFStringRef kIDSMessageRecipientDeviceID; -extern const CFStringRef kIDSMessageUsesAckModel; -extern const CFStringRef kIDSMessageSenderDeviceID; + +// Expanded notification utilities +#if __OBJC__ +@interface SOSCachedNotification : NSObject +- (instancetype)init NS_UNAVAILABLE; ++ (NSString *)notificationName:(const char *)notificationString; +@end +#endif + +bool SOSCachedNotificationOperation(const char *notificationString, bool (^operation) (int token, bool gtg)); +uint64_t SOSGetCachedCircleBitmask(void); +SOSCCStatus SOSGetCachedCircleStatus(CFErrorRef *error); +uint64_t SOSCachedViewBitmask(void); +CFSetRef SOSCreateCachedViewStatus(void); + + __END_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m index 00059bd4..f3222236 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m @@ -26,6 +26,7 @@ #include #include #include +#include #include "utilities/SecCFError.h" #include "utilities/SecCFRelease.h" #include "utilities/SecCFWrappers.h" @@ -50,17 +51,10 @@ #include -#include +#include -const CFStringRef kSecIDSErrorDomain = CFSTR("com.apple.security.ids.error"); -const CFStringRef kIDSOperationType = CFSTR("IDSMessageOperation"); -const CFStringRef kIDSMessageToSendKey = CFSTR("MessageToSendKey"); -const CFStringRef kIDSMessageUniqueID = CFSTR("MessageID"); -const CFStringRef kIDSMessageRecipientPeerID = CFSTR("RecipientPeerID"); -const CFStringRef kIDSMessageRecipientDeviceID = CFSTR("RecipientDeviceID"); -const CFStringRef kIDSMessageSenderDeviceID = CFSTR("SendersDeviceID"); +#include -const CFStringRef kIDSMessageUsesAckModel = CFSTR("UsesAckModel"); const CFStringRef kSOSErrorDomain = CFSTR("com.apple.security.sos.error"); const CFStringRef kSOSDSIDKey = CFSTR("AccountDSID"); const CFStringRef SOSTransportMessageTypeIDSV2 = CFSTR("IDS2.0"); @@ -182,15 +176,10 @@ CFStringRef SOSItemsChangedCopyDescription(CFDictionaryRef changes, bool is_send return string; } +CFStringRef SOSCopyHashBufAsString(uint8_t *digest, size_t len) { + char encoded[2 * len + 1]; // Big enough for base64 encoding. -CFStringRef SOSCopyIDOfDataBuffer(CFDataRef data, CFErrorRef *error) { - const struct ccdigest_info * di = ccsha1_di(); - uint8_t digest[di->output_size]; - char encoded[2 * di->output_size]; // Big enough for base64 encoding. - - ccdigest(di, CFDataGetLength(data), CFDataGetBytePtr(data), digest); - - size_t length = SecBase64Encode(digest, sizeof(digest), encoded, sizeof(encoded)); + size_t length = SecBase64Encode(digest, len, encoded, sizeof(encoded)); assert(length && length < sizeof(encoded)); if (length > kSOSPeerIDLengthMax) length = kSOSPeerIDLengthMax; @@ -198,6 +187,13 @@ CFStringRef SOSCopyIDOfDataBuffer(CFDataRef data, CFErrorRef *error) { return CFStringCreateWithCString(kCFAllocatorDefault, encoded, kCFStringEncodingASCII); } +CFStringRef SOSCopyIDOfDataBuffer(CFDataRef data, CFErrorRef *error) { + const struct ccdigest_info * di = ccsha1_di(); + uint8_t digest[di->output_size]; + ccdigest(di, CFDataGetLength(data), CFDataGetBytePtr(data), digest); + return SOSCopyHashBufAsString(digest, sizeof(digest)); +} + CFStringRef SOSCopyIDOfDataBufferWithLength(CFDataRef data, CFIndex len, CFErrorRef *error) { CFStringRef retval = NULL; CFStringRef tmp = SOSCopyIDOfDataBuffer(data, error); @@ -209,9 +205,10 @@ CFStringRef SOSCopyIDOfDataBufferWithLength(CFDataRef data, CFIndex len, CFError CFStringRef SOSCopyIDOfKey(SecKeyRef key, CFErrorRef *error) { CFDataRef publicBytes = NULL; CFStringRef result = NULL; - require_quiet(SecError(SecKeyCopyPublicBytes(key, &publicBytes), error, CFSTR("Failed to export public bytes %@"), key), fail); + require_action_quiet(key, errOut, SOSErrorCreate(kSOSErrorNoKey, error, NULL, CFSTR("NULL key passed to SOSCopyIDOfKey"))); + require_quiet(SecError(SecKeyCopyPublicBytes(key, &publicBytes), error, CFSTR("Failed to export public bytes %@"), key), errOut); result = SOSCopyIDOfDataBuffer(publicBytes, error); -fail: +errOut: CFReleaseNull(publicBytes); return result; } @@ -326,3 +323,109 @@ CFDataRef CFDataCreateWithDER(CFAllocatorRef allocator, CFIndex size, uint8_t*(^ } return result; } + +@implementation SOSCachedNotification ++ (NSString *)notificationName:(const char *)notificationString { +#if TARGET_OS_OSX + return [NSString stringWithFormat:@"user.uid.%d.%s", getuid(), notificationString]; +#else + return @(notificationString); +#endif +} + +@end + +bool SOSCachedNotificationOperation(const char *notificationString, bool (^operation) (int token, bool gtg)) { + static os_unfair_lock token_lock = OS_UNFAIR_LOCK_INIT; + static NSMutableDictionary *tokenCache = NULL; + int token = NOTIFY_TOKEN_INVALID; + + @autoreleasepool { + os_unfair_lock_lock(&token_lock); + if (tokenCache == NULL) { + tokenCache = [NSMutableDictionary dictionary]; + } + NSString *notification = [SOSCachedNotification notificationName:notificationString]; + if (notification == NULL) { + os_unfair_lock_unlock(&token_lock); + return false; + } + + NSNumber *cachedToken = tokenCache[notification]; + if (cachedToken == NULL) { + uint32_t status; + + status = notify_register_check([notification UTF8String], &token); + if (status == NOTIFY_STATUS_OK) { + tokenCache[notification] = @(token); + } else { + secnotice("cachedStatus", "Failed to retreive token for %@: error %d", + notification, status); + } + } else { + token = [cachedToken intValue]; + } + os_unfair_lock_unlock(&token_lock); + } + + return operation(token, (token != NOTIFY_TOKEN_INVALID)); +} + +uint64_t SOSGetCachedCircleBitmask(void) { + __block uint64_t retval = 0; // If the following call fails and we return 0 the caller, checking CC_STATISVALID will see we didn't get anything. + SOSCachedNotificationOperation(kSOSCCCircleChangedNotification, ^bool(int token, bool gtg) { + if(gtg) { + notify_get_state(token, &retval); + } + return false; + }); + return retval; +} + +const SOSCCStatus kSOSNoCachedValue = -99; + +SOSCCStatus SOSGetCachedCircleStatus(CFErrorRef *error) { + uint64_t statusMask = SOSGetCachedCircleBitmask(); + SOSCCStatus retval = kSOSNoCachedValue; + + if(statusMask & CC_STATISVALID) { + if(statusMask & CC_UKEY_TRUSTED) { + retval = (SOSCCStatus) statusMask & CC_MASK; + } else { + retval = kSOSCCError; + if(error) { + CFReleaseNull(*error); + if(statusMask & CC_PEER_IS_IN) { + SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("Public Key isn't available, this peer is in the circle, but invalid. The iCloud Password must be provided to keychain syncing subsystem to repair this."), NULL, error); + } else { + SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("Public Key isn't available. The iCloud Password must be provided to keychain syncing subsystem to repair this."), NULL, error); + } + } + } + } + return retval; +} + +uint64_t SOSCachedViewBitmask(void) { + __block uint64_t retval = 0; + if(SOSGetCachedCircleStatus(NULL) == kSOSCCInCircle) { + SOSCachedNotificationOperation(kSOSCCViewMembershipChangedNotification, ^bool(int token, bool gtg) { + if(gtg) { + notify_get_state(token, &retval); + return true; + } + return false; + }); + } + return retval; +} + +CFSetRef SOSCreateCachedViewStatus(void) { + __block CFSetRef retval = NULL; + uint64_t state = SOSCachedViewBitmask(); + if(state) { + retval = SOSViewCreateSetFromBitmask(state); + } + return retval; +} + diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h index 079be6dc..c0783bb5 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h @@ -60,7 +60,6 @@ CFStringRef SOSRetirementKeyCreateWithCircleAndPeer(SOSCircleRef circle, CFStrin CFStringRef SOSMessageKeyCreateFromTransportToPeer(SOSMessage* transport, CFStringRef myID, CFStringRef peer_name); CFStringRef SOSMessageKeyCreateFromPeerToTransport(SOSMessage* transport, CFStringRef myID, CFStringRef peer_name); CFStringRef SOSLastKeyParametersPushedKeyCreateWithAccountGestalt(SOSAccount* account); -CFStringRef SOSMessageKeyCreateWithCircleNameAndTransportType(CFStringRef circleName, CFStringRef transportType); CFStringRef SOSRingKeyCreateWithRingName(CFStringRef ring_name); CFStringRef SOSLastKeyParametersPushedKeyCreateWithPeerID(CFStringRef peerID); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m index 58f7a78e..155c73dc 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m @@ -261,12 +261,6 @@ CFStringRef SOSMessageKeyCreateWithCircleNameAndPeerNames(CFStringRef circleName circleName, sCircleSeparator, from_peer_name, sFromToSeparator, to_peer_name); } -CFStringRef SOSMessageKeyCreateWithCircleNameAndTransportType(CFStringRef circleName, CFStringRef transportType) -{ - return CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@%@%@%@"), - circleName, sCircleSeparator, transportType, sFromToSeparator, SOSTransportMessageTypeIDSV2); -} - CFStringRef SOSMessageKeyCreateWithCircleAndPeerNames(SOSCircleRef circle, CFStringRef from_peer_name, CFStringRef to_peer_name) { return SOSMessageKeyCreateWithCircleNameAndPeerNames(SOSCircleGetName(circle), from_peer_name, to_peer_name); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h index c25d8eb3..05d6cd87 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h @@ -86,10 +86,6 @@ SOSPeerInfoRef SOSPeerInfoCopyWithViewsChange(CFAllocatorRef allocator, SOSPeerI SecKeyRef signingKey, CFErrorRef* error); SOSPeerInfoRef SOSPeerInfoCopyAsApplication(SOSPeerInfoRef pi, SecKeyRef userkey, SecKeyRef peerkey, CFErrorRef *error); -SOSPeerInfoRef SOSPeerInfoCopyWithSecurityPropertyChange(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, - SOSSecurityPropertyActionCode action, CFStringRef property, SOSSecurityPropertyResultCode *retval, - SecKeyRef signingKey, CFErrorRef* error); - SOSPeerInfoRef SOSPeerInfoCopyWithPing(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, SecKeyRef signingKey, CFErrorRef* error); SOSPeerInfoRef SOSPeerInfoCopyAsApplication(SOSPeerInfoRef pi, SecKeyRef userkey, SecKeyRef peerkey, CFErrorRef *error); @@ -201,27 +197,11 @@ CFSetRef SOSPeerInfoGetPermittedViews(SOSPeerInfoRef peer); bool SOSPeerInfoIsEnabledView(SOSPeerInfoRef peer, CFStringRef viewName); CFMutableSetRef SOSPeerInfoCopyEnabledViews(SOSPeerInfoRef peer); void SOSPeerInfoWithEnabledViewSet(SOSPeerInfoRef pi, void (^operation)(CFSetRef enabled)); +uint64_t SOSPeerInfoViewBitMask(SOSPeerInfoRef pi); -SOSSecurityPropertyResultCode SOSPeerInfoSecurityPropertyStatus(SOSPeerInfoRef pi, CFStringRef property, CFErrorRef *error); - -//Transport -CFBooleanRef SOSPeerInfoCopyIDSPreference(SOSPeerInfoRef peer); -SOSPeerInfoRef SOSPeerInfoSetIDSPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error); - -CFBooleanRef SOSPeerInfoCopyIDSFragmentationPreference(SOSPeerInfoRef peer); -CFBooleanRef SOSPeerInfoCopyIDSACKModelPreference(SOSPeerInfoRef peer); -SOSPeerInfoRef SOSPeerInfoSetIDSFragmentationPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error); -SOSPeerInfoRef CF_RETURNS_RETAINED SOSPeerInfoSetIDSACKModelPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error); - -CFStringRef SOSPeerInfoCopyTransportType(SOSPeerInfoRef peer); -bool SOSPeerInfoTransportTypeIs(SOSPeerInfoRef pi, CFStringRef transportType); -SOSPeerInfoRef SOSPeerInfoSetTransportType(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFStringRef transportType, SecKeyRef signingKey, CFErrorRef *error); bool SOSPeerInfoKVSOnly(SOSPeerInfoRef pi); - -// IDSs device ID -bool SOSPeerInfoHasDeviceID(SOSPeerInfoRef peer); +CFStringRef SOSPeerInfoCopyTransportType(SOSPeerInfoRef peer); CFStringRef SOSPeerInfoCopyDeviceID(SOSPeerInfoRef peer); -SOSPeerInfoRef SOSPeerInfoSetDeviceID(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFStringRef IDS, SecKeyRef signingKey, CFErrorRef *error); /* octagon keys */ SOSPeerInfoRef CF_RETURNS_RETAINED @@ -242,11 +222,6 @@ SOSPeerInfoSetOctagonEncryptionKey(CFAllocatorRef allocator, CFStringRef SOSPeerInfoCopySerialNumber(SOSPeerInfoRef pi); CFStringRef SOSPeerInfoCopyOSVersion(SOSPeerInfoRef pi); - -bool SOSPeerInfoShouldUseIDSTransport(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer); -bool SOSPeerInfoShouldUseIDSMessageFragmentation(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer); -bool SOSPeerInfoShouldUseACKModel(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer); - void SOSPeerInfoLogState(char *category, SOSPeerInfoRef pi, SecKeyRef pubKey, CFStringRef myPID, char sigchr); enum { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m index 8a2dbf3a..ea95f3c2 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -312,6 +311,9 @@ static SOSPeerInfoRef SOSPeerInfoCreate_Internal(CFAllocatorRef allocator, description_modifier(pi->description); pi->peerID = SOSCopyIDOfKey(publicKey, error); + + pi->verifiedAppKeyID = NULL; + pi->verifiedResult = false; require_quiet(pi->peerID, exit); @@ -324,11 +326,6 @@ static SOSPeerInfoRef SOSPeerInfoCreate_Internal(CFAllocatorRef allocator, // V2DictionarySetValue handles NULL as remove if (backup_key != NULL) SOSPeerInfoV2DictionarySetValue(pi, sBackupKeyKey, backup_key); - SOSPeerInfoV2DictionarySetValue(pi, sDeviceID, IDSID); - SOSPeerInfoV2DictionarySetValue(pi, sTransportType, transportType); - SOSPeerInfoV2DictionarySetValue(pi, sPreferIDS, preferIDS); - SOSPeerInfoV2DictionarySetValue(pi, sPreferIDSFragmentation, preferFragmentation); - SOSPeerInfoV2DictionarySetValue(pi, sPreferIDSACKModel, preferAckModel); SOSPeerInfoV2DictionarySetValue(pi, sViewsKey, enabledViews); // ================ V2 Additions End @@ -380,6 +377,8 @@ SOSPeerInfoRef SOSPeerInfoCreateCopy(CFAllocatorRef allocator, SOSPeerInfoRef to pi->gestalt = CFDictionaryCreateCopy(allocator, toCopy->gestalt); pi->peerID = CFStringCreateCopy(allocator, toCopy->peerID); + pi->verifiedAppKeyID = NULL; // The peer resulting from this will need to be re-evaluated for an application signature. + pi->verifiedResult = false; pi->version = toCopy->version; if(!SOSPeerInfoVersionHasV2Data(pi)) SOSPeerInfoExpandV2Data(pi, error); @@ -402,24 +401,7 @@ SOSPeerInfoRef SOSPeerInfoCreateCurrentCopy(CFAllocatorRef allocator, SOSPeerInf SOSPeerInfoRef pi = SOSPeerInfoCreateCopy(allocator, toCopy, error); if(!SOSPeerInfoVersionHasV2Data(pi)) SOSPeerInfoUpdateToV2(pi, error); - - //SOSPeerInfoSetSerialNumber(pi); - if (IDSID) { - SOSPeerInfoV2DictionarySetValue(pi, sDeviceID, IDSID); - } - if (transportType) { - SOSPeerInfoV2DictionarySetValue(pi, sTransportType, transportType); - } - if (preferIDS) { - SOSPeerInfoV2DictionarySetValue(pi, sPreferIDS, preferIDS); - } - if (preferFragmentation) { - SOSPeerInfoV2DictionarySetValue(pi, sPreferIDSFragmentation, preferFragmentation); - } - if (preferAckModel) { - SOSPeerInfoV2DictionarySetValue(pi, sPreferIDSACKModel, preferAckModel); - } if (enabledViews) { SOSPeerInfoV2DictionarySetValue(pi, sViewsKey, enabledViews); } @@ -572,33 +554,6 @@ SOSViewResultCode SOSPeerInfoViewStatus(SOSPeerInfoRef pi, CFStringRef view, CFE return SOSViewsQuery(pi, view, error); } - -SOSPeerInfoRef SOSPeerInfoCopyWithSecurityPropertyChange(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, - SOSSecurityPropertyActionCode action, CFStringRef property, SOSSecurityPropertyResultCode *retval, - SecKeyRef signingKey, CFErrorRef* error) { - SOSPeerInfoRef pi = SOSPeerInfoCreateCopy(allocator, toCopy, error); - if(action == kSOSCCSecurityPropertyEnable) { - *retval = SOSSecurityPropertyEnable(pi, property, error); - require((kSOSCCSecurityPropertyValid == *retval), exit); - } else if(action == kSOSCCSecurityPropertyDisable) { - *retval = SOSSecurityPropertyDisable(pi, property, error); - require((kSOSCCSecurityPropertyNotValid == *retval), exit); - } - - require_action_quiet(SOSPeerInfoSign(signingKey, pi, error), exit, *retval = kSOSCCGeneralViewError); - return pi; - -exit: - CFReleaseNull(pi); - return NULL; -} - -SOSViewResultCode SOSPeerInfoSecurityPropertyStatus(SOSPeerInfoRef pi, CFStringRef property, CFErrorRef *error) { - return SOSSecurityPropertyQuery(pi, property, error); - } - - - static void SOSPeerInfoDestroy(CFTypeRef aObj) { SOSPeerInfoRef pi = (SOSPeerInfoRef) aObj; @@ -608,6 +563,8 @@ static void SOSPeerInfoDestroy(CFTypeRef aObj) { CFReleaseNull(pi->gestalt); CFReleaseNull(pi->peerID); CFReleaseNull(pi->v2Dictionary); + CFReleaseNull(pi->verifiedAppKeyID); + pi->verifiedResult = false; } static Boolean SOSPeerInfoCompare(CFTypeRef lhs, CFTypeRef rhs) { @@ -675,18 +632,17 @@ static CFStringRef copyDescriptionWithFormatOptions(CFTypeRef aObj, CFDictionary description = CFStringCreateWithFormat(kCFAllocatorDefault, formatOptions, CFSTR("<%@: [name: %20@] [%c%c%c%c%c%c%c] [type: %-20@] [spid: %8@] [os: %10@] [devid: %10@] [serial: %12@]"), - objectPrefix, - isKnown(SOSPeerInfoGetPeerName(pi)), - '-', - '-', - boolToChars(selfValid, 'S', 's'), - boolToChars(retired, 'R', 'r'), - boolToChars(backingUp, 'B', 'b'), - boolToChars(isKVS, 'K', 'I'), - '-', - isKnown(SOSPeerInfoGetPeerDeviceType(pi)), isKnown(peerID), - isKnown(osVersion), isKnown(deviceID), isKnown(serialNum)); - + objectPrefix, + isKnown(SOSPeerInfoGetPeerName(pi)), + '-', + '-', + boolToChars(selfValid, 'S', 's'), + boolToChars(retired, 'R', 'r'), + boolToChars(backingUp, 'B', 'b'), + boolToChars(isKVS, 'K', 'I'), + '-', + isKnown(SOSPeerInfoGetPeerDeviceType(pi)), isKnown(peerID), + isKnown(osVersion), isKnown(deviceID), isKnown(serialNum)); CFReleaseNull(peerID); CFReleaseNull(deviceID); @@ -709,7 +665,8 @@ void SOSPeerInfoLogState(char *category, SOSPeerInfoRef pi, SecKeyRef pubKey, CF if(!pi) return; bool appValid = SOSPeerInfoApplicationVerify(pi, pubKey, NULL); bool retired = SOSPeerInfoIsRetirementTicket(pi); - bool selfValid = SOSPeerInfoVerify(pi, NULL); + // We won't inflate invalid peerInfos. Mark this true to keep scanning utilities from breaking. + bool selfValid = true; bool backingUp = SOSPeerInfoHasBackupKey(pi); bool isMe = CFEqualSafe(SOSPeerInfoGetPeerID(pi), myPID) == true; bool isKVS = SOSPeerInfoKVSOnly(pi); @@ -730,7 +687,7 @@ void SOSPeerInfoLogState(char *category, SOSPeerInfoRef pi, SecKeyRef pubKey, CF sigchr, isKnown(SOSPeerInfoGetPeerDeviceType(pi)), isKnown(peerID), isKnown(osVersion), isKnown(deviceID), isKnown(serialNum)); - + CFReleaseNull(peerID); CFReleaseNull(deviceID); CFReleaseNull(serialNum); @@ -870,7 +827,12 @@ SOSPeerInfoRef SOSPeerInfoCopyAsApplication(SOSPeerInfoRef original, SecKeyRef u SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Failed to sign public key hash for peer"), NULL, error)); CFDictionarySetValue(pi->description, sApplicationUsig, usersig); - + pi->verifiedAppKeyID = SOSCopyIDOfKey(userkey, error); + if(pi->verifiedAppKeyID == NULL) { + secnotice("PICache", "failed to get userKeyID"); + } else { + pi->verifiedResult = true; + } require_quiet(SOSPeerInfoSign(peerkey, pi, error), fail); result = pi; @@ -886,7 +848,16 @@ bool SOSPeerInfoApplicationVerify(SOSPeerInfoRef pi, SecKeyRef userkey, CFErrorR const struct ccdigest_info *di = ccsha256_di(); uint8_t hbuf[di->output_size]; bool result = false; - + CFStringRef userKeyID = NULL; + + // If we've already succeeded signature check with this key move on. + require_action_quiet(userkey, exit, SOSErrorCreate(kSOSErrorNoKey, error, NULL, CFSTR("Can't validate PeerInfos with no userKey"))); + userKeyID = SOSCopyIDOfKey(userkey, error); + require_action_quiet(!CFEqualSafe(userKeyID, pi->verifiedAppKeyID), exit, result = pi->verifiedResult); + + // verifiedAppKeyID was NULL or not the key we're looking for - clear it. + CFReleaseNull(pi->verifiedAppKeyID); + pi->verifiedResult = false; CFDataRef usig = CFDictionaryGetValue(pi->description, sApplicationUsig); require_action_quiet(usig, exit, SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Peer is not an applicant"), NULL, error)); @@ -895,10 +866,14 @@ bool SOSPeerInfoApplicationVerify(SOSPeerInfoRef pi, SecKeyRef userkey, CFErrorR SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Failed to create hash for peer applicant"), NULL, error)); require_action_quiet(sosVerifyHash(userkey, di, hbuf, usig), exit, SOSCreateError(kSOSErrorUnexpectedType, CFSTR("user signature of public key hash fails to verify"), NULL, error)); + // Remember the userkey we validated for this peerinfo. + pi->verifiedAppKeyID = CFStringCreateCopy(kCFAllocatorDefault, userKeyID); + pi->verifiedResult = true; result = SOSPeerInfoVerify(pi, error); exit: + CFReleaseNull(userKeyID); return result; } @@ -1011,46 +986,6 @@ SOSPeerInfoRef SOSPeerInfoUpgradeSignatures(CFAllocatorRef allocator, SecKeyRef return retval; } -CFBooleanRef SOSPeerInfoCopyIDSPreference(SOSPeerInfoRef peer){ - CFBooleanRef preference = (CFBooleanRef)SOSPeerInfoV2DictionaryCopyBoolean(peer, sPreferIDS); - return (preference ? preference : CFRetain(kCFBooleanFalse)); -} - - -SOSPeerInfoRef SOSPeerInfoSetIDSPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error){ - return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error, - ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) { - SOSPeerInfoV2DictionarySetValue(peerToModify, sPreferIDS, preference); - return true; - }); -} - -CFBooleanRef SOSPeerInfoCopyIDSFragmentationPreference(SOSPeerInfoRef peer){ - CFBooleanRef preference = (CFBooleanRef)SOSPeerInfoV2DictionaryCopyBoolean(peer, sPreferIDSFragmentation); - return (preference ? preference : CFRetain(kCFBooleanFalse)); -} - -CFBooleanRef SOSPeerInfoCopyIDSACKModelPreference(SOSPeerInfoRef peer){ - CFBooleanRef preference = (CFBooleanRef)SOSPeerInfoV2DictionaryCopyBoolean(peer, sPreferIDSACKModel); - return (preference ? preference : CFRetain(kCFBooleanFalse)); -} - -SOSPeerInfoRef CF_RETURNS_RETAINED SOSPeerInfoSetIDSFragmentationPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error){ - return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error, - ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) { - SOSPeerInfoV2DictionarySetValue(peerToModify, sPreferIDSFragmentation, preference); - return true; - }); -} - -SOSPeerInfoRef CF_RETURNS_RETAINED SOSPeerInfoSetIDSACKModelPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error){ - return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error, - ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) { - SOSPeerInfoV2DictionarySetValue(peerToModify, sPreferIDSACKModel, preference); - return true; - }); -} - static SOSPeerInfoRef CF_RETURNS_RETAINED SOSPeerInfoSetOctagonKey(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, @@ -1101,24 +1036,11 @@ SOSPeerInfoSetOctagonEncryptionKey(CFAllocatorRef allocator, return SOSPeerInfoSetOctagonKey(allocator, toCopy, sOctagonPeerEncryptionPublicKeyKey, octagonEncryptionKey, signingKey, error); } -bool SOSPeerInfoTransportTypeIs(SOSPeerInfoRef pi, CFStringRef transportType) { - return SOSPeerInfoV2DictionaryHasStringValue(pi, sTransportType, transportType); -} - CFStringRef SOSPeerInfoCopyTransportType(SOSPeerInfoRef peer){ CFStringRef transportType = (CFStringRef)SOSPeerInfoV2DictionaryCopyString(peer, sTransportType); return (transportType ? transportType : CFRetain(SOSTransportMessageTypeKVS)); } -SOSPeerInfoRef SOSPeerInfoSetTransportType(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFStringRef transportType, SecKeyRef signingKey, CFErrorRef *error){ - - return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error, - ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) { - SOSPeerInfoV2DictionarySetValue(peerToModify, sTransportType, transportType); - return true; - }); -} - bool SOSPeerInfoKVSOnly(SOSPeerInfoRef pi) { CFStringRef transportType = SOSPeerInfoCopyTransportType(pi); bool retval = CFEqualSafe(transportType, SOSTransportMessageTypeKVS); @@ -1126,58 +1048,8 @@ bool SOSPeerInfoKVSOnly(SOSPeerInfoRef pi) { return retval; } -bool SOSPeerInfoHasDeviceID(SOSPeerInfoRef peer) { - return SOSPeerInfoV2DictionaryHasString(peer, sDeviceID); -} - CFStringRef SOSPeerInfoCopyDeviceID(SOSPeerInfoRef peer){ - return (CFStringRef)SOSPeerInfoV2DictionaryCopyString(peer, sDeviceID); -} - -SOSPeerInfoRef SOSPeerInfoSetDeviceID(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFStringRef IDS, SecKeyRef signingKey, CFErrorRef *error){ - - return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error, - ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) { - SOSPeerInfoV2DictionarySetValue(peerToModify, sDeviceID, IDS); - return true; - }); -} - -bool SOSPeerInfoShouldUseIDSTransport(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer){ - return SOSPeerInfoHasDeviceID(myPeer) && SOSPeerInfoTransportTypeIs(myPeer, SOSTransportMessageTypeIDSV2) && - SOSPeerInfoHasDeviceID(theirPeer) && SOSPeerInfoTransportTypeIs(theirPeer, SOSTransportMessageTypeIDSV2); -} - -bool SOSPeerInfoShouldUseIDSMessageFragmentation(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer){ - - bool success = false; - - CFBooleanRef myPreference = SOSPeerInfoCopyIDSFragmentationPreference(myPeer); - - CFBooleanRef theirPreference = SOSPeerInfoCopyIDSFragmentationPreference(theirPeer); - secnotice("IDS Transport", "mypreference: %@, theirpreference: %@", myPreference, theirPreference); - if((myPreference == kCFBooleanTrue && theirPreference == kCFBooleanTrue)) - success = true; - - CFReleaseNull(myPreference); - CFReleaseNull(theirPreference); - return success; -} - -bool SOSPeerInfoShouldUseACKModel(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer){ - bool success = false; - - CFBooleanRef myPreference = SOSPeerInfoCopyIDSACKModelPreference(myPeer); - - CFBooleanRef theirPreference = SOSPeerInfoCopyIDSACKModelPreference(theirPeer); - secnotice("IDS Transport", "mypreference: %@, theirpreference: %@", myPreference, theirPreference); - if((myPreference == kCFBooleanTrue && theirPreference == kCFBooleanTrue)) - success = true; - - CFReleaseNull(myPreference); - CFReleaseNull(theirPreference); - return success; - + return CFSTR("not implemented"); } SOSPeerInfoDeviceClass SOSPeerInfoGetClass(SOSPeerInfoRef pi) { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoDER.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoDER.m index f5d7be07..2ee2e588 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoDER.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoDER.m @@ -123,8 +123,9 @@ SOSPeerInfoRef SOSPeerInfoCreateFromDER(CFAllocatorRef allocator, CFErrorRef* er if(!SOSPeerInfoVerify(pi, error)) { SOSCreateErrorWithFormat(kSOSErrorBadSignature, NULL, error, NULL, CFSTR("Signature doesn't validate")); - if (error) + if (error) { secerror("Can't validate PeerInfo: %@", *error); + } goto fail; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h index b95b10a1..9bbd329c 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h @@ -25,6 +25,8 @@ #ifndef sec_SOSPeerInfoInternal_h #define sec_SOSPeerInfoInternal_h +/* Please don't use anything from this file unless you're part of the Security project. */ + extern const CFStringRef kPIUserDefinedDeviceNameKey; extern const CFStringRef kPIDeviceModelNameKey; extern const CFStringRef kPIMessageProtocolVersionKey; @@ -33,4 +35,6 @@ extern const CFStringRef kPIOSVersionKey; extern const CFStringRef sGestaltKey; extern const CFStringRef sVersionKey; +extern CFStringRef SOSGestaltSerial; + #endif diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h index 28b34561..c216d2c0 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h @@ -23,6 +23,9 @@ struct __OpaqueSOSPeerInfo { CFDictionaryRef gestalt; CFStringRef peerID; CFIndex version; + CFStringRef verifiedAppKeyID; + bool verifiedResult; + /* V2 and beyond are listed below */ CFMutableDictionaryRef v2Dictionary; }; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoSecurityProperties.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoSecurityProperties.h deleted file mode 100644 index 55f7cff4..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoSecurityProperties.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// SOSPeerInfoSecurityProperties.h -// sec -// -// Created by Richard Murphy on 3/14/15. -// -// - -#ifndef _sec_SOSPeerInfoSecurityProperties_ -#define _sec_SOSPeerInfoSecurityProperties_ - - -#include -#include -#include -#include -#include - -typedef struct __OpaqueSOSSecurityProperty { - CFRuntimeBase _base; - CFStringRef label; -} *SOSSecurityPropertyRef; - -bool SOSSecurityPropertiesSetDefault(SOSPeerInfoRef pi, CFErrorRef *error); -CFMutableSetRef SOSSecurityPropertiesCreateDefault(SOSPeerInfoRef pi, CFErrorRef *error); - -// Basic interfaces to change and query Security Properties -SOSSecurityPropertyResultCode SOSSecurityPropertyEnable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error); -SOSSecurityPropertyResultCode SOSSecurityPropertyDisable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error); -SOSSecurityPropertyResultCode SOSSecurityPropertyQuery(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error); - -CFSetRef SOSSecurityPropertyGetAllCurrent(void); -CFMutableSetRef SOSPeerInfoCopySecurityProperty(SOSPeerInfoRef pi); - -#endif /* defined(_sec_SOSPeerInfoSecurityProperties_) */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoSecurityProperties.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoSecurityProperties.m deleted file mode 100644 index 008753b8..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoSecurityProperties.m +++ /dev/null @@ -1,140 +0,0 @@ -// -// SOSPeerInfoSecurityProperties.c -// sec -// -// Created by Richard Murphy on 3/14/15. -// -// - - -#include -#include - -#include "SOSPeerInfoSecurityProperties.h" -#include -#include -#include -#include - -#include -#include -#include -#include - -#define secpropMemError CFSTR("Failed to get memory for SecurityProperties in PeerInfo") -#define secpropUnknownError CFSTR("Unknown Security Property(%@) (SOSSecurityPropertyResultCode=%d)") -#define secpropInvalidError CFSTR("Peer is invalid for this security property(%@) (SOSSecurityPropertyResultCode=%d)") - -const CFStringRef kSOSSecPropertyHasEntropy = CFSTR("SecPropEntropy"); -const CFStringRef kSOSSecPropertyScreenLock = CFSTR("SecPropScreenLock"); -const CFStringRef kSOSSecPropertySEP = CFSTR("SecPropSEP"); -const CFStringRef kSOSSecPropertyIOS = CFSTR("SecPropIOS"); - - -CFSetRef SOSSecurityPropertyGetAllCurrent(void) { - static dispatch_once_t dot; - static CFMutableSetRef allSecurityProperties = NULL; - dispatch_once(&dot, ^{ - allSecurityProperties = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); - CFSetAddValue(allSecurityProperties, kSOSSecPropertyHasEntropy); - CFSetAddValue(allSecurityProperties, kSOSSecPropertyScreenLock); - CFSetAddValue(allSecurityProperties, kSOSSecPropertySEP); - CFSetAddValue(allSecurityProperties, kSOSSecPropertyIOS); - }); - return allSecurityProperties; -} - -static bool SOSSecurityPropertyIsKnownProperty(CFStringRef secPropName) { - CFSetRef allSecurityProperties = SOSSecurityPropertyGetAllCurrent(); - if(CFSetContainsValue(allSecurityProperties, secPropName)) return true; - secnotice("SecurityProperties","Not a known Security Property"); - return false; -} - - -static CFMutableSetRef CFSetCreateMutableForSOSSecurityProperties(CFAllocatorRef allocator) { - return CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks); -} - -CFMutableSetRef SOSPeerInfoCopySecurityProperty(SOSPeerInfoRef pi) { - if (!SOSPeerInfoVersionHasV2Data(pi)) { - return NULL; - } else { - CFMutableSetRef secproperty = (CFMutableSetRef)SOSPeerInfoV2DictionaryCopySet(pi, sSecurityPropertiesKey); - if (!secproperty) - secerror("%@ v2 peer has no security properties", SOSPeerInfoGetPeerID(pi)); - return secproperty; - } -} - -static void SOSPeerInfoSetSecurityProperty(SOSPeerInfoRef pi, CFSetRef newproperties) { - if(!newproperties) { - secnotice("secproperty","Asked to swap to NULL Security Properties"); - return; - } - SOSPeerInfoV2DictionarySetValue(pi, sSecurityPropertiesKey, newproperties); -} - -static bool SOSPeerInfoSecurityPropertyIsValid(SOSPeerInfoRef pi, CFStringRef propertyname) { - return true; -} - -CFMutableSetRef SOSSecurityPropertiesCreateDefault(SOSPeerInfoRef pi, CFErrorRef *error) { - return CFSetCreateMutableForSOSSecurityProperties(NULL); -} - -SOSSecurityPropertyResultCode SOSSecurityPropertyEnable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error) { - SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError; - - CFMutableSetRef newSecurityProperties = SOSPeerInfoCopySecurityProperty(pi); - require_action_quiet(newSecurityProperties, fail, - SOSCreateError(kSOSErrorAllocationFailure, secpropMemError, NULL, error)); - require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname), fail, - SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, secpropUnknownError, propertyname, retval = kSOSCCNoSuchSecurityProperty)); - require_action_quiet(SOSPeerInfoSecurityPropertyIsValid(pi, propertyname), fail, - SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, secpropInvalidError, propertyname, retval = kSOSCCSecurityPropertyNotQualified)); - CFSetAddValue(newSecurityProperties, propertyname); - SOSPeerInfoSetSecurityProperty(pi, newSecurityProperties); - CFReleaseSafe(newSecurityProperties); - return kSOSCCSecurityPropertyValid; - -fail: - CFReleaseNull(newSecurityProperties); - secnotice("SecurityProperties","Failed to enable Security Property(%@): %@", propertyname, *error); - return retval; -} - -SOSSecurityPropertyResultCode SOSSecurityPropertyDisable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error) { - SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError; - CFMutableSetRef newSecurityProperties = SOSPeerInfoCopySecurityProperty(pi); - require_action_quiet(newSecurityProperties, fail, - SOSCreateError(kSOSErrorAllocationFailure, secpropMemError, NULL, error)); - require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname), fail, - SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, secpropUnknownError, propertyname, retval = kSOSCCNoSuchSecurityProperty)); - - CFSetRemoveValue(newSecurityProperties, propertyname); - SOSPeerInfoSetSecurityProperty(pi, newSecurityProperties); - CFReleaseSafe(newSecurityProperties); - return kSOSCCSecurityPropertyNotValid; - -fail: - CFReleaseNull(newSecurityProperties); - secnotice("SecurityProperties","Failed to disable Security Property(%@): %@", propertyname, *error); - return retval; -} - -SOSSecurityPropertyResultCode SOSSecurityPropertyQuery(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error) { - SOSSecurityPropertyResultCode retval = kSOSCCNoSuchSecurityProperty; - secnotice("SecurityProperties", "Querying %@", propertyname); - require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname), fail, - SOSCreateError(kSOSErrorNameMismatch, secpropUnknownError, NULL, error)); - CFMutableSetRef secproperty = SOSPeerInfoCopySecurityProperty(pi); - if(!secproperty) return kSOSCCSecurityPropertyNotValid; - retval = (CFSetContainsValue(secproperty, propertyname)) ? kSOSCCSecurityPropertyValid: kSOSCCSecurityPropertyNotValid; - CFReleaseNull(secproperty); - -fail: - secnotice("SecurityProperties","Failed to query Security Property(%@): %@", propertyname, *error); - return retval; -} - diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.h index 2a2b1de7..d482b248 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.h @@ -18,7 +18,7 @@ extern CFStringRef sV2DictionaryKey; // CFData wrapper for V2 extensions extern CFStringRef sViewsKey; // Set of Views extern CFStringRef sSerialNumberKey; // Device Serial Number -extern CFStringRef sSecurityPropertiesKey; // Set of Security Properties +extern CFStringRef sMachineIDKey; // Account MID extern CFStringRef kSOSHsaCrKeyDictionary; // HSA Challenge-Response area extern CFStringRef sPreferIDS; // Whether or not a peer requires to speak over IDS or KVS extern CFStringRef sPreferIDSFragmentation; // Whether or not a peer requires to speak over fragmented IDS or not diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m index dbdf0934..0a504884 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m @@ -22,14 +22,16 @@ CFStringRef sV2DictionaryKey = CFSTR("V2DictionaryData"); // CFData wrapper for V2 extensions CFStringRef sViewsKey = CFSTR("Views"); // Array of View labels CFStringRef sSerialNumberKey = CFSTR("SerialNumber"); +CFStringRef sMachineIDKey = CFSTR("MachineIDKey"); CFStringRef sViewsPending = CFSTR("ViewsPending"); // Array of View labels (pending) -CFStringRef sSecurityPropertiesKey = CFSTR("SecurityProperties"); CFStringRef kSOSHsaCrKeyDictionary = CFSTR("HSADictionary"); CFStringRef sRingState = CFSTR("RingState"); CFStringRef sBackupKeyKey = CFSTR("BackupKey"); CFStringRef sEscrowRecord = CFSTR("EscrowRecord"); +CFStringRef SOSGestaltSerial = NULL; + #if TARGET_OS_IPHONE // need entitlement for this: @@ -37,6 +39,9 @@ CFStringRef sEscrowRecord = CFSTR("EscrowRecord"); #include static CFStringRef SOSCopySerialNumberAsString(CFErrorRef *error) { + if (SOSGestaltSerial) + return CFRetain(SOSGestaltSerial); + CFTypeRef iosAnswer = (CFStringRef) MGCopyAnswer(kMGQSerialNumber, NULL); if(!iosAnswer) { SOSCreateError(kSOSErrorAllocationFailure, CFSTR("No Memory"), NULL, error); @@ -50,6 +55,8 @@ static CFStringRef SOSCopySerialNumberAsString(CFErrorRef *error) { #include static CFStringRef SOSCopySerialNumberAsString(CFErrorRef *error) { + if (SOSGestaltSerial) + return CFRetain(SOSGestaltSerial); CFStringRef serialNumber = NULL; CFStringRef retval = NULL; @@ -176,13 +183,6 @@ bool SOSPeerInfoUpdateToV2(SOSPeerInfoRef pi, CFErrorRef *error) { CFMutableSetRef views = SOSViewCopyViewSet(kViewSetDefault); CFMutableSetRef secproperties = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); CFDictionaryAddValue(v2Dictionary, sViewsKey, views); - CFDictionaryAddValue(v2Dictionary, sSecurityPropertiesKey, secproperties); - - CFDictionaryAddValue(v2Dictionary, sDeviceID, CFSTR("")); - CFDictionaryAddValue(v2Dictionary, sTransportType, SOSTransportMessageTypeKVS); - CFDictionaryAddValue(v2Dictionary, sPreferIDS, kCFBooleanFalse); - CFDictionaryAddValue(v2Dictionary, sPreferIDSFragmentation, kCFBooleanTrue); - CFDictionaryAddValue(v2Dictionary, sPreferIDSACKModel, kCFBooleanTrue); require_action_quiet((v2data = SOSCreateDERFromDictionary(v2Dictionary, error)), out, SOSCreateError(kSOSErrorAllocationFailure, CFSTR("No Memory"), NULL, error)); CFDictionaryAddValue(pi->description, sV2DictionaryKey, v2data); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m index 237a5224..66774675 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m @@ -54,10 +54,12 @@ static size_t SOSPiggyBackBlobGetDEREncodedSize(SOSGenCountRef gencount, SecKeyR require_quiet(accumulate_size(&total_payload, der_sizeof_number(gencount, error)), errOut); require_quiet(accumulate_size(&total_payload, der_sizeof_data_or_null(publicBytes, error)), errOut); require_quiet(accumulate_size(&total_payload, der_sizeof_data_or_null(signature, error)), errOut); + CFReleaseNull(publicBytes); return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, total_payload); errOut: SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error); + CFReleaseNull(publicBytes); return 0; } @@ -77,6 +79,9 @@ static uint8_t* SOSPiggyBackBlobEncodeToDER(SOSGenCountRef gencount, SecKeyRef p der_encode_number(gencount, error, der, der_encode_data_or_null(publicBytes, error, der, der_encode_data_or_null(signature, error, der, der_end)))); + + CFReleaseNull(publicBytes); + return der_end; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m index 0e7b6ae3..af466cff 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m @@ -20,8 +20,8 @@ #include -#include -#include +#include +#include #include #include @@ -49,16 +49,6 @@ #include -/* Copied from CFPriv.h */ -// #include - -CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void); -CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey; -CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey; -CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey; - - - static char *CFDictionaryCopyCStringWithDefault(CFDictionaryRef dict, const void *key, char *defaultString) { char *retval = NULL; require_quiet(dict, use_default); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m index 41787724..1d0c6e17 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m index bbc7eac0..b503757a 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.h deleted file mode 100644 index 2f31a754..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// SOSTransportMessageIDS.h -// sec -// -// -#ifndef sec_SOSTransportMessageIDS_h -#define sec_SOSTransportMessageIDS_h - -@class SOSMessage; - -typedef enum { - kIDSStartPingTestMessage = 1, - kIDSEndPingTestMessage= 2, - kIDSSendOneMessage = 3, - kIDSPeerReceivedACK = 4, - kIDSPeerAvailability = 6, - kIDSPeerAvailabilityDone = 7, - kIDSKeychainSyncIDSFragmentation = 8, - kIDSPeerUsesACK = 9 -} idsOperation; - - -extern const CFStringRef kSecIDSErrorDomain; -extern const CFStringRef kIDSOperationType; -extern const CFStringRef kIDSMessageToSendKey; -extern const CFStringRef kIDSMessageUniqueID; -extern const CFStringRef kIDSMessageRecipientPeerID; -extern const CFStringRef kIDSMessageRecipientDeviceID; -extern const CFStringRef kIDSMessageUsesAckModel; -extern const CFStringRef kIDSMessageSenderDeviceID;; - -@interface SOSMessageIDS : SOSMessage -{ - CFBooleanRef useFragmentation; -} -@property (atomic) CFBooleanRef useFragmentation; - --(id) initWithAcount:(SOSAccount*)acct circleName:(CFStringRef)name; - --(HandleIDSMessageReason) SOSTransportMessageIDSHandleMessage:(SOSAccount*)account m:(CFDictionaryRef) message err:(CFErrorRef *)error; - --(bool) SOSTransportMessageIDSGetIDSDeviceID:(SOSAccount*)acct; - --(void) SOSTransportMessageIDSSetFragmentationPreference:(SOSMessage*) transport pref:(CFBooleanRef) preference; --(CFBooleanRef) SOSTransportMessageIDSGetFragmentationPreference:(SOSMessage*) transport; - -@end -#endif diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.m deleted file mode 100644 index 0d4425fc..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.m +++ /dev/null @@ -1,392 +0,0 @@ -// -// SOSTransportMessageIDS.c -// sec -// -// -#include -#include -#import -#import -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" - -#define IDS "IDS transport" - -@implementation SOSMessageIDS - -@synthesize useFragmentation = useFragmentation; - --(CFIndex) SOSTransportMessageGetTransportType -{ - return kIDS; -} - --(void) SOSTransportMessageIDSSetFragmentationPreference:(SOSMessageIDS*) transport pref:(CFBooleanRef) preference -{ - useFragmentation = preference; -} - --(CFBooleanRef) SOSTransportMessageIDSGetFragmentationPreference:(SOSMessageIDS*) transport -{ - return useFragmentation; -} - --(id) initWithAcount:(SOSAccount*)acct circleName:(CFStringRef)name -{ - self = [super init]; - - if (self) { - self.useFragmentation = kCFBooleanTrue; - self.account = acct; - self.circleName = [[NSString alloc]initWithString:(__bridge NSString*)name]; - [self SOSTransportMessageIDSGetIDSDeviceID:account]; - SOSRegisterTransportMessage((SOSMessage*)self); - } - - return self; -} - --(CFDictionaryRef) CF_RETURNS_RETAINED SOSTransportMessageHandlePeerMessageReturnsHandledCopy:(SOSMessage*) transport peerMessages:(CFMutableDictionaryRef) circle_peer_messages_table err:(CFErrorRef *)error -{ - return CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); -} - -static HandleIDSMessageReason checkMessageValidity(SOSAccount* account, CFStringRef fromDeviceID, CFStringRef fromPeerID, CFStringRef *peerID, SOSPeerInfoRef *theirPeerInfo){ - SOSAccountTrustClassic *trust = account.trust; - __block HandleIDSMessageReason reason = kHandleIDSMessageDontHandle; - - SOSCircleForEachPeer(trust.trustedCircle, ^(SOSPeerInfoRef peer) { - CFStringRef deviceID = SOSPeerInfoCopyDeviceID(peer); - CFStringRef pID = SOSPeerInfoGetPeerID(peer); - - if( deviceID && pID && fromPeerID && fromDeviceID && CFStringGetLength(fromPeerID) != 0 ){ - if(CFStringCompare(pID, fromPeerID, 0) == 0){ - if(CFStringGetLength(deviceID) == 0){ - secnotice("ids transport", "device ID was empty in the peer list, holding on to message"); - CFReleaseNull(deviceID); - reason = kHandleIDSMessageNotReady; - return; - } - else if(CFStringCompare(fromDeviceID, deviceID, 0) != 0){ //IDSids do not match, ghost - secnotice("ids transport", "deviceIDMisMatch"); - reason = kHandleIDSmessageDeviceIDMismatch; - CFReleaseNull(deviceID); - return; - } - else if(CFStringCompare(deviceID, fromDeviceID, 0) == 0){ - *peerID = pID; - *theirPeerInfo = peer; - CFReleaseNull(deviceID); - reason = kHandleIDSMessageSuccess; - return; - } - else{ - secerror("?? deviceID:%@, pID: %@, fromPeerID: %@, fromDeviceID: %@", deviceID, pID, fromPeerID, fromDeviceID); - } - } - } - CFReleaseNull(deviceID); - }); - - return reason; -} - --(HandleIDSMessageReason) SOSTransportMessageIDSHandleMessage:(SOSAccount*)acct m:(CFDictionaryRef) message err:(CFErrorRef *)error -{ - secnotice("IDS Transport", "SOSTransportMessageIDSHandleMessage!"); - - CFStringRef dataKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyIDSDataMessage, kCFStringEncodingASCII); - CFStringRef deviceIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyDeviceID, kCFStringEncodingASCII); - CFStringRef sendersPeerIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeySendersPeerID, kCFStringEncodingASCII); - CFStringRef ourPeerIdKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyPeerID, kCFStringEncodingASCII); - NSString *errMessage = nil; - - HandleIDSMessageReason result = kHandleIDSMessageSuccess; - - CFDataRef messageData = asData(CFDictionaryGetValue(message, dataKey), NULL); - __block CFStringRef fromDeviceID = asString(CFDictionaryGetValue(message, deviceIDKey), NULL); - __block CFStringRef fromPeerID = (CFStringRef)CFDictionaryGetValue(message, sendersPeerIDKey); - CFStringRef ourPeerID = asString(CFDictionaryGetValue(message, ourPeerIdKey), NULL); - - CFStringRef peerID = NULL; - SOSPeerInfoRef theirPeer = NULL; - - require_action_quiet(fromDeviceID, exit, result = kHandleIDSMessageDontHandle; errMessage = @"Missing device name"); - require_action_quiet(fromPeerID, exit, result = kHandleIDSMessageDontHandle; errMessage = @"Missing from peer id"); - require_action_quiet(messageData && CFDataGetLength(messageData) != 0, exit, result = kHandleIDSMessageDontHandle; errMessage = @"no message data"); - require_action_quiet(SOSAccountHasFullPeerInfo(account, error), exit, result = kHandleIDSMessageNotReady; errMessage = @"no full perinfo"); - require_action_quiet(ourPeerID && [account.peerID isEqual: (__bridge NSString*) ourPeerID], exit, result = kHandleIDSMessageDontHandle; secnotice("IDS Transport","ignoring message for: %@", ourPeerID)); - - require_quiet((result = checkMessageValidity( account, fromDeviceID, fromPeerID, &peerID, &theirPeer)) == kHandleIDSMessageSuccess, exit); - - if ([account.ids_message_transport SOSTransportMessageHandlePeerMessage:account.ids_message_transport id:peerID cm:messageData err:error]) { - CFMutableDictionaryRef peersToSyncWith = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - CFMutableSetRef peerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(peerIDs, peerID); - SOSAccountTrustClassic* trust = account.trust; - //sync using fragmentation? - if(SOSPeerInfoShouldUseIDSMessageFragmentation(trust.peerInfo, theirPeer)){ - //set useFragmentation bit - [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref: kCFBooleanTrue]; - } - else{ - [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref: kCFBooleanFalse]; - } - - if(![account.ids_message_transport SOSTransportMessageSyncWithPeers:account.ids_message_transport p:peerIDs err:error]){ - secerror("SOSTransportMessageIDSHandleMessage Could not sync with all peers: %@", *error); - }else{ - secnotice("IDS Transport", "Synced with all peers!"); - } - - CFReleaseNull(peersToSyncWith); - CFReleaseNull(peerIDs); - }else{ - if(error && *error != NULL){ - CFStringRef errorMessage = CFErrorCopyDescription(*error); - if (-25308 == CFErrorGetCode(*error)) { // tell KeychainSyncingOverIDSProxy to call us back when device unlocks - result = kHandleIDSMessageLocked; - }else{ //else drop it, couldn't handle the message - result = kHandleIDSMessageDontHandle; - } - secerror("IDS Transport Could not handle message: %@, %@", messageData, *error); - CFReleaseNull(errorMessage); - - } - else{ //no error but failed? drop it, log message - secerror("IDS Transport Could not handle message: %@", messageData); - result = kHandleIDSMessageDontHandle; - - } - } - -exit: - - if(errMessage != nil){ - secerror("%@", errMessage); - } - CFReleaseNull(ourPeerIdKey); - CFReleaseNull(sendersPeerIDKey); - CFReleaseNull(deviceIDKey); - CFReleaseNull(dataKey); - return result; -} - - -static bool sendToPeer(SOSMessageIDS* transport, bool shouldUseAckModel, CFStringRef circleName, CFStringRef deviceID, CFStringRef peerID,CFDictionaryRef message, CFErrorRef *error) -{ - __block bool success = false; - CFStringRef errorMessage = NULL; - CFDictionaryRef userInfo; - CFStringRef operation = NULL; - CFDataRef operationData = NULL; - CFMutableDataRef mutableData = NULL; - SOSAccount* account = [transport SOSTransportMessageGetAccount]; - CFStringRef ourPeerID = SOSPeerInfoGetPeerID(account.peerInfo); - CFStringRef operationToString = NULL; - - CFDictionaryRef messagetoSend = NULL; - - if(deviceID == NULL || CFStringGetLength(deviceID) == 0){ - errorMessage = CFSTR("Need an IDS Device ID to sync"); - userInfo = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kCFErrorLocalizedDescriptionKey, errorMessage, NULL); - if(error != NULL){ - *error =CFErrorCreate(kCFAllocatorDefault, CFSTR("com.apple.security.ids.error"), kSecIDSErrorNoDeviceID, userInfo); - secerror("%@", *error); - } - CFReleaseNull(messagetoSend); - CFReleaseNull(operation); - CFReleaseNull(operationData); - CFReleaseNull(mutableData); - CFReleaseNull(userInfo); - CFReleaseNull(operationToString); - - return success; - } - - if(CFDictionaryGetValue(message, kIDSOperationType) == NULL && [transport SOSTransportMessageIDSGetFragmentationPreference:transport] == kCFBooleanTrue){ - //handle a keychain data blob using fragmentation! - secnotice("IDS Transport","sendToPeer: using fragmentation!"); - - operationToString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), kIDSKeychainSyncIDSFragmentation); - messagetoSend = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, - kIDSOperationType, operationToString, - kIDSMessageRecipientDeviceID, deviceID, - kIDSMessageRecipientPeerID, peerID, - kIDSMessageUsesAckModel, (shouldUseAckModel ? CFSTR("YES") : CFSTR("NO")), - kIDSMessageToSendKey, message, - NULL); - } - else{ //otherhandle handle the test message without fragmentation - secnotice("IDS Transport","sendToPeer: not going to fragment message"); - - CFMutableDictionaryRef annotatedMessage = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, message); - CFDictionaryAddValue(annotatedMessage, kIDSMessageRecipientPeerID, peerID); - CFDictionaryAddValue(annotatedMessage, kIDSMessageRecipientDeviceID, deviceID); - CFDictionaryAddValue(annotatedMessage, kIDSMessageUsesAckModel, (shouldUseAckModel ? CFSTR("YES") : CFSTR("NO"))); - CFTransferRetained(messagetoSend, annotatedMessage); - CFReleaseNull(annotatedMessage); - } - - dispatch_semaphore_t wait_for = dispatch_semaphore_create(0); - - secnotice("IDS Transport", "Starting"); - - SecADAddValueForScalarKey(CFSTR("com.apple.security.sos.sendids"), 1); - - CFStringRef myDeviceID = CFRetainSafe((__bridge CFStringRef)account.deviceID); - if(!myDeviceID){ - myDeviceID = SOSPeerInfoCopyDeviceID(account.peerInfo); - } - - SOSCloudKeychainSendIDSMessage(messagetoSend, deviceID, ourPeerID, myDeviceID, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [transport SOSTransportMessageIDSGetFragmentationPreference:transport], ^(CFDictionaryRef returnedValues, CFErrorRef sync_error) { - success = (sync_error == NULL); - if (sync_error && error) { - CFRetainAssign(*error, sync_error); - } - - dispatch_semaphore_signal(wait_for); - }); - - if (dispatch_semaphore_wait(wait_for, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 2)) != 0) { - secerror("IDS Transport: timed out waiting for message send to complete"); - } - - if(!success){ - if(error != NULL) - secerror("IDS Transport: Failed to send message to peer! %@", *error); - else - secerror("IDS Transport: Failed to send message to peer"); - } - else{ - secnotice("IDS Transport", "Sent message to peer!"); - } - CFReleaseNull(myDeviceID); - CFReleaseNull(messagetoSend); - CFReleaseNull(operation); - CFReleaseNull(operationData); - CFReleaseNull(mutableData); - CFReleaseNull(operationToString); - return success; -} - - --(bool) SOSTransportMessageSyncWithPeers:(SOSMessageIDS*) transport p:(CFSetRef) peers err:(CFErrorRef *)error -{ - // Each entry is keyed by circle name and contains a list of peerIDs - __block bool result = true; - - CFSetForEach(peers, ^(const void *value) { - CFStringRef peerID = asString(value, NULL); - - result &= [transport SOSTransportMessageSendMessageIfNeeded:transport id:(__bridge CFStringRef)(transport.circleName) pID:peerID err:error]; - }); - - return result; -} - --(bool) SOSTransportMessageSendMessages:(SOSMessageIDS*) transport pm:(CFDictionaryRef) peer_messages err:(CFErrorRef *)error -{ - __block bool result = true; - - SOSPeerInfoRef myPeer = transport->account.peerInfo; - CFStringRef myID = SOSPeerInfoGetPeerID(myPeer); - if(!myPeer) - return result; - - CFDictionaryForEach(peer_messages, ^(const void *key, const void *value) { - CFErrorRef error = NULL; - - SOSPeerInfoRef peer = NULL; - CFStringRef deviceID = NULL; - CFDictionaryRef message = NULL; - - CFStringRef peerID = asString(key, &error); - require_quiet(peerID, skip); - require_quiet(!CFEqualSafe(myID, key), skip); - - message = CFRetainSafe(asDictionary(value, &error)); - if (message == NULL) { - // If it's not a data, return the error - CFDataRef messageData = asData(value, NULL); - if (messageData) { - CFReleaseNull(error); - message = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, peerID, messageData, NULL); - } - } - require_quiet(message, skip); - - peer = SOSAccountCopyPeerWithID(transport->account, peerID, &error); - require_quiet(peer, skip); - - deviceID = SOSPeerInfoCopyDeviceID(peer); - require_action_quiet(deviceID, skip, SOSErrorCreate(kSOSErrorSendFailure, &error, NULL, CFSTR("No IDS ID"))); - - [transport SOSTransportMessageIDSSetFragmentationPreference:transport - pref:SOSPeerInfoShouldUseIDSMessageFragmentation(myPeer, peer) ? kCFBooleanTrue : kCFBooleanFalse]; - bool shouldUseAckModel = SOSPeerInfoShouldUseACKModel(myPeer, peer); - - result &= sendToPeer(transport, shouldUseAckModel, (__bridge CFStringRef)(transport.circleName), deviceID, peerID, message, &error); - - skip: - if (error) { - secerror("Failed to sync to %@ over IDS: %@", peerID, error); - } - - CFReleaseNull(peer); - CFReleaseNull(deviceID); - CFReleaseNull(message); - - CFReleaseNull(error); - }); - - return result; -} - - --(bool) SOSTransportMessageFlushChanges:(SOSMessageIDS*) transport err:(CFErrorRef *)error -{ - return true; -} - --(bool) SOSTransportMessageCleanupAfterPeerMessages:(SOSMessageIDS*) transport peers:(CFDictionaryRef) peers err:(CFErrorRef*) error -{ - return true; -} - --(bool) SOSTransportMessageIDSGetIDSDeviceID:(SOSAccount*)acct -{ - SOSAccountTrustClassic* trust = acct.trust; - CFStringRef deviceID = SOSPeerInfoCopyDeviceID(trust.peerInfo); - bool hasDeviceID = (deviceID != NULL && CFStringGetLength(deviceID) != 0) || account.deviceID; - CFReleaseNull(deviceID); - - if(!hasDeviceID){ - SOSCloudKeychainGetIDSDeviceID(^(CFDictionaryRef returnedValues, CFErrorRef sync_error){ - bool success = (sync_error == NULL); - if (!success) { - secerror("Could not ask KeychainSyncingOverIDSProxy for Device ID: %@", sync_error); - } - else{ - secnotice("IDS Transport", "Successfully attempting to retrieve the IDS Device ID"); - } - }); - } - - return hasDeviceID; -} -@end diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m index 22b72d82..9fb69094 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m @@ -96,32 +96,6 @@ static bool SOSTransportMessageKVSUpdateKVS(SOSMessageKVS* transport, CFDictiona return true; } -static bool SOSTransportMessageKVSSendPendingChanges(SOSMessageKVS* transport, CFErrorRef *error) { - CFErrorRef changeError = NULL; - - if (transport->pending_changes == NULL || CFDictionaryGetCount(transport->pending_changes) == 0) { - CFReleaseNull(transport->pending_changes); - return true; - } - SOSAccount* acct = [transport SOSTransportMessageGetAccount]; - CFTypeRef dsid = SOSAccountGetValue(acct, kSOSDSIDKey, error); - - if(dsid == NULL) - dsid = kCFNull; - - CFDictionaryAddValue(transport->pending_changes, kSOSKVSRequiredKey, dsid); - - bool success = SOSTransportMessageKVSUpdateKVS(transport, transport->pending_changes, &changeError); - if (success) { - CFDictionaryRemoveAllValues(transport->pending_changes); - } else { - SOSCreateErrorWithFormat(kSOSErrorSendFailure, changeError, error, NULL, - CFSTR("Send changes block failed [%@]"), transport->pending_changes); - } - - return success; -} - static void SOSTransportMessageKVSAddToPendingChanges(SOSMessageKVS* transport, CFStringRef message_key, CFDataRef message_data){ if (transport.pending_changes == NULL) { transport.pending_changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); @@ -258,11 +232,6 @@ static bool sendToPeer(SOSMessage* transport, CFStringRef circleName, CFStringRe return true; } --(bool) SOSTransportMssageFlushChanges:(SOSMessage*) transport err:(CFErrorRef *)error -{ - return SOSTransportMessageKVSSendPendingChanges((SOSMessageKVS*) transport, error); -} - @end diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h index 6c689bf5..b664a5b2 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h @@ -38,14 +38,6 @@ typedef enum SyncWithAllPeersReason { kSyncWithAllPeersLocked, } SyncWithAllPeersReason; -typedef enum HandleIDSMessageReason { - kHandleIDSMessageDontHandle = 0, - kHandleIDSMessageNotReady, - kHandleIDSMessageSuccess, - kHandleIDSMessageLocked, - kHandleIDSmessageDeviceIDMismatch -} HandleIDSMessageReason; - /* * Piggy backing codes */ @@ -93,30 +85,6 @@ enum { }; typedef int SOSViewActionCode; -/* - SecurityProperty Result Codes - */ -enum { - kSOSCCGeneralSecurityPropertyError = 0, - kSOSCCSecurityPropertyValid = 1, - kSOSCCSecurityPropertyNotValid = 2, - kSOSCCSecurityPropertyNotQualified = 3, - kSOSCCNoSuchSecurityProperty = 4, - kSOSCCSecurityPropertyPending = 5, -}; -typedef int SOSSecurityPropertyResultCode; - - -/* - SecurityProperty Action Codes - */ -enum { - kSOSCCSecurityPropertyEnable = 1, - kSOSCCSecurityPropertyDisable = 2, - kSOSCCSecurityPropertyQuery = 3, -}; -typedef int SOSSecurityPropertyActionCode; - #if __OBJC__ #import @@ -129,7 +97,6 @@ typedef int SOSSecurityPropertyActionCode; @protocol SOSControlProtocol - (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))complete; - (void)kvsPerformanceCounters:(void(^)(NSDictionary *))reply; -- (void)idsPerformanceCounters:(void(^)(NSDictionary *))reply; - (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary *))reply; - (void)stashedCredentialPublicKey:(void(^)(NSData *, NSError *error))complete; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h index 0995fa31..e3692d24 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h @@ -87,6 +87,8 @@ SOSViewResultCode SOSViewsQuery(SOSPeerInfoRef pi, CFStringRef viewname, CFError CFSetRef SOSViewsGetAllCurrent(void); void SOSViewsForEachDefaultEnabledViewName(void (^operation)(CFStringRef viewName)); +CFSetRef SOSViewCreateSetFromBitmask(uint64_t bitmask); + // Test constraints void SOSViewsSetTestViewsSet(CFSetRef testViewNames); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.m index a3065494..39bbeb68 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.m @@ -220,6 +220,73 @@ CFSetRef SOSViewsGetAllCurrent(void) { return allViews; } +static CFDictionaryRef SOSViewsGetBitmasks(void) { + static dispatch_once_t once; + static CFMutableDictionaryRef masks = NULL; + + dispatch_once(&once, ^{ + CFSetRef views = SOSViewsGetAllCurrent(); + CFMutableArrayRef viewArray = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); + CFSetForEach(views, ^(const void *value) { + CFStringRef viewName = (CFStringRef) value; + CFArrayAppendValue(viewArray, viewName); + }); + CFIndex viewCount = CFArrayGetCount(viewArray); + if(viewCount > 32) { + secnotice("views", "Too many views defined, can't make bitmask (%d)", (int) viewCount); + } else { + __block uint32_t maskValue = 1; + CFRange all = CFRangeMake(0, viewCount); + CFArraySortValues(viewArray, all, (CFComparatorFunction)CFStringCompare, NULL); + masks = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, NULL); + CFArrayForEach(viewArray, ^(const void *value) { + CFDictionaryAddValue(masks, value, (const void *) (uintptr_t) maskValue); + maskValue <<= 1; + }); + } + CFReleaseNull(viewArray); + }); + return masks; +} + +static uint64_t SOSViewBitmaskFromSet(CFSetRef views) { + __block uint64_t retval = 0; + CFDictionaryRef masks = SOSViewsGetBitmasks(); + if(masks) { + CFSetForEach(views, ^(const void *viewName) { + uint64_t viewMask = (uint64_t) CFDictionaryGetValue(masks, viewName); + retval |= viewMask; + }); + } + return retval; +} + +uint64_t SOSPeerInfoViewBitMask(SOSPeerInfoRef pi) { + __block uint64_t retval = 0; + CFSetRef views = SOSPeerInfoCopyEnabledViews(pi); + if(views) { + retval = SOSViewBitmaskFromSet(views); + CFReleaseNull(views); + } + return retval; +} + +CFSetRef SOSViewCreateSetFromBitmask(uint64_t bitmask) { + CFMutableSetRef retval = NULL; + CFDictionaryRef masks = SOSViewsGetBitmasks(); + if(masks) { + retval = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + CFDictionaryForEach(masks, ^(const void *key, const void *value) { + CFStringRef viewName = (CFStringRef) key; + uint64_t viewMask = (uint64_t) value; + if(bitmask & viewMask) { + CFSetAddValue(retval, viewName); + } + }); + } + return retval; +} + const char *SOSViewsXlateAction(SOSViewActionCode action) { switch(action) { case kSOSCCViewEnable: return "kSOSCCViewEnable"; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/ViewList.list b/OSX/sec/SOSCircle/SecureObjectSync/ViewList.list index 5cfd60f0..165b3842 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/ViewList.list +++ b/OSX/sec/SOSCircle/SecureObjectSync/ViewList.list @@ -46,4 +46,5 @@ DOVIEWMACRO(Manatee, "Manatee", "manatee", DOVIEWMACRO(AutoUnlock, "AutoUnlock", "autounlock", CKKS, D, , A, , ) DOVIEWMACRO(Health, "Health", "health", CKKS, D, , A, , ) DOVIEWMACRO(ApplePay, "ApplePay", "applepay", CKKS, D, , A, , ) +DOVIEWMACRO(Home, "Home", "home", CKKS, D, , A, , ) diff --git a/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m b/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m index 0ca7efe4..b6add4ef 100644 --- a/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m +++ b/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m @@ -29,8 +29,8 @@ #include -#include -#include +#include +#include #include #include @@ -55,14 +55,6 @@ #include -/* Copied from CFPriv.h */ -// #include - -CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void); -CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey; -CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey; -CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey; - #define MAXKVSKEYTYPE kUnknownKey #define DATE_LENGTH 18 @@ -110,46 +102,55 @@ static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error CFArrayRef ppi = getArray(&error); SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(NULL); CFStringRef mypeerID = SOSPeerInfoGetPeerID(me); - + if(ppi) { printmsg(CFSTR("%s count: %ld\n"), label, (long)CFArrayGetCount(ppi)); CFArrayForEach(ppi, ^(const void *value) { char buf[160]; SOSPeerInfoRef peer = (SOSPeerInfoRef)value; + if(!peer) { return; } CFIndex version = SOSPeerInfoGetVersion(peer); CFStringRef peerName = SOSPeerInfoGetPeerName(peer); CFStringRef devtype = SOSPeerInfoGetPeerDeviceType(peer); CFStringRef peerID = SOSPeerInfoGetPeerID(peer); CFStringRef transportType = CFSTR("KVS"); CFStringRef deviceID = CFSTR(""); + CFStringRef machineID = CFSTR(""); CFDictionaryRef gestalt = SOSPeerInfoCopyPeerGestalt(peer); - CFStringRef osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion")); - - + CFStringRef osVersion = CFSTR("Unknown"); + if(gestalt) { + osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion")); + } + if(version >= 2){ CFDictionaryRef v2Dictionary = peer->v2Dictionary; - transportType = CFDictionaryGetValue(v2Dictionary, sTransportType); - deviceID = CFDictionaryGetValue(v2Dictionary, sDeviceID); + if(v2Dictionary) { + transportType = CFDictionaryGetValue(v2Dictionary, CFSTR("TransportType")); + deviceID = CFDictionaryGetValue(v2Dictionary, CFSTR("DeviceID")); + machineID = CFDictionaryGetValue(v2Dictionary, CFSTR("MachineIDKey")); + } } char *pname = CFStringToCString(peerName); char *dname = CFStringToCString(devtype); - char *tname = CFStringToCString(transportType); + char *tname = transportType ? CFStringToCString(transportType) : CFStringToCString(CFSTR("KVS")); char *iname = CFStringToCString(deviceID); + char *mname = CFStringToCString(machineID); const char *me = CFEqualSafe(mypeerID, peerID) ? "me>" : " "; - - - snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-36s", me, label, pname, dname, tname, iname); - + + + snprintf(buf, 160, "%s %s: %-16s dev:%-16s trn:%-16s devid:%-36s mid: %-36s", me, label, pname, dname, tname, iname, mname); + free(pname); free(dname); free(tname); free(iname); + free(mname); // %s in (Core)Foundation format strings treats the string as MacRoman, need to do this to guarantee UTF8 handling CFStringRef bufstr = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8); CFStringRef pid = SOSPeerInfoGetPeerID(peer); CFIndex vers = SOSPeerInfoGetVersion(peer); - printmsg(CFSTR("%@ %@ V%d OS:%@\n"), bufstr, pid, vers, osVersion ?: CFSTR("")); + printmsg(CFSTR("%@ pid:%@ V%d OS:%@\n"), bufstr, pid, vers, osVersion ?: CFSTR("")); CFRelease(bufstr); CFReleaseNull(gestalt); diff --git a/OSX/sec/SOSCircle/Tool/keychain_log.m b/OSX/sec/SOSCircle/Tool/keychain_log.m index 65b4419b..8286b218 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_log.m +++ b/OSX/sec/SOSCircle/Tool/keychain_log.m @@ -44,8 +44,8 @@ #include -#include -#include +#include +#include #include #include @@ -94,13 +94,6 @@ static char *createDateStrNow() { return retval; } -// #include - -CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void); -CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey; -CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey; -CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey; - static char *CFDictionaryCopyCString(CFDictionaryRef dict, const void *key) { CFStringRef val = CFDictionaryGetValue(dict, key); char *retval = CFStringToCString(val); diff --git a/OSX/sec/SOSCircle/Tool/keychain_sync.h b/OSX/sec/SOSCircle/Tool/keychain_sync.h index 4ea67f28..a8918dc6 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_sync.h +++ b/OSX/sec/SOSCircle/Tool/keychain_sync.h @@ -57,14 +57,11 @@ SECURITY_COMMAND( " -4 delete engine state from the keychain\n" " -5 cleanup old KVS keys in KVS\n" " -6 [test]populate KVS with garbage KVS keys\n" - - "\n" - "IDS\n" - " -g set IDS device id\n" - " -p retrieve IDS device id\n" - " -x ping all devices in an IDS account\n" - " -w check IDS availability\n" - " -z retrieve IDS id through KeychainSyncingOverIDSProxy\n" + "\n" + "Circle Tools\n" + " --remove-peer SPID Remove a peer identified by the first 8 or more\n" + " characters of its spid. Specify multiple times to\n" + " remove more than one peer.\n" "\n" "Password\n" " -P [label:]password set password (optionally for a given label) for sync\n" @@ -81,8 +78,6 @@ SECURITY_COMMAND( " viewnames are: keychain|masterkey|iclouddrive|photos|cloudkit|escrow|fde|maildrop|icloudbackup|notes|imessage|appletv|homekit\n" " wifi|passwords|creditcards|icloudidentity|othersyncable\n" " -L list all known view and their status\n" - " -S [enable|disable|propertyname] enable, disable, or query my PeerInfo's Security Property set\n" - " propertynames are: hasentropy|screenlock|SEP|IOS\n" " -U purge private key material cache\n" " -V Report View Sync Status on all known clients.\n" " -Y Report yet to initial sync views\n" diff --git a/OSX/sec/SOSCircle/Tool/keychain_sync.m b/OSX/sec/SOSCircle/Tool/keychain_sync.m index 32136f94..8c013db4 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_sync.m +++ b/OSX/sec/SOSCircle/Tool/keychain_sync.m @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include @@ -153,6 +155,29 @@ static bool tryPassword(char *labelAndPassword, CFErrorRef *err) return returned; } +/* + * Prompt user, call SOSCCTryUserCredentials. + * Does not support optional label syntax like -T/-P. + * Returns true on success. + */ +static bool +promptAndTryPassword(CFErrorRef *error) +{ + bool success = false; + char passbuf[1024]; + CFDataRef password; + + if (readpassphrase("iCloud password: ", passbuf, sizeof(passbuf), RPP_REQUIRE_TTY) != NULL) { + password = CFDataCreate(NULL, (const UInt8 *)passbuf, strlen(passbuf)); + if (password != NULL) { + success = SOSCCTryUserCredentials(CFSTR("security command line tool"), password, error); + CFReleaseNull(password); + } + } + + return success; +} + static bool syncAndWait(CFErrorRef *err) { __block CFTypeRef objects = NULL; @@ -183,72 +208,6 @@ static bool syncAndWait(CFErrorRef *err) return false; } -static CFStringRef convertStringToProperty(char *propertyname) { - CFStringRef propertyspec = NULL; - - if(strcmp(propertyname, "hasentropy") == 0) { - propertyspec = kSOSSecPropertyHasEntropy; - } else if(strcmp(propertyname, "screenlock") == 0) { - propertyspec = kSOSSecPropertyScreenLock; - } else if(strcmp(propertyname, "SEP") == 0) { - propertyspec = kSOSSecPropertySEP; - } else if(strcmp(propertyname, "IOS") == 0) { - propertyspec = kSOSSecPropertyIOS; - } - return propertyspec; -} - - -static CFStringRef convertPropertyReturnCodeToString(SOSSecurityPropertyResultCode ac) { - CFStringRef retval = NULL; - switch(ac) { - case kSOSCCGeneralSecurityPropertyError: - retval = CFSTR("General Error"); break; - case kSOSCCSecurityPropertyValid: - retval = CFSTR("Is Member of Security Property"); break; - case kSOSCCSecurityPropertyNotValid: - retval = CFSTR("Is Not Member of Security Property"); break; - case kSOSCCSecurityPropertyNotQualified: - retval = CFSTR("Is not qualified for Security Property"); break; - case kSOSCCNoSuchSecurityProperty: - retval = CFSTR("No Such Security Property"); break; - } - return retval; -} - - -static bool SecPropertycmd(char *itemName, CFErrorRef *err) { - char *cmd, *propertyname; - SOSSecurityPropertyActionCode ac = kSOSCCSecurityPropertyQuery; - CFStringRef propertyspec; - - propertyname = strchr(itemName, ':'); - if(propertyname == NULL) return false; - *propertyname = 0; - propertyname++; - cmd = itemName; - - if(strcmp(cmd, "enable") == 0) { - ac = kSOSCCSecurityPropertyEnable; - } else if(strcmp(cmd, "disable") == 0) { - ac = kSOSCCSecurityPropertyDisable; - } else if(strcmp(cmd, "query") == 0) { - ac = kSOSCCSecurityPropertyQuery; - } else { - return false; - } - - propertyspec = convertStringToProperty(propertyname); - if(!propertyspec) return false; - - SOSSecurityPropertyResultCode rc = SOSCCSecurityProperty(propertyspec, ac, err); - CFStringRef resultString = convertPropertyReturnCodeToString(rc); - - printmsg(CFSTR("Property Result: %@ : %@\n"), resultString, propertyspec); - return true; -} - - static void dumpStringSet(CFStringRef label, CFSetRef s) { if(!s || !label) return; @@ -291,21 +250,21 @@ static bool dumpMyPeer(CFErrorRef *error) { CFBooleanRef preferIDSACKModel = SOSPeerInfoV2DictionaryCopyBoolean(myPeer, sPreferIDSACKModel); CFStringRef transportType = SOSPeerInfoV2DictionaryCopyString(myPeer, sTransportType); CFStringRef idsDeviceID = SOSPeerInfoV2DictionaryCopyString(myPeer, sDeviceID); - CFMutableSetRef properties = SOSPeerInfoV2DictionaryCopySet(myPeer, sSecurityPropertiesKey); - + printmsg(CFSTR("Serial#: %@ PrefIDS#: %@ PrefFragmentation#: %@ PrefACK#: %@ transportType#: %@ idsDeviceID#: %@\n"), serialNumber, preferIDS, preferIDSFragmentation, preferIDSACKModel, transportType, idsDeviceID); + + printmsg(CFSTR("Serial#: %@\n"), + serialNumber); dumpStringSet(CFSTR(" Views: "), views); - dumpStringSet(CFSTR("SecurityProperties: "), properties); - + + CFReleaseSafe(serialNumber); CFReleaseSafe(preferIDS); CFReleaseSafe(preferIDSFragmentation); CFReleaseSafe(views); CFReleaseSafe(transportType); CFReleaseSafe(idsDeviceID); - CFReleaseSafe(properties); - } bool ret = myPeer != NULL; @@ -393,6 +352,107 @@ static bool dumpYetToSync(CFErrorRef *error) { return !hadError; } +#pragma mark - +#pragma mark --remove-peer + +static void +add_matching_peerinfos(CFMutableArrayRef list, CFArrayRef spids, CFArrayRef (*copy_peer_func)(CFErrorRef *)) +{ + CFErrorRef error; + CFArrayRef peers; + SOSPeerInfoRef pi; + CFStringRef spid; + CFIndex i, j; + + peers = copy_peer_func(&error); + if (peers != NULL) { + for (i = 0; i < CFArrayGetCount(peers); i++) { + pi = (SOSPeerInfoRef)CFArrayGetValueAtIndex(peers, i); + for (j = 0; j < CFArrayGetCount(spids); j++) { + spid = (CFStringRef)CFArrayGetValueAtIndex(spids, j); + if (CFStringGetLength(spid) < 8) { + continue; + } + if (CFStringHasPrefix(SOSPeerInfoGetPeerID(pi), spid)) { + CFArrayAppendValue(list, pi); + } + } + } + CFRelease(peers); + } else { + // unlikely + CFShow(error); + CFRelease(error); + } +} + +static CFArrayRef +copy_peerinfos(CFArrayRef spids) +{ + CFMutableArrayRef matches; + + matches = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + add_matching_peerinfos(matches, spids, SOSCCCopyValidPeerPeerInfo); + add_matching_peerinfos(matches, spids, SOSCCCopyNotValidPeerPeerInfo); + add_matching_peerinfos(matches, spids, SOSCCCopyRetirementPeerInfo); + + return matches; +} + +static bool +doRemovePeers(CFArrayRef peerids, CFErrorRef *error) +{ + bool success = false; + CFArrayRef peers = NULL; + CFErrorRef localError = NULL; + CFIndex i; + char buf[16]; + + peers = copy_peerinfos(peerids); + if (peers == NULL || CFArrayGetCount(peers) == 0) { + fprintf(stdout, "No matching peers to remove.\n"); + success = true; + goto done; + } + + fprintf(stdout, "Matched the following devices:\n"); + for (i = 0; i < CFArrayGetCount(peers); i++) { + // Ugly. + CFShow(CFArrayGetValueAtIndex(peers, i)); + } + + if (readpassphrase("Confirm removal (y/N): ", buf, sizeof(buf), RPP_ECHO_ON | RPP_FORCEUPPER) == NULL) { + goto done; + } + + if (buf[0] != 'Y') { + success = true; + goto done; + } + + success = SOSCCRemovePeersFromCircle(peers, &localError); + if (!success && isSOSErrorCoded(localError, kSOSErrorPrivateKeyAbsent)) { + CFReleaseNull(localError); + + success = promptAndTryPassword(&localError); + if (success) { + success = SOSCCRemovePeersFromCircle(peers, &localError); + } + } + +done: + CFReleaseNull(peers); + + if (!success && error != NULL) { + *error = localError; + } else { + CFReleaseNull(localError); + } + + return success; +} + +#pragma mark - // enable, disable, accept, reject, status, Reset, Clear int @@ -430,13 +490,6 @@ keychain_sync(int argc, char * const *argv) " -4 delete engine state from the keychain" " -5 cleanup old KVS keys in KVS" " -6 [test]populate KVS with garbage KVS keys - " - "IDS" - " -g set IDS device id" - " -p retrieve IDS device id" - " -x ping all devices in an IDS account" - " -w check IDS availability" - " -z retrieve IDS id through KeychainSyncingOverIDSProxy" " "Password" " -P [label:]password set password (optionally for a given label) for sync" @@ -453,20 +506,27 @@ keychain_sync(int argc, char * const *argv) " viewnames are: keychain|masterkey|iclouddrive|photos|cloudkit|escrow|fde|maildrop|icloudbackup|notes|imessage|appletv|homekit|" " wifi|passwords|creditcards|icloudidentity|othersyncable" " -L list all known view and their status" - " -S [enable|disable|propertyname] enable, disable, or query my PeerInfo's Security Property set" - " propertynames are: hasentropy|screenlock|SEP|IOS\n" " -U purge private key material cache\n" " -V Report View Sync Status on all known clients.\n" " -H Set escrow record.\n" " -J Get the escrow record.\n" " -M Check peer availability.\n" */ - int ch, result = 0; + enum { + SYNC_REMOVE_PEER, + }; + int action = -1; + const struct option longopts[] = { + { "remove-peer", required_argument, &action, SYNC_REMOVE_PEER, }, + { NULL, 0, NULL, 0, }, + }; + int ch, result = 0; CFErrorRef error = NULL; bool hadError = false; + CFMutableArrayRef peers2remove = NULL; SOSLogSetOutputTo(NULL, NULL); - while ((ch = getopt(argc, argv, "ab:deg:hikl:mopq:rSv:w:x:zA:B:MNJCDEF:HG:ILOP:RT:UWX:VY0123456")) != -1) + while ((ch = getopt_long(argc, argv, "ab:deg:hikl:mopq:rSv:w:x:zA:B:MNJCDEF:HG:ILOP:RT:UWX:VY0123456", longopts, NULL)) != -1) switch (ch) { case 'l': { @@ -503,69 +563,6 @@ keychain_sync(int argc, char * const *argv) notify_post(kSOSCCCircleChangedNotification); break; } - - case 'p': - { - fprintf(outFile, "Grabbing DS ID\n"); - CFStringRef deviceID = SOSCCCopyDeviceID(&error); - if (error) { - hadError = true; - break; - } - if (!isNull(deviceID)) { - const char *id = CFStringGetCStringPtr(deviceID, kCFStringEncodingUTF8); - if (id) - fprintf(outFile, "IDS Device ID: %s\n", id); - else - fprintf(outFile, "IDS Device ID is null!\n"); - } - CFReleaseNull(deviceID); - break; - } - - case 'g': - { - fprintf(outFile, "Setting DS ID: %s\n", optarg); - CFStringRef deviceID = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); - hadError = SOSCCSetDeviceID(deviceID, &error); - CFReleaseNull(deviceID); - break; - } - - case 'w': - { - fprintf(outFile, "Attempting to send this message over IDS: %s\n", optarg); - CFStringRef message = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); - hadError = SOSCCIDSServiceRegistrationTest(message, &error); - if (error) { - printerr(CFSTR("IDS is not ready: %@\n"), error); - CFRelease(error); - } - CFReleaseNull(message); - break; - } - - case 'x': - { - fprintf(outFile, "Starting ping test using this message: %s\n", optarg); - CFStringRef message = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); - hadError = SOSCCIDSPingTest(message, &error); - if (error) { - printerr(CFSTR("Ping test failed to start: %@\n"), error); - CFRelease(error); - } - CFReleaseNull(message); - break; - } - - case 'z': - hadError = SOSCCIDSDeviceIDIsAvailableTest(&error); - if (error) { - printerr(CFSTR("Failed to retrieve IDS device ID: %@\n"), error); - CFRelease(error); - } - break; - case 'e': fprintf(outFile, "Turning ON keychain syncing\n"); hadError = requestToJoinCircle(&error); @@ -782,15 +779,6 @@ keychain_sync(int argc, char * const *argv) CFReleaseNull(attempts); hadError = false; break; - } - case 'M': - { - bool success = SOSCCCheckPeerAvailability(&error); - if(success) - hadError = false; - else - hadError = true; - break; } case 'I': { @@ -864,10 +852,6 @@ keychain_sync(int argc, char * const *argv) hadError = !listviewcmd(&error); break; - case 'S': - hadError = !SecPropertycmd(optarg, &error); - break; - case 'b': hadError = setBag(optarg, &error); break; @@ -875,13 +859,35 @@ keychain_sync(int argc, char * const *argv) case 'Y': hadError = dumpYetToSync(&error); break; + case 0: + switch (action) { + case SYNC_REMOVE_PEER: { + CFStringRef optstr; + optstr = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8); + if (peers2remove == NULL) { + peers2remove = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + } + CFArrayAppendValue(peers2remove, optstr); + CFRelease(optstr); + break; + } + default: + return SHOW_USAGE_MESSAGE; + } + break; case '?': - default: - return SHOW_USAGE_MESSAGE; - } + default: + return SHOW_USAGE_MESSAGE; + } - if (hadError) + if (peers2remove != NULL) { + hadError = !doRemovePeers(peers2remove, &error); + CFRelease(peers2remove); + } + + if (hadError) { printerr(CFSTR("Error: %@\n"), error); + } - return result; + return result; } diff --git a/OSX/sec/Security/Regressions/Security_regressions.h b/OSX/sec/Security/Regressions/Security_regressions.h index 7c818088..b610bdf4 100644 --- a/OSX/sec/Security/Regressions/Security_regressions.h +++ b/OSX/sec/Security/Regressions/Security_regressions.h @@ -49,7 +49,6 @@ DISABLED_ONE_TEST(si_77_SecAccessControl) ONE_TEST(si_78_query_attrs) ONE_TEST(si_80_empty_data) ONE_TEST(si_82_token_ag) -ONE_TEST(si_89_cms_hash_agility) ONE_TEST(si_90_emcs) ONE_TEST(si_95_cms_basic) diff --git a/OSX/sec/Security/Regressions/crypto/pbkdf2-00-hmac-sha1.c b/OSX/sec/Security/Regressions/crypto/pbkdf2-00-hmac-sha1.c index 80c243df..66cda73d 100644 --- a/OSX/sec/Security/Regressions/crypto/pbkdf2-00-hmac-sha1.c +++ b/OSX/sec/Security/Regressions/crypto/pbkdf2-00-hmac-sha1.c @@ -25,17 +25,25 @@ hmac_sha1(const uint8_t *key, size_t key_len, const uint8_t *text, size_t text_l } static -void -pbkdf2_hmac_sha1_deriviation(const uint8_t *passphrase, size_t passphrase_length, +OSStatus +pbkdf2_hmac_sha1_derivation(const uint8_t *passphrase, size_t passphrase_length, const uint8_t *salt, size_t salt_length, size_t iterations, uint8_t *key_out, size_t key_length) { // MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20; - uint8_t temp_data[3*20+salt_length]; + uint8_t *temp_data = malloc(3*20+salt_length); + + if (temp_data == NULL) { + return errSecMemoryError; + } pbkdf2(hmac_sha1, 20, passphrase, passphrase_length, salt, salt_length, iterations, key_out, key_length, temp_data); + + free(temp_data); + + return errSecSuccess; } @@ -52,7 +60,7 @@ printComparison(const uint8_t*left, const uint8_t* right, int length) } #endif -static int kTestTestCount = 4; +static int kTestTestCount = 8; static void tests(void) { { @@ -69,9 +77,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha1_derivation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-1"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1"); } { @@ -88,9 +96,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha1_derivation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-2"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-2"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'Salt' I-2"); } { @@ -107,13 +115,13 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha1_derivation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-4096"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-4096"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'Salt' I-4096"); } SKIP: { - skip("16777216 iterations is too slow", 1, 0); + skip("16777216 iterations is too slow", 2, 0); const char *password = "password"; const char *salt = "salt"; @@ -128,9 +136,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha1_derivation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-16777216"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-16777216"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'Salt' I-16777216"); } } diff --git a/OSX/sec/Security/Regressions/crypto/spbkdf-00-hmac-sha1.c b/OSX/sec/Security/Regressions/crypto/spbkdf-00-hmac-sha1.c index 843dfb79..dc0065f2 100644 --- a/OSX/sec/Security/Regressions/crypto/spbkdf-00-hmac-sha1.c +++ b/OSX/sec/Security/Regressions/crypto/spbkdf-00-hmac-sha1.c @@ -13,7 +13,7 @@ #include "Security_regressions.h" -static int kTestTestCount = 8; +static int kTestTestCount = 16; static void tests(void) { @@ -31,9 +31,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-1"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-1"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-1"); } { @@ -50,9 +50,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-2"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-2"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-2"); } { @@ -69,9 +69,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-4096"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-4096"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-4096"); } SKIP: { @@ -90,9 +90,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-16777216"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-16777216"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-16777216"); } @@ -115,9 +115,9 @@ static void tests(void) CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize); CFDataIncreaseLength(resultData, resultSize); - SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData); + is(SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-1"); - ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-1"); + is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-1"); CFReleaseSafe(password); CFReleaseSafe(salt); @@ -145,9 +145,9 @@ static void tests(void) CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize); CFDataIncreaseLength(resultData, resultSize); - SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData); + is(SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-2"); - ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-2"); + is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-2"); CFReleaseSafe(password); CFReleaseSafe(salt); @@ -176,9 +176,9 @@ static void tests(void) CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize); CFDataIncreaseLength(resultData, resultSize); - SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData); + is(SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-4096"); - ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-4096"); + is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-4096"); CFReleaseSafe(password); CFReleaseSafe(salt); @@ -188,7 +188,7 @@ static void tests(void) } SKIP: { - skip("16777216 iterations is too slow", 1, 0); + skip("16777216 iterations is too slow", 2, 0); CFStringRef password = CFStringCreateWithCString(NULL, "password", kCFStringEncodingUTF8); CFStringRef salt = CFStringCreateWithCString(NULL, "salt", kCFStringEncodingUTF8); @@ -209,9 +209,9 @@ static void tests(void) CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize); CFDataIncreaseLength(resultData, resultSize); - SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData); + is(SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-16777216"); - ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-16777216"); + is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-16777216"); CFReleaseSafe(password); CFReleaseSafe(salt); diff --git a/OSX/sec/Security/Regressions/crypto/spbkdf-01-hmac-sha256.c b/OSX/sec/Security/Regressions/crypto/spbkdf-01-hmac-sha256.c index 744041a8..0ab1cf39 100644 --- a/OSX/sec/Security/Regressions/crypto/spbkdf-01-hmac-sha256.c +++ b/OSX/sec/Security/Regressions/crypto/spbkdf-01-hmac-sha256.c @@ -13,7 +13,7 @@ #include "Security_regressions.h" -static int kTestTestCount = 8; +static int kTestTestCount = 16; static void tests(void) { @@ -32,9 +32,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-1"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-1"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-1"); } { @@ -52,9 +52,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-2"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-2"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-2"); } { @@ -72,9 +72,9 @@ static void tests(void) uint8_t actual[resultSize]; - pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-4096"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-4096"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-4096"); } SKIP: { @@ -94,9 +94,9 @@ SKIP: { uint8_t actual[resultSize]; - pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize); + is(pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-16777216"); - ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-16777216"); + is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-16777216"); } @@ -120,9 +120,9 @@ SKIP: { CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize); CFDataIncreaseLength(resultData, resultSize); - SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData); + is(SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-1"); - ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-1"); + is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-1"); CFReleaseSafe(password); CFReleaseSafe(salt); @@ -151,9 +151,9 @@ SKIP: { CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize); CFDataIncreaseLength(resultData, resultSize); - SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData); + is(SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-2"); - ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-2"); + is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-2"); CFReleaseSafe(password); CFReleaseSafe(salt); @@ -182,9 +182,9 @@ SKIP: { CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize); CFDataIncreaseLength(resultData, resultSize); - SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData); + is(SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-4096"); - ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-4096"); + is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-4096"); CFReleaseSafe(password); CFReleaseSafe(salt); @@ -194,7 +194,7 @@ SKIP: { } SKIP: { - skip("16777216 iterations is too slow", 1, 0); + skip("16777216 iterations is too slow", 2, 0); CFStringRef password = CFStringCreateWithCString(NULL, "password", kCFStringEncodingUTF8); CFStringRef salt = CFStringCreateWithCString(NULL, "salt", kCFStringEncodingUTF8); @@ -216,9 +216,10 @@ SKIP: { CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize); CFDataIncreaseLength(resultData, resultSize); - SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData); + is(SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData), errSecSuccess, + "pbkdf-sha-256: P-'password' S-'salt' I-16777216"); - ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-16777216"); + is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-16777216"); CFReleaseSafe(password); CFReleaseSafe(salt); diff --git a/OSX/sec/Security/Regressions/secitem/si-10-find-internet.c b/OSX/sec/Security/Regressions/secitem/si-10-find-internet.c index 57694b9c..f4e4e76c 100644 --- a/OSX/sec/Security/Regressions/secitem/si-10-find-internet.c +++ b/OSX/sec/Security/Regressions/secitem/si-10-find-internet.c @@ -60,7 +60,7 @@ static void tests(void) CFReleaseNull(query2); query2 = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, results); CFReleaseNull(results); - CFDictionaryRemoveValue(query2, kSecAttrSHA1), + CFDictionaryRemoveValue(query2, kSecAttrSHA1); CFDictionarySetValue(query2, kSecClass, kSecClassInternetPassword); CFDictionarySetValue(query2, kSecReturnData, kCFBooleanTrue); ok_status(SecItemCopyMatching(query2, &results), "find internet password using returned attributes"); diff --git a/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m b/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m index bca3b341..edd8ed5e 100644 --- a/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m +++ b/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m @@ -100,11 +100,7 @@ static void test_key_failure(void) { SecKeyRef pubkey = NULL; require_action(cert, blockOut, fail("Failed to parse cert with SPKI error: %@", url)); -#if TARGET_OS_OSX - pubkey = SecCertificateCopyPublicKey_ios(cert); -#else - pubkey = SecCertificateCopyPublicKey(cert); -#endif + pubkey = SecCertificateCopyKey(cert); is(pubkey, NULL, "Successfully parsed bad SPKI: %@", url); blockOut: diff --git a/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c b/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c index 8f461216..396d72db 100644 --- a/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c +++ b/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c @@ -29,7 +29,7 @@ static void basic_tests(void) { SecTrustRef trust = NULL; CFArrayRef _anchors = NULL, certs = NULL, anchors = NULL, replacementPolicies; - SecCertificateRef cert0 = NULL, cert1 = NULL, _root = NULL, cert_xedge2 = NULL, garthc2 = NULL; + SecCertificateRef cert0 = NULL, cert1 = NULL, _anchor = NULL, cert_google = NULL, garthc2 = NULL; SecPolicyRef policy = NULL, replacementPolicy = NULL, replacementPolicy2 = NULL; CFDateRef date = NULL; CFDataRef c0_serial = NULL, serial = NULL; @@ -97,13 +97,9 @@ SKIP: { if (!cert0) { goto errOut; } c0_serial = CFDataCreate(NULL, _c0_serial, sizeof(_c0_serial)); -#if TARGET_OS_IPHONE - ok(serial = SecCertificateCopySerialNumber(cert0), "copy cert0 serial"); -#else CFErrorRef error = NULL; - ok(serial = SecCertificateCopySerialNumber(cert0, &error), "copy cert0 serial"); + ok(serial = SecCertificateCopySerialNumberData(cert0, &error), "copy cert0 serial"); CFReleaseNull(error); -#endif ok(CFEqual(c0_serial, serial), "serial matches"); CFReleaseNull(serial); CFReleaseNull(c0_serial); @@ -157,59 +153,56 @@ SKIP: { "trust is kSecTrustResultUnspecified"); is(SecTrustGetCertificateCount(trust), 3, "cert count is 3"); - /* Set certs to be the xedge2 leaf. */ + /* Set certs to be the www.google.com leaf. */ CFReleaseNull(certs); - isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_certificate, - sizeof(xedge2_certificate)), NULL, "create cert_xedge2"); - certs = CFArrayCreate(NULL, (const void **)&cert_xedge2, 1, &kCFTypeArrayCallBacks); + isnt(cert_google = SecCertificateCreateWithBytes(NULL, google_certificate, + sizeof(google_certificate)), NULL, "create cert_google"); + certs = CFArrayCreate(NULL, (const void **)&cert_google, 1, &kCFTypeArrayCallBacks); CFReleaseNull(trust); CFReleaseNull(policy); CFReleaseNull(date); bool server = true; - policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com")); + policy = SecPolicyCreateSSL(server, CFSTR("www.google.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), - "create trust for ssl server xedge2.apple.com"); + "create trust for ssl server www.google.com"); - /* This test uses a cert whose root is no longer in our trust store, - * so we need to explicitly set it as a trusted anchor - */ - isnt(_root = SecCertificateCreateWithBytes(NULL, entrust1024RootCA, sizeof(entrust1024RootCA)), + isnt(_anchor = SecCertificateCreateWithBytes(NULL, googleInternetAuthoritySubCA, sizeof(googleInternetAuthoritySubCA)), NULL, "create root"); - const void *v_roots[] = { _root }; - isnt(_anchors = CFArrayCreate(NULL, v_roots, array_size(v_roots), &kCFTypeArrayCallBacks), + const void *v_anchors[] = { _anchor }; + isnt(_anchors = CFArrayCreate(NULL, v_anchors, array_size(v_anchors), &kCFTypeArrayCallBacks), NULL, "create anchors"); if (!_anchors) { goto errOut; } ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors"); - /* Jan 1st 2009. */ - date = CFDateCreate(NULL, 252288000.0); - ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); - ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); + /* May 23, 2018. */ + date = CFDateCreate(NULL, 548800000.0); + ok_status(SecTrustSetVerifyDate(trust, date), "set www.google.com trust date to May 23, 2018"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate www.google.com trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); CFReleaseNull(trust); CFReleaseNull(policy); server = false; - policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com")); + policy = SecPolicyCreateSSL(server, CFSTR("www.google.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), - "create trust for ssl client xedge2.apple.com"); + "create trust for ssl client www.google.com"); ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors"); - ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); - ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); + ok_status(SecTrustSetVerifyDate(trust, date), "set google trust date to May 23, 2018"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate google trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); CFReleaseNull(trust); CFReleaseNull(policy); server = true; - policy = SecPolicyCreateIPSec(server, CFSTR("xedge2.apple.com")); + policy = SecPolicyCreateIPSec(server, CFSTR("www.google.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), - "create trust for ip server xedge2.apple.com"); + "create trust for ip server www.google.com"); ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors"); - ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); - ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); + ok_status(SecTrustSetVerifyDate(trust, date), "set www.apple.com trust date to May 23, 2018"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate www.google.com trust"); #if 0 /* Although this shouldn't be a valid ipsec cert, since we no longer check for ekus in the ipsec policy it is. */ @@ -226,12 +219,12 @@ SKIP: { policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ssl server nowhere.com"); - replacementPolicy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com")); + replacementPolicy = SecPolicyCreateSSL(server, CFSTR("www.google.com")); SecTrustSetPolicies(trust, replacementPolicy); CFReleaseNull(replacementPolicy); ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors"); - ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); - ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); + ok_status(SecTrustSetVerifyDate(trust, date), "set www.google.com trust date to May 23, 2018"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate www.google.com trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); @@ -241,14 +234,14 @@ SKIP: { policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ssl server nowhere.com"); - replacementPolicy2 = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com")); + replacementPolicy2 = SecPolicyCreateSSL(server, CFSTR("www.google.com")); replacementPolicies = CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)&replacementPolicy2, 1, &kCFTypeArrayCallBacks); SecTrustSetPolicies(trust, replacementPolicies); CFReleaseNull(replacementPolicy2); CFReleaseNull(replacementPolicies); ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors"); - ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); - ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); + ok_status(SecTrustSetVerifyDate(trust, date), "set www.google.com trust date to May 23, 2018"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate www.google.com trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); @@ -261,7 +254,7 @@ SKIP: { isnt(garthc2 = SecCertificateCreateWithBytes(NULL, garthc2_certificate, sizeof(garthc2_certificate)), NULL, "create garthc2"); certs = CFArrayCreate(NULL, (const void **)&garthc2, 1, &kCFTypeArrayCallBacks); - policy = SecPolicyCreateSSL(server, CFSTR("garthc2.apple.com")); + policy = SecPolicyCreateSSL(server, NULL); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ip server garthc2.apple.com"); date = CFDateCreate(NULL, 269568000.0); @@ -277,7 +270,7 @@ SKIP: { errOut: CFReleaseSafe(garthc2); - CFReleaseSafe(cert_xedge2); + CFReleaseSafe(cert_google); CFReleaseSafe(anchors); CFReleaseSafe(trust); CFReleaseSafe(serial); @@ -288,7 +281,7 @@ errOut: CFReleaseSafe(cert1); CFReleaseSafe(date); - CFReleaseSafe(_root); + CFReleaseSafe(_anchor); CFReleaseSafe(_anchors); } @@ -336,7 +329,7 @@ static void rsa8k_tests(void) CFArrayRef certs = NULL; isnt(certs = CFArrayCreate(NULL, &prt_forest_fi, 1, &kCFTypeArrayCallBacks), NULL, "failed to create cert array"); SecPolicyRef policy = NULL; - isnt(policy = SecPolicyCreateSSL(false, CFSTR("owa.prt-forest.fi")), NULL, "failed to create policy"); + isnt(policy = SecPolicyCreateSSL(true, CFSTR("owa.prt-forest.fi")), NULL, "failed to create policy"); SecTrustRef trust = NULL; ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ip client owa.prt-forest.fi"); @@ -893,14 +886,86 @@ static void test_tls_analytics_report(void) CFErrorRef error = NULL; bool reported = SecTrustReportTLSAnalytics(CFSTR("TLSConnectionEvent"), metric, &error); ok(reported, "Failed to report analytics with error %@", error); + xpc_release(metric); +} + +static void test_weak_signature(void) { + SecCertificateRef md5_root = NULL, md5_leaf = NULL, sha256_root = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFArrayRef certs = NULL, anchors = NULL; + CFDateRef verifyDate = NULL; + CFErrorRef error = NULL; + + require_action(md5_root = SecCertificateCreateWithBytes(NULL, _md5_root, sizeof(_md5_root)), errOut, + fail("failed to create md5 root cert")); + require_action(md5_leaf = SecCertificateCreateWithBytes(NULL, _md5_leaf, sizeof(_md5_leaf)), errOut, + fail("failed to create md5 leaf cert")); + require_action(sha256_root = SecCertificateCreateWithBytes(NULL, _sha256_root, sizeof(_sha256_root)), errOut, + fail("failed to create sha256 root cert")); + + require_action(certs = CFArrayCreate(NULL, (const void **)&md5_root, 1, &kCFTypeArrayCallBacks), errOut, + fail("failed to create certs array")); + require_action(anchors = CFArrayCreate(NULL, (const void **)&md5_root, 1, &kCFTypeArrayCallBacks), errOut, + fail("failed to create anchors array")); + require_action(policy = SecPolicyCreateBasicX509(), errOut, fail("failed to make policy")); + require_action(verifyDate = CFDateCreate(NULL, 550600000), errOut, fail("failed to make verification date")); // June 13, 2018 + + /* Test self-signed MD5 cert. Should work since cert is a trusted anchor - rdar://39152516 */ + require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, + fail("failed to create trust object")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, + fail("faild to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, + fail("failed to set verify date")); + ok(SecTrustEvaluateWithError(trust, &error), "self-signed MD5 cert failed"); + is(error, NULL, "got a trust error for self-signed MD5 cert: %@", error); + + /* clean up and set up for next test */ + CFReleaseNull(error); + CFReleaseNull(trust); + CFReleaseNull(anchors); + CFReleaseNull(certs); + + require_action(certs = CFArrayCreate(NULL, (const void **)&md5_leaf, 1, &kCFTypeArrayCallBacks), errOut, + fail("failed to create certs array")); + require_action(anchors = CFArrayCreate(NULL, (const void **)&sha256_root, 1, &kCFTypeArrayCallBacks), errOut, + fail("failed to create anchors array")); + + + /* Test non-self-signed MD5 cert. Should fail. */ + require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, + fail("failed to create trust object")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, + fail("faild to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, + fail("failed to set verify date")); + is(SecTrustEvaluateWithError(trust, &error), false, "non-self-signed MD5 cert succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecInvalidDigestAlgorithm, "got wrong error code for MD5 leaf cert, got %ld, expected %d", + (long)CFErrorGetCode(error), errSecInvalidDigestAlgorithm); + } else { + fail("expected trust evaluation to fail and it did not."); + } + +errOut: + CFReleaseNull(md5_root); + CFReleaseNull(md5_leaf); + CFReleaseNull(sha256_root); + CFReleaseNull(certs); + CFReleaseNull(anchors); + CFReleaseNull(policy); + CFReleaseNull(verifyDate); + CFReleaseNull(trust); + CFReleaseNull(error); } int si_20_sectrust(int argc, char *const *argv) { #if TARGET_OS_IPHONE - plan_tests(101+9+(8*13)+9+1+2+17+2+9+2); + plan_tests(101+9+(8*13)+9+1+2+17+2+9+2+4); #else - plan_tests(97+9+(8*13)+9+1+2+2+17+2+9+2); + plan_tests(97+9+(8*13)+9+1+2+2+17+2+9+2+4); #endif basic_tests(); @@ -916,6 +981,7 @@ int si_20_sectrust(int argc, char *const *argv) test_optional_policy_check(); test_serialization(); test_tls_analytics_report(); + test_weak_signature(); return 0; } diff --git a/OSX/sec/Security/Regressions/secitem/si-20-sectrust.h b/OSX/sec/Security/Regressions/secitem/si-20-sectrust.h index 5c08d4c6..4f2ae6b8 100644 --- a/OSX/sec/Security/Regressions/secitem/si-20-sectrust.h +++ b/OSX/sec/Security/Regressions/secitem/si-20-sectrust.h @@ -222,180 +222,147 @@ static const uint8_t _c1[] = { }; -/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Operations/CN=xedge2.apple.com - issuer :/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority */ -const uint8_t xedge2_certificate[1385]={ - 0x30,0x82,0x05,0x65,0x30,0x82,0x04,0xCE,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x46, - 0x9C,0xDF,0x96,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, - 0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, - 0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74, - 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04, - 0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, - 0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62, - 0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C, - 0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C, - 0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74, - 0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38, - 0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, - 0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72, - 0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41, - 0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x31, - 0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x32, - 0x38,0x31,0x39,0x30,0x33,0x31,0x32,0x5A,0x30,0x81,0x83,0x31,0x0B,0x30,0x09,0x06, - 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04, - 0x08,0x13,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30, - 0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E, - 0x6F,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x13,0x09,0x41,0x70,0x70,0x6C, - 0x65,0x20,0x49,0x6E,0x63,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x13,0x13, - 0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,0x4F,0x70,0x65,0x72,0x61,0x74,0x69, - 0x6F,0x6E,0x73,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x78,0x65, - 0x64,0x67,0x65,0x32,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x81, - 0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00, - 0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC7,0xF3,0xA1,0x0E,0x0E, - 0xA4,0xDF,0xC5,0x3F,0x24,0x87,0xC3,0x6E,0xE7,0xD0,0x7C,0x2B,0x5A,0x1C,0xF3,0x67, - 0x6C,0x6B,0x56,0x0A,0x95,0xC9,0xE5,0x13,0x28,0x6E,0x16,0x9D,0x4F,0xB1,0x76,0xFB, - 0x7D,0x42,0x5B,0x2A,0x7C,0xCC,0x97,0x75,0xAA,0xA6,0xA9,0xDE,0xB2,0xEC,0xEF,0xE2, - 0xAB,0x40,0xAE,0x9A,0x23,0xF0,0x6A,0x10,0xB3,0x75,0x27,0xF0,0xF4,0x7D,0x08,0x67, - 0x8F,0xCE,0x41,0x24,0x74,0xAA,0x37,0xB6,0xC1,0x32,0x61,0xCF,0x7D,0x1C,0x21,0xCD, - 0xCF,0x7C,0x9E,0xE2,0x48,0x03,0x7E,0x78,0xB3,0x86,0x3D,0x06,0x6B,0x39,0xEC,0xC8, - 0x73,0x68,0xDB,0xE7,0x5B,0x97,0xF4,0xF9,0xA3,0xE7,0xFB,0x81,0x2E,0x4D,0x0B,0x3F, - 0xA9,0xCA,0xDE,0x32,0x26,0xF3,0xF0,0x97,0x72,0x65,0xAB,0x02,0x03,0x01,0x00,0x01, - 0xA3,0x82,0x02,0xA2,0x30,0x82,0x02,0x9E,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04, - 0x04,0x03,0x02,0x05,0xA0,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,0x22, - 0x80,0x0F,0x32,0x30,0x30,0x38,0x30,0x31,0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33, - 0x5A,0x81,0x0F,0x32,0x30,0x31,0x30,0x30,0x31,0x32,0x38,0x31,0x39,0x30,0x33,0x31, - 0x32,0x5A,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04, - 0x04,0x03,0x02,0x06,0x40,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A, - 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x82,0x01,0x68,0x06,0x03, - 0x55,0x1D,0x20,0x04,0x82,0x01,0x5F,0x30,0x82,0x01,0x5B,0x30,0x82,0x01,0x57,0x06, - 0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x4B,0x02,0x30,0x82,0x01,0x48,0x30,0x26, - 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70, - 0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, - 0x65,0x74,0x2F,0x63,0x70,0x73,0x30,0x82,0x01,0x1C,0x06,0x08,0x2B,0x06,0x01,0x05, - 0x05,0x07,0x02,0x02,0x30,0x82,0x01,0x0E,0x1A,0x82,0x01,0x0A,0x54,0x68,0x65,0x20, - 0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x53,0x53,0x4C,0x20,0x57,0x65,0x62,0x20, - 0x53,0x65,0x72,0x76,0x65,0x72,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,0x20,0x28,0x43,0x50,0x53,0x29,0x20,0x61,0x76, - 0x61,0x69,0x6C,0x61,0x62,0x6C,0x65,0x20,0x61,0x74,0x20,0x77,0x77,0x77,0x2E,0x65, - 0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x63,0x70,0x73,0x20,0x20, - 0x69,0x73,0x20,0x68,0x65,0x72,0x65,0x62,0x79,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70, - 0x6F,0x72,0x61,0x74,0x65,0x64,0x20,0x69,0x6E,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72, - 0x20,0x75,0x73,0x65,0x20,0x6F,0x72,0x20,0x72,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65, - 0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69, - 0x63,0x61,0x74,0x65,0x2E,0x20,0x20,0x54,0x68,0x69,0x73,0x20,0x43,0x50,0x53,0x20, - 0x63,0x6F,0x6E,0x74,0x61,0x69,0x6E,0x73,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74, - 0x69,0x6F,0x6E,0x73,0x20,0x6F,0x6E,0x20,0x77,0x61,0x72,0x72,0x61,0x6E,0x74,0x69, - 0x65,0x73,0x20,0x61,0x6E,0x64,0x20,0x6C,0x69,0x61,0x62,0x69,0x6C,0x69,0x74,0x69, - 0x65,0x73,0x2E,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63, - 0x29,0x20,0x32,0x30,0x30,0x32,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x4C, - 0x69,0x6D,0x69,0x74,0x65,0x64,0x30,0x33,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2C,0x30, - 0x2A,0x30,0x28,0xA0,0x26,0xA0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, - 0x63,0x72,0x6C,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F, - 0x73,0x65,0x72,0x76,0x65,0x72,0x31,0x2E,0x63,0x72,0x6C,0x30,0x33,0x06,0x08,0x2B, - 0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x27,0x30,0x25,0x30,0x23,0x06,0x08,0x2B, - 0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x17,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, - 0x6F,0x63,0x73,0x70,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74, - 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62, - 0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0, - 0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2D,0xEF,0xD9,0xAF, - 0x1A,0x89,0x40,0x53,0x75,0x48,0x26,0x59,0x2F,0xEC,0x11,0x18,0xC0,0xD1,0x7A,0x34, - 0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x19,0x06,0x09,0x2A, - 0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B,0x04,0x56,0x37, - 0x2E,0x31,0x03,0x02,0x03,0x28,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, - 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x77,0x33,0x2A,0x69,0x45,0x5A,0xB2, - 0xF5,0x74,0xF7,0xDF,0xC7,0x08,0x85,0x86,0x88,0x98,0x41,0x7F,0x57,0x49,0x01,0xBA, - 0x13,0x21,0x40,0xD0,0x0A,0x5C,0xA7,0x37,0xDF,0xB3,0x7E,0xF8,0xED,0x04,0x63,0xC3, - 0xE8,0x0F,0xA0,0xE5,0xC4,0x4F,0x3A,0x90,0xE4,0x87,0x5F,0xEC,0xDB,0x65,0x8B,0x6E, - 0x88,0x6E,0x6E,0xE4,0xBC,0x6A,0x7E,0x37,0x47,0x04,0xFF,0x09,0xC6,0x70,0xE1,0x65, - 0x8F,0xE3,0xE9,0x60,0xEB,0xE8,0x8E,0x29,0xAE,0xF9,0x81,0xCA,0x9A,0x97,0x3C,0x6F, - 0x7C,0xFA,0xA8,0x49,0xB4,0x33,0x76,0x9C,0x65,0x92,0x12,0xF6,0x7F,0x6A,0x62,0x84, - 0x29,0x5F,0x14,0x26,0x6E,0x07,0x6F,0x5C,0xB5,0x7C,0x21,0x64,0x7C,0xD9,0x93,0xF4, - 0x9C,0xC8,0xE7,0xEC,0xC6,0xAC,0x13,0xC4,0xF0 +/* subject:/C=US/ST=California/L=Mountain View/O=Google LLC/CN=www.google.com */ +/* issuer :/C=US/O=Google Trust Services/CN=Google Internet Authority G3 */ +const uint8_t google_certificate[]={ + 0x30,0x82,0x03,0xC7,0x30,0x82,0x02,0xAF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x55, + 0x81,0x47,0xC4,0x26,0x8C,0x3F,0xC2,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, + 0x06,0x13,0x02,0x55,0x53,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15, + 0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x53,0x65,0x72, + 0x76,0x69,0x63,0x65,0x73,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x03,0x13,0x1C, + 0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20, + 0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D, + 0x31,0x38,0x30,0x35,0x30,0x38,0x31,0x34,0x34,0x37,0x34,0x33,0x5A,0x17,0x0D,0x31, + 0x38,0x30,0x37,0x33,0x31,0x31,0x33,0x32,0x37,0x30,0x30,0x5A,0x30,0x68,0x31,0x0B, + 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06, + 0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61, + 0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74, + 0x61,0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04, + 0x0A,0x0C,0x0A,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x4C,0x4C,0x43,0x31,0x17,0x30, + 0x15,0x06,0x03,0x55,0x04,0x03,0x0C,0x0E,0x77,0x77,0x77,0x2E,0x67,0x6F,0x6F,0x67, + 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,0xDD,0x10,0xCB,0x4F,0xB1,0x49,0xF9,0xE8,0xC2,0x8E,0xB5,0xB9,0xC3,0x7D,0xCC, + 0x9D,0x94,0x3A,0x91,0x19,0x7C,0xA9,0xB3,0x78,0x81,0x21,0x01,0xC0,0x76,0x12,0xA9, + 0x84,0x65,0xDF,0xD3,0xE2,0x51,0xFF,0x17,0x9F,0x69,0x0F,0x0B,0xFA,0x04,0x0D,0xBA, + 0x35,0xBB,0xE8,0x1F,0x14,0x66,0xB7,0xC7,0xD7,0xFC,0xEB,0x10,0xD6,0xCD,0x79,0x8A, + 0x22,0xA3,0x82,0x01,0x52,0x30,0x82,0x01,0x4E,0x30,0x13,0x06,0x03,0x55,0x1D,0x25, + 0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x0E, + 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x19, + 0x06,0x03,0x55,0x1D,0x11,0x04,0x12,0x30,0x10,0x82,0x0E,0x77,0x77,0x77,0x2E,0x67, + 0x6F,0x6F,0x67,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x68,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x01,0x01,0x04,0x5C,0x30,0x5A,0x30,0x2D,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x30,0x02,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x70,0x6B, + 0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x67,0x73,0x72,0x32,0x2F,0x47,0x54,0x53,0x47, + 0x49,0x41,0x47,0x33,0x2E,0x63,0x72,0x74,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05, + 0x05,0x07,0x30,0x01,0x86,0x1D,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73, + 0x70,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x47,0x54,0x53,0x47,0x49, + 0x41,0x47,0x33,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2B,0x53, + 0xE0,0x79,0xD4,0xFD,0xA4,0xD4,0xDF,0x18,0x6B,0xDD,0x80,0x4D,0x11,0x35,0xC7,0xB2, + 0x41,0xCC,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,0x77,0xC2,0xB8, + 0x50,0x9A,0x67,0x76,0x76,0xB1,0x2D,0xC2,0x86,0xD0,0x83,0xA0,0x7E,0xA6,0x7E,0xBA, + 0x4B,0x30,0x21,0x06,0x03,0x55,0x1D,0x20,0x04,0x1A,0x30,0x18,0x30,0x0C,0x06,0x0A, + 0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x05,0x03,0x30,0x08,0x06,0x06,0x67,0x81, + 0x0C,0x01,0x02,0x02,0x30,0x31,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2A,0x30,0x28,0x30, + 0x26,0xA0,0x24,0xA0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72, + 0x6C,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x47,0x54,0x53,0x47,0x49, + 0x41,0x47,0x33,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6E,0x85,0x02,0xC0,0xF0, + 0x15,0xBF,0xAF,0x4F,0x29,0x73,0x19,0x87,0x7F,0x30,0xB3,0x24,0xD1,0xEE,0xA7,0xDC, + 0x90,0x44,0x30,0xC1,0xA0,0x84,0x65,0x52,0x26,0xE6,0xAD,0x0D,0xCA,0x43,0xEE,0xB6, + 0x6B,0x37,0x9D,0xFF,0x97,0x80,0x09,0x85,0x58,0x46,0xEC,0xFF,0xF2,0x42,0x6A,0xBB, + 0xE6,0xA3,0xB4,0x9B,0x26,0x26,0xA8,0x53,0xA9,0xB9,0x95,0xB6,0x42,0x06,0x94,0xED, + 0x31,0xC5,0x33,0xF7,0x91,0x6A,0x90,0x4B,0xD2,0x8A,0x45,0xAE,0x3A,0xA0,0x10,0x27, + 0xAE,0xF4,0x9A,0xC9,0x5E,0x63,0x20,0xAD,0xF2,0xCB,0xDC,0x74,0xA8,0x83,0x32,0x56, + 0x6D,0xAA,0x6C,0xCA,0xBC,0xCC,0x71,0x23,0xD4,0xAC,0xA9,0xAE,0xEA,0x04,0xD6,0x75, + 0xE7,0xBF,0x18,0xC7,0x9C,0xCC,0x7B,0xE6,0x81,0x62,0xC6,0xFA,0x17,0xA8,0x82,0x2F, + 0xCC,0xE9,0xAC,0xEF,0x81,0xCC,0xAE,0x1A,0x1C,0x79,0x35,0x7B,0x54,0xFE,0x06,0x57, + 0x2F,0x58,0xD0,0x7C,0x4E,0x5A,0x75,0xAE,0xCC,0x31,0xD6,0x20,0xA6,0xB1,0xDA,0x39, + 0x9E,0x46,0x5B,0x15,0x76,0xF2,0x3E,0x2C,0xB1,0x5E,0xBF,0x7F,0x29,0xE3,0xBE,0xC6, + 0xF3,0xE5,0xEB,0xD5,0x91,0x48,0x84,0x41,0x7B,0xB6,0x3B,0x83,0xC6,0xCE,0x1B,0xE2, + 0x88,0x44,0x91,0x89,0x72,0x27,0xF9,0xD2,0x72,0x33,0xCF,0xC3,0xB2,0x52,0x38,0x65, + 0x17,0x14,0x00,0x4E,0x36,0x1C,0xC2,0xAD,0xBF,0x7F,0x3A,0x18,0xF7,0x52,0xFA,0x3B, + 0x86,0x18,0xF3,0x24,0x97,0xF7,0x35,0x58,0x48,0x0D,0x7D,0x93,0x18,0xA7,0x14,0x52, + 0x1A,0x19,0x9D,0xDB,0xD5,0xCC,0xA3,0xC5,0x48,0x6D,0x8A, }; -const uint8_t entrust1024RootCA[1244]={ - 0x30,0x82,0x04,0xD8,0x30,0x82,0x04,0x41,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x37, - 0x4A,0xD2,0x43,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, - 0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, - 0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74, - 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04, - 0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, - 0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62, - 0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C, - 0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C, - 0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74, - 0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38, - 0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, - 0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72, - 0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41, - 0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x35, - 0x32,0x35,0x31,0x36,0x30,0x39,0x34,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x35,0x32, - 0x35,0x31,0x36,0x33,0x39,0x34,0x30,0x5A,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06, - 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04, - 0x0A,0x13,0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B, - 0x30,0x39,0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74, - 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63, - 0x6F,0x72,0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69, - 0x6D,0x69,0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06, - 0x03,0x55,0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45, - 0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74, - 0x65,0x64,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74, - 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20, - 0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, - 0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x81, - 0x9D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00, - 0x03,0x81,0x8B,0x00,0x30,0x81,0x87,0x02,0x81,0x81,0x00,0xCD,0x28,0x83,0x34,0x54, - 0x1B,0x89,0xF3,0x0F,0xAF,0x37,0x91,0x31,0xFF,0xAF,0x31,0x60,0xC9,0xA8,0xE8,0xB2, - 0x10,0x68,0xED,0x9F,0xE7,0x93,0x36,0xF1,0x0A,0x64,0xBB,0x47,0xF5,0x04,0x17,0x3F, - 0x23,0x47,0x4D,0xC5,0x27,0x19,0x81,0x26,0x0C,0x54,0x72,0x0D,0x88,0x2D,0xD9,0x1F, - 0x9A,0x12,0x9F,0xBC,0xB3,0x71,0xD3,0x80,0x19,0x3F,0x47,0x66,0x7B,0x8C,0x35,0x28, - 0xD2,0xB9,0x0A,0xDF,0x24,0xDA,0x9C,0xD6,0x50,0x79,0x81,0x7A,0x5A,0xD3,0x37,0xF7, - 0xC2,0x4A,0xD8,0x29,0x92,0x26,0x64,0xD1,0xE4,0x98,0x6C,0x3A,0x00,0x8A,0xF5,0x34, - 0x9B,0x65,0xF8,0xED,0xE3,0x10,0xFF,0xFD,0xB8,0x49,0x58,0xDC,0xA0,0xDE,0x82,0x39, - 0x6B,0x81,0xB1,0x16,0x19,0x61,0xB9,0x54,0xB6,0xE6,0x43,0x02,0x01,0x03,0xA3,0x82, - 0x01,0xD7,0x30,0x82,0x01,0xD3,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8, - 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07,0x30,0x82,0x01,0x19,0x06,0x03,0x55, - 0x1D,0x1F,0x04,0x82,0x01,0x10,0x30,0x82,0x01,0x0C,0x30,0x81,0xDE,0xA0,0x81,0xDB, - 0xA0,0x81,0xD8,0xA4,0x81,0xD5,0x30,0x81,0xD2,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, - 0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13, - 0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39, - 0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75, - 0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72, - 0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69, - 0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55, - 0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74, - 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64, - 0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75, - 0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65, - 0x72,0x76,0x65,0x72,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,0x0D,0x30,0x0B, - 0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4C,0x31,0x30,0x29,0xA0,0x27,0xA0, - 0x25,0x86,0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E, - 0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x52,0x4C,0x2F,0x6E,0x65, - 0x74,0x31,0x2E,0x63,0x72,0x6C,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30, - 0x22,0x80,0x0F,0x31,0x39,0x39,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39,0x34, - 0x30,0x5A,0x81,0x0F,0x32,0x30,0x31,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39, - 0x34,0x30,0x5A,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x06, - 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62, - 0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0, - 0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xF0,0x17,0x62,0x13, - 0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,0x1A, - 0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x19, - 0x06,0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B, - 0x04,0x56,0x34,0x2E,0x30,0x03,0x02,0x04,0x90,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, - 0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x90,0xDC,0x30,0x02, - 0xFA,0x64,0x74,0xC2,0xA7,0x0A,0xA5,0x7C,0x21,0x8D,0x34,0x17,0xA8,0xFB,0x47,0x0E, - 0xFF,0x25,0x7C,0x8D,0x13,0x0A,0xFB,0xE4,0x98,0xB5,0xEF,0x8C,0xF8,0xC5,0x10,0x0D, - 0xF7,0x92,0xBE,0xF1,0xC3,0xD5,0xD5,0x95,0x6A,0x04,0xBB,0x2C,0xCE,0x26,0x36,0x65, - 0xC8,0x31,0xC6,0xE7,0xEE,0x3F,0xE3,0x57,0x75,0x84,0x7A,0x11,0xEF,0x46,0x4F,0x18, - 0xF4,0xD3,0x98,0xBB,0xA8,0x87,0x32,0xBA,0x72,0xF6,0x3C,0xE2,0x3D,0x9F,0xD7,0x1D, - 0xD9,0xC3,0x60,0x43,0x8C,0x58,0x0E,0x22,0x96,0x2F,0x62,0xA3,0x2C,0x1F,0xBA,0xAD, - 0x05,0xEF,0xAB,0x32,0x78,0x87,0xA0,0x54,0x73,0x19,0xB5,0x5C,0x05,0xF9,0x52,0x3E, - 0x6D,0x2D,0x45,0x0B,0xF7,0x0A,0x93,0xEA,0xED,0x06,0xF9,0xB2, +/* subject:/C=US/O=Google Trust Services/CN=Google Internet Authority G3 */ +/* issuer :/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign */ +const uint8_t googleInternetAuthoritySubCA[]={ + 0x30,0x82,0x04,0x5C,0x30,0x82,0x03,0x44,0xA0,0x03,0x02,0x01,0x02,0x02,0x0D,0x01, + 0xE3,0xA9,0x30,0x1C,0xFC,0x72,0x06,0x38,0x3F,0x9A,0x53,0x1D,0x30,0x0D,0x06,0x09, + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x4C,0x31,0x20,0x30, + 0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69, + 0x67,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x32,0x31, + 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C, + 0x53,0x69,0x67,0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47, + 0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30, + 0x36,0x31,0x35,0x30,0x30,0x30,0x30,0x34,0x32,0x5A,0x17,0x0D,0x32,0x31,0x31,0x32, + 0x31,0x35,0x30,0x30,0x30,0x30,0x34,0x32,0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06, + 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04, + 0x0A,0x13,0x15,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x54,0x72,0x75,0x73,0x74,0x20, + 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04, + 0x03,0x13,0x1C,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x49,0x6E,0x74,0x65,0x72,0x6E, + 0x65,0x74,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x47,0x33,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, + 0xCA,0x52,0x4B,0xEA,0x1E,0xFF,0xCE,0x24,0x6B,0xA8,0xDA,0x72,0x18,0x68,0xD5,0x56, + 0x5D,0x0E,0x48,0x5A,0x2D,0x35,0x09,0x76,0x5A,0xCF,0xA4,0xC8,0x1C,0xB1,0xA9,0xFE, + 0x53,0x89,0xFB,0xAD,0x34,0xFF,0x88,0x5B,0x9F,0xBB,0xE7,0xE8,0x00,0x01,0xDC,0x35, + 0x73,0x75,0x03,0xAD,0xB3,0xB1,0xB9,0xA4,0x7D,0x2B,0x26,0x79,0xCE,0x15,0x40,0x0A, + 0xEF,0x51,0xB8,0x9F,0x32,0x8C,0x7C,0x70,0x86,0x52,0x4B,0x16,0xFE,0x6A,0x27,0x6B, + 0xE6,0x36,0x7A,0x62,0x50,0xD8,0xDF,0x9A,0x89,0xCC,0x09,0x29,0xEB,0x4F,0x29,0x14, + 0x88,0x80,0x0B,0x8F,0x38,0x1E,0x80,0x6A,0x18,0x7C,0x1D,0xBD,0x97,0x3B,0x78,0x7D, + 0x45,0x49,0x36,0x4F,0x41,0xCD,0xA2,0xE0,0x76,0x57,0x3C,0x68,0x31,0x79,0x64,0xC9, + 0x6E,0xD7,0x51,0x1E,0x66,0xC3,0xA2,0x64,0x2C,0x79,0xC0,0xE7,0x65,0xC3,0x56,0x84, + 0x53,0x5A,0x43,0x6D,0xCB,0x9A,0x02,0x20,0xD2,0xEF,0x1A,0x69,0xD1,0xB0,0x9D,0x73, + 0xA2,0xE0,0x2A,0x60,0x65,0x50,0x31,0xCF,0xFB,0xB3,0x2F,0xBF,0x11,0x88,0x40,0x2E, + 0xB5,0x49,0x10,0x0F,0x0A,0x6E,0xDC,0x97,0xFA,0xBF,0x2C,0x9F,0x05,0x39,0x0B,0x58, + 0x54,0xAF,0x06,0x96,0xE8,0xC5,0x8E,0x01,0x16,0xBC,0xA8,0x1A,0x4D,0x41,0xC5,0x93, + 0x91,0xA2,0x1E,0xA1,0x8B,0xF2,0xFE,0xC1,0x88,0x24,0x49,0xA3,0x47,0x4B,0xC5,0x13, + 0x01,0xDD,0xA7,0x57,0x12,0x69,0x62,0x2B,0xEB,0xFE,0x20,0xEF,0x69,0xFB,0x3A,0xA5, + 0xF0,0x7E,0x29,0xEE,0xED,0x96,0x16,0xF7,0xB1,0x1F,0xA0,0xE4,0x90,0x25,0xE0,0x33, + 0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x33,0x30,0x82,0x01,0x2F,0x30,0x0E,0x06, + 0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x1D,0x06, + 0x03,0x55,0x1D,0x25,0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, + 0x03,0x01,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x12,0x06,0x03, + 0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00, + 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x77,0xC2,0xB8,0x50,0x9A, + 0x67,0x76,0x76,0xB1,0x2D,0xC2,0x86,0xD0,0x83,0xA0,0x7E,0xA6,0x7E,0xBA,0x4B,0x30, + 0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x9B,0xE2,0x07,0x57, + 0x67,0x1C,0x1E,0xC0,0x6A,0x06,0xDE,0x59,0xB4,0x9A,0x2D,0xDF,0xDC,0x19,0x86,0x2E, + 0x30,0x35,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x29,0x30,0x27, + 0x30,0x25,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x19,0x68,0x74, + 0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F, + 0x6F,0x67,0x2F,0x67,0x73,0x72,0x32,0x30,0x32,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2B, + 0x30,0x29,0x30,0x27,0xA0,0x25,0xA0,0x23,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F, + 0x2F,0x63,0x72,0x6C,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x67,0x73, + 0x72,0x32,0x2F,0x67,0x73,0x72,0x32,0x2E,0x63,0x72,0x6C,0x30,0x3F,0x06,0x03,0x55, + 0x1D,0x20,0x04,0x38,0x30,0x36,0x30,0x34,0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x02, + 0x30,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C, + 0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67, + 0x2F,0x72,0x65,0x70,0x6F,0x73,0x69,0x74,0x6F,0x72,0x79,0x2F,0x30,0x0D,0x06,0x09, + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00, + 0x1C,0xB7,0x89,0x96,0xE4,0x53,0xED,0xBB,0xEC,0xDB,0xA8,0x32,0x01,0x9F,0x2C,0xA3, + 0xCD,0x6D,0xAD,0x42,0x12,0x77,0xB3,0xB8,0xE6,0xC9,0x03,0x52,0x60,0x20,0x7B,0x57, + 0x27,0xC6,0x11,0xB5,0x3F,0x67,0x0D,0x99,0x2C,0x5B,0x5A,0xCA,0x22,0x0A,0xDD,0x9E, + 0xBB,0x1F,0x4B,0x48,0x3F,0x8F,0x02,0x3D,0x8B,0x21,0x84,0x45,0x1D,0x6D,0xF5,0xFF, + 0xAC,0x68,0x89,0xCD,0x64,0xE2,0xD6,0xD6,0x5E,0x40,0xC2,0x8E,0x2A,0xF7,0xEF,0x14, + 0xD3,0x36,0xA4,0x40,0x30,0xF5,0x32,0x15,0x15,0x92,0x76,0xFB,0x7E,0x9E,0x53,0xEA, + 0xC2,0x76,0xFC,0x39,0xAD,0x88,0xFE,0x66,0x92,0x26,0xE9,0x1C,0xC4,0x38,0xCD,0x49, + 0xFA,0x43,0x87,0xF0,0x5D,0xD6,0x56,0x4D,0x81,0xD7,0x7F,0xF1,0xC2,0xDD,0xB0,0x4D, + 0xFE,0xC3,0x2A,0x6E,0x7C,0x9F,0x6E,0x5C,0xED,0x62,0x42,0x99,0xE1,0xF7,0x36,0xEE, + 0x14,0x8C,0x2C,0x20,0xE3,0x46,0x97,0x5A,0x77,0x03,0xC0,0xA0,0xC6,0x4A,0x88,0xFD, + 0x40,0x22,0x87,0x72,0x5A,0x18,0xEA,0x9C,0xA5,0xC7,0x5A,0x08,0x8C,0xE4,0x05,0xA4, + 0x7D,0xB9,0x84,0x35,0x5F,0x89,0x36,0x56,0x0E,0x40,0x3D,0x12,0xE8,0xBB,0x35,0x72, + 0xED,0xAF,0x08,0x56,0x4E,0xB0,0xBB,0x2E,0xA9,0x9B,0xE4,0xFB,0x1D,0x3E,0x0B,0x63, + 0xC8,0x9B,0x4B,0x91,0x44,0x66,0x57,0xC0,0x14,0xB4,0x96,0xF0,0xDC,0x2C,0x57,0x3F, + 0x52,0x04,0xAD,0x95,0xAA,0x7D,0x4D,0xD0,0xF2,0x0C,0x9F,0x9C,0x40,0xE8,0xD6,0x55, + 0x73,0xBA,0x3C,0xDF,0x90,0xCB,0x00,0x5B,0x21,0x11,0x67,0xC2,0xED,0x32,0x1E,0xDE, }; - /* subject:/CN=garthc2.apple.com/O=Apple Inc./OU=DTS/ST=California/C=US/L=Cupertino/emailAddress=gcummings@apple.com issuer :/CN=garthc2.apple.com/O=Apple Inc./OU=DTS/ST=California/C=US/L=Cupertino/emailAddress=gcummings@apple.com */ const uint8_t garthc2_certificate[730]={ @@ -1963,3 +1930,212 @@ unsigned char _comodo_rsa_root[1500]={ 0xB5,0x14,0x69,0x66,0x0E,0x82,0xE7,0xCD,0xCE,0xC8,0x2D,0xA6,0x51,0x7F,0x21,0xC1, 0x35,0x53,0x85,0x06,0x4A,0x5D,0x9F,0xAD,0xBB,0x1B,0x5F,0x74, }; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test MD5 Root */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test MD5 Root */ +uint8_t _md5_root[]={ + 0x30,0x82,0x03,0xCE,0x30,0x82,0x02,0xB6,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0x89,0x96,0x98,0xE1,0x25,0xF9,0x94,0x1E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x30,0x81,0x82,0x31,0x0B,0x30,0x09,0x06,0x03, + 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08, + 0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,0x10, + 0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F, + 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65, + 0x20,0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x0C,0x14, + 0x53,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x45,0x6E,0x67,0x69,0x6E,0x65,0x65, + 0x72,0x69,0x6E,0x67,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x0C,0x0D,0x54, + 0x65,0x73,0x74,0x20,0x4D,0x44,0x35,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D, + 0x31,0x38,0x30,0x36,0x31,0x32,0x32,0x33,0x34,0x37,0x30,0x39,0x5A,0x17,0x0D,0x31, + 0x39,0x30,0x36,0x31,0x32,0x32,0x33,0x34,0x37,0x30,0x39,0x5A,0x30,0x81,0x82,0x31, + 0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11, + 0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69, + 0x61,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65, + 0x72,0x74,0x69,0x6E,0x6F,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A, + 0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03, + 0x55,0x04,0x0B,0x0C,0x14,0x53,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x45,0x6E, + 0x67,0x69,0x6E,0x65,0x65,0x72,0x69,0x6E,0x67,0x31,0x16,0x30,0x14,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x0D,0x54,0x65,0x73,0x74,0x20,0x4D,0x44,0x35,0x20,0x52,0x6F,0x6F, + 0x74,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,0xBA,0xAB,0xFB,0x22,0xB6,0x25,0x79,0x2A,0x84,0xDB,0x59,0xE9,0x48,0x7C, + 0x36,0x54,0xCC,0x6F,0x82,0xE6,0x0A,0x11,0x31,0x31,0x84,0xB4,0xB2,0x7F,0x97,0xFD, + 0xF9,0x3A,0xB2,0x49,0xB2,0x2C,0x36,0x39,0x9A,0x57,0x97,0x8F,0x92,0xB3,0xD2,0xE0, + 0x91,0x1A,0x06,0x19,0xD2,0xB4,0xE3,0xD9,0xFF,0x0C,0x25,0xFA,0x85,0x78,0x1D,0x40, + 0xD9,0xB8,0xD5,0xA7,0x62,0x84,0x8E,0x20,0xFF,0xBB,0xD0,0x83,0xF9,0x59,0xFC,0x68, + 0x06,0x76,0x0D,0x10,0x82,0xC3,0xEA,0x49,0xD7,0xBE,0x79,0x0C,0x8A,0x57,0xBC,0x5B, + 0xD7,0xD2,0xF0,0x33,0x79,0xC4,0xC7,0xA7,0x64,0x3C,0x82,0xFA,0x76,0x9E,0x04,0xB6, + 0x49,0xB8,0xE6,0xFE,0x1E,0x0C,0x56,0x84,0x8B,0x51,0x91,0x81,0x92,0x1C,0xBA,0xDB, + 0xA8,0xF4,0x60,0x36,0x8F,0xB6,0x3D,0xBF,0x7E,0xDD,0x0F,0x3B,0x1C,0x17,0xDC,0x4B, + 0x6C,0x32,0xCF,0xE9,0x9B,0xE7,0xBD,0x97,0x3C,0x31,0x15,0x27,0xB8,0xCA,0x7E,0xB9, + 0x63,0xB5,0xA3,0xB3,0x0C,0x3A,0x3D,0x83,0xE6,0xC2,0xAB,0xF7,0x9B,0x90,0x8D,0xD3, + 0xA1,0x3A,0x57,0xBE,0x95,0x75,0x51,0x40,0x3B,0xE9,0x86,0x52,0xD4,0x95,0xBF,0xE5, + 0xA7,0xD5,0x91,0x11,0x04,0x84,0x89,0x96,0xCB,0xC7,0x68,0xAE,0xEF,0x03,0xC7,0x08, + 0xE5,0x39,0x72,0x14,0xEB,0x85,0x31,0xE5,0x1C,0x7E,0xE6,0x8C,0x24,0x8A,0x6E,0xBD, + 0xE0,0x14,0xFA,0x54,0x41,0xE2,0x22,0x0C,0x77,0xE9,0x85,0x52,0xD2,0x57,0x8E,0x50, + 0xB5,0xBD,0xD9,0xBD,0xEB,0xA4,0xDE,0xE4,0x76,0x8C,0x18,0xAF,0xEB,0x73,0xFC,0xD6, + 0xB1,0x09,0x02,0x03,0x01,0x00,0x01,0xA3,0x45,0x30,0x43,0x30,0x12,0x06,0x03,0x55, + 0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30, + 0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30, + 0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x50,0xD0,0xF4,0xB0,0xFF,0x54, + 0x6F,0x98,0x26,0x0A,0x8A,0xA7,0x72,0x90,0xCC,0xD2,0x63,0xEF,0x1D,0x16,0x30,0x0D, + 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x03,0x82,0x01, + 0x01,0x00,0x48,0x03,0xF2,0xD6,0x05,0x9E,0x02,0x47,0xEF,0xDA,0xAE,0x6C,0xDF,0x1C, + 0xC4,0xE2,0xFB,0x62,0x89,0xE7,0xC7,0x55,0xE4,0x7B,0x20,0xC3,0xCE,0x7F,0x94,0x60, + 0x2D,0xE6,0x63,0x43,0xF1,0x03,0xC3,0x9D,0x79,0xA8,0x62,0x75,0x3D,0x41,0xAF,0xCE, + 0x3F,0x70,0xA7,0xF9,0xAC,0x8C,0xC7,0xBA,0x01,0xE4,0xAE,0xDF,0x15,0xBC,0x36,0xDE, + 0x27,0x63,0xBD,0x4C,0xE5,0x20,0x4E,0x8B,0x91,0x80,0x60,0xBF,0xF8,0x34,0xD5,0x89, + 0xE0,0x5D,0x0F,0x5E,0xF6,0x63,0xC0,0x26,0x7F,0x48,0xBA,0x38,0x80,0xEA,0x91,0xDF, + 0xC4,0x53,0xE0,0x7B,0x0D,0xF1,0x85,0x35,0x55,0xC3,0x0B,0xDD,0x35,0x82,0x75,0x7F, + 0x5A,0x23,0x2C,0x11,0xD6,0x2E,0xA1,0xB0,0x61,0x81,0x04,0x8A,0xD0,0x3E,0xFC,0x30, + 0xD4,0x46,0x4C,0x64,0x6C,0xF1,0x29,0xED,0x5F,0x49,0x54,0xB7,0x79,0xC7,0xC2,0x03, + 0x53,0x1A,0x7D,0xB9,0x17,0x10,0xFF,0x4F,0xD7,0x4E,0x0A,0x58,0x51,0xB3,0x77,0x50, + 0xA2,0x93,0x24,0x60,0x95,0x70,0x77,0xB4,0x18,0x72,0xBB,0x43,0x49,0x44,0xBE,0x11, + 0x1D,0xD9,0xCB,0x37,0xCE,0x6F,0x02,0xBC,0x7F,0xCE,0x52,0x06,0xFA,0x38,0x7D,0x75, + 0x60,0xDD,0xAF,0x0C,0x1F,0xAF,0xA9,0x2F,0x11,0xB8,0xC8,0xEF,0x12,0xE2,0xB2,0xC2, + 0x87,0xF3,0xAC,0x10,0x16,0x40,0x0D,0x9B,0xFA,0x7F,0xA3,0xDD,0xBE,0x31,0xA2,0x6B, + 0x5B,0xF4,0x50,0x6F,0xC6,0x6F,0xBB,0x2E,0xD3,0x34,0x16,0xBF,0xB3,0x61,0x5E,0xD3, + 0x5C,0x03,0x9E,0xE6,0xEB,0x6E,0xF7,0x11,0x1F,0xF8,0x90,0x34,0xC9,0x7B,0x21,0x14, + 0x4F,0x70, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test Root CA */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test Root CA */ +uint8_t _sha256_root[] = { + 0x30,0x82,0x03,0xCC,0x30,0x82,0x02,0xB4,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xF7,0xC7,0x8C,0x2F,0xE6,0xB8,0xCE,0xD2,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x81,0x31,0x0B,0x30,0x09,0x06,0x03, + 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08, + 0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,0x10, + 0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F, + 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65, + 0x20,0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x0C,0x14, + 0x53,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x45,0x6E,0x67,0x69,0x6E,0x65,0x65, + 0x72,0x69,0x6E,0x67,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C,0x54, + 0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31, + 0x38,0x30,0x34,0x32,0x38,0x32,0x30,0x32,0x31,0x32,0x30,0x5A,0x17,0x0D,0x32,0x38, + 0x30,0x34,0x32,0x35,0x32,0x30,0x32,0x31,0x32,0x30,0x5A,0x30,0x81,0x81,0x31,0x0B, + 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06, + 0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61, + 0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72, + 0x74,0x69,0x6E,0x6F,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41, + 0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55, + 0x04,0x0B,0x0C,0x14,0x53,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x45,0x6E,0x67, + 0x69,0x6E,0x65,0x65,0x72,0x69,0x6E,0x67,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x0C,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,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, + 0xDD,0xC7,0xD4,0xC4,0xC9,0x5B,0x62,0xEF,0x30,0x90,0x81,0x1A,0xA8,0x3C,0x5F,0x37, + 0xEC,0xEF,0x85,0xEF,0x54,0x77,0x67,0xD7,0xED,0x1A,0x97,0xF0,0x0A,0x3E,0x42,0x9C, + 0xFC,0x74,0xDD,0x27,0x40,0xF9,0xFA,0xA9,0x42,0xA7,0x71,0x05,0x18,0x4E,0xCC,0xC4, + 0x8C,0x27,0x4C,0x55,0x21,0xBF,0xCA,0xB8,0xAD,0xB4,0x2E,0x4E,0x0B,0x0C,0x43,0xCF, + 0x94,0x4E,0x52,0xBB,0x39,0xEB,0x69,0x6B,0x32,0xF0,0x88,0x16,0x33,0xE4,0x91,0x7A, + 0xF6,0xA7,0xBC,0x28,0x9F,0xAD,0x40,0x02,0xC7,0xA1,0x13,0x5E,0x94,0xCA,0xDF,0x0F, + 0xEB,0xC6,0xDB,0x2A,0xF9,0x3D,0x57,0x52,0x41,0x2E,0x0D,0x85,0xA2,0xD1,0x12,0x80, + 0x69,0x74,0x8C,0x4D,0xEC,0x8B,0x82,0xEA,0xA5,0xD7,0xDF,0x9F,0x1E,0xBA,0xC6,0x2D, + 0xAC,0x3F,0xFC,0x12,0xF4,0xB1,0x29,0x7C,0x05,0x40,0x68,0x3F,0xAC,0x80,0x5A,0xB0, + 0xD8,0xA3,0x17,0xB8,0x94,0x0F,0x40,0x7F,0x33,0xDC,0xAF,0x51,0xA9,0xEA,0x95,0x32, + 0xCA,0x8F,0x36,0xDA,0x93,0xC7,0x20,0xA2,0xC2,0xB2,0xDD,0x0B,0x6A,0xC1,0x4D,0x21, + 0x80,0x16,0x54,0x6C,0xFD,0xB0,0xCC,0x3C,0xF9,0x78,0x64,0x40,0x4E,0xB0,0x43,0xA6, + 0xF6,0xF9,0x8E,0xEE,0xBC,0x41,0x49,0xCB,0x20,0x9A,0x71,0x85,0xF4,0xA2,0xA2,0xE6, + 0x18,0xDD,0xA7,0x76,0xC1,0x86,0xB5,0x43,0xE3,0xE0,0x76,0x51,0x5E,0xD6,0x0A,0xA9, + 0x2E,0x31,0x95,0x2C,0x2F,0x3D,0x76,0x59,0x41,0x75,0x50,0xCD,0x96,0x63,0x34,0x62, + 0x4D,0xE4,0xA8,0xA3,0x08,0x3A,0xDF,0x28,0x36,0x58,0x72,0xBC,0x4B,0x4F,0x07,0xE3, + 0x02,0x03,0x01,0x00,0x01,0xA3,0x45,0x30,0x43,0x30,0x12,0x06,0x03,0x55,0x1D,0x13, + 0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x0E,0x06, + 0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06, + 0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xB5,0xA9,0x53,0x08,0x10,0x38,0x1A,0xA5, + 0xB3,0x84,0xC9,0xEE,0xC4,0xAB,0x0F,0xB8,0x5F,0x68,0x10,0xA2,0x30,0x0D,0x06,0x09, + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00, + 0xDA,0xA8,0xB6,0x1B,0xA8,0x15,0x27,0xDA,0xA9,0xE9,0x2F,0xC2,0x87,0xB6,0x7E,0x0A, + 0xDE,0x88,0x65,0xB9,0x23,0x5F,0x7B,0x35,0xE1,0xDB,0xB2,0xBA,0x3B,0x1D,0xE5,0x3E, + 0x20,0x7E,0x2B,0x93,0xD0,0xB5,0xEC,0x9B,0x4E,0xB8,0x64,0xAE,0x7A,0x77,0xB6,0x7C, + 0x80,0x9D,0x35,0x42,0x23,0xAE,0x91,0x6A,0xAB,0x27,0xBE,0x46,0x80,0xE0,0x58,0xA9, + 0x8C,0x47,0xFF,0x7E,0x79,0x7F,0xFC,0xB0,0x71,0xFF,0x35,0x4A,0x5E,0x30,0xAC,0xF5, + 0xCB,0xC6,0x57,0xD2,0x93,0x4E,0x78,0xD4,0x14,0x7C,0x43,0x6A,0x5E,0x20,0x01,0xB6, + 0x30,0x41,0xC4,0xB0,0x3D,0x72,0x0C,0xD6,0x36,0x88,0x37,0x4A,0xE9,0xF3,0xBB,0x28, + 0x1D,0x53,0x62,0x6D,0x1B,0x79,0xAA,0xDC,0xF2,0x0A,0x9A,0xD6,0x00,0x9E,0x18,0x82, + 0x3E,0x7D,0xD1,0x9C,0x5A,0x16,0xA5,0xA7,0x73,0x68,0x61,0x63,0x99,0x26,0x8D,0xB9, + 0xAF,0x01,0x98,0xA4,0x94,0x1D,0x7F,0x12,0x51,0x0A,0xAC,0xCE,0x65,0xBA,0xBF,0x38, + 0xF9,0xDB,0xC9,0x82,0xA3,0x2C,0x5D,0x22,0x87,0xEA,0xD2,0x45,0xD3,0xEC,0x50,0xF1, + 0x29,0x7B,0x09,0x10,0x4D,0xE0,0x21,0x35,0x4F,0x3F,0x0F,0x29,0x5D,0x30,0x83,0xBD, + 0xD9,0x45,0x78,0x49,0xD7,0xAF,0xC6,0xF0,0x3E,0x2B,0xD6,0xC3,0x7B,0xF9,0x2F,0x3B, + 0xCB,0x3E,0xB9,0xC9,0x08,0xE7,0x19,0x9C,0xEA,0xFC,0x03,0xED,0x51,0xF7,0x3C,0x5E, + 0x09,0x67,0x91,0x5F,0x22,0x58,0x73,0x31,0xE7,0xA0,0x9F,0x9D,0xBF,0x48,0x2D,0x7C, + 0xFE,0xAA,0xFE,0x29,0x56,0x11,0xE8,0x0F,0xBE,0xE0,0x3A,0xA6,0x8D,0x82,0x34,0xFB, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test MD5 Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test Root CA */ +uint8_t _md5_leaf[] = { + 0x30,0x82,0x04,0x5D,0x30,0x82,0x03,0x45,0xA0,0x03,0x02,0x01,0x02,0x02,0x13,0x7A, + 0x22,0xA1,0x88,0x18,0x9E,0x75,0x77,0xE6,0xEF,0x7E,0xC0,0x33,0x8E,0xE8,0x90,0xE8, + 0x7B,0xC5,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05, + 0x00,0x30,0x81,0x81,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, + 0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69, + 0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C, + 0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x13,0x30,0x11,0x06,0x03, + 0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31, + 0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x0C,0x14,0x53,0x65,0x63,0x75,0x72,0x69, + 0x74,0x79,0x20,0x45,0x6E,0x67,0x69,0x6E,0x65,0x65,0x72,0x69,0x6E,0x67,0x31,0x15, + 0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C,0x54,0x65,0x73,0x74,0x20,0x52,0x6F, + 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x36,0x31,0x32,0x32, + 0x33,0x34,0x35,0x35,0x38,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x31,0x32,0x32,0x33, + 0x34,0x35,0x35,0x38,0x5A,0x30,0x81,0x82,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, + 0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A, + 0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,0x10,0x06,0x03, + 0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x13, + 0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49, + 0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x0C,0x14,0x53,0x65, + 0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x45,0x6E,0x67,0x69,0x6E,0x65,0x65,0x72,0x69, + 0x6E,0x67,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x0C,0x0D,0x54,0x65,0x73, + 0x74,0x20,0x4D,0x44,0x35,0x20,0x4C,0x65,0x61,0x66,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,0xAD,0xB6,0x0E,0xB4,0xE8, + 0xA1,0x87,0xDB,0x0A,0x67,0xA2,0xE0,0xAD,0xD3,0x22,0x30,0xBF,0x7A,0x17,0x94,0x95, + 0xE2,0xA3,0xC3,0xF3,0xA7,0xD1,0x31,0xAA,0xD4,0x6F,0x12,0x20,0x6A,0x28,0x31,0xA3, + 0x02,0x11,0xB7,0xCB,0xEF,0x49,0xE1,0x8D,0xAB,0x41,0x83,0x0A,0xBB,0xDE,0x44,0x93, + 0x73,0x13,0x4B,0xFD,0x36,0x8A,0x57,0x30,0x3D,0x86,0x62,0x96,0x2A,0x3B,0x59,0x7C, + 0x29,0x19,0x73,0xA6,0x9C,0xE3,0x5C,0x2E,0xB6,0x91,0x42,0x9A,0x52,0xC7,0x60,0xF0, + 0x05,0x99,0x46,0xC8,0x6B,0x3A,0xD9,0xB7,0x70,0xDB,0xCA,0x81,0x71,0x74,0xDF,0x20, + 0xD3,0x94,0xF9,0x70,0xBA,0xF3,0x69,0x0B,0x9D,0x40,0xC0,0xC2,0xBF,0x95,0xAD,0xFF, + 0x88,0xF5,0x12,0x41,0x80,0xB1,0x7E,0xAD,0x2F,0x80,0x88,0xC7,0x60,0x89,0xFE,0x3C, + 0x0C,0xCA,0x85,0x67,0xFD,0xD1,0x84,0x89,0x77,0x7E,0xA1,0x77,0x1D,0xCD,0x80,0xE1, + 0xFA,0x2A,0xF9,0x04,0x60,0xED,0x77,0xB7,0x05,0xF7,0xA0,0x08,0xCF,0xFE,0x7B,0x3D, + 0x75,0x84,0x8C,0x7A,0x6A,0x48,0x22,0x44,0xAE,0xA7,0x2F,0xC6,0xE6,0xC3,0x8C,0x1A, + 0xAD,0xEA,0x12,0x3F,0x06,0x6F,0x03,0x61,0xCE,0xAA,0x42,0x73,0x23,0x3D,0x41,0x08, + 0x33,0x6F,0x76,0xC6,0x39,0xBB,0x94,0xCF,0xBA,0x44,0x92,0x17,0x6D,0xD1,0x1D,0xAE, + 0xF2,0x47,0x61,0x6F,0xAE,0x67,0x23,0xCD,0x6A,0x9A,0x52,0xD9,0x0B,0x06,0x8A,0xA2, + 0x33,0x8F,0x35,0x14,0xBD,0x4F,0xE7,0x2E,0x09,0x7B,0xAB,0x4E,0x99,0xA9,0x28,0x2B, + 0xAD,0x8E,0xDA,0x21,0xD9,0xD3,0x73,0x5B,0x86,0x69,0xEF,0x02,0x03,0x01,0x00,0x01, + 0xA3,0x81,0xCA,0x30,0x81,0xC7,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF, + 0x04,0x02,0x30,0x00,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, + 0x03,0x02,0x07,0x80,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06, + 0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x16,0x06,0x03,0x55,0x1D,0x11, + 0x04,0x0F,0x30,0x0D,0x82,0x0B,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63,0x6F, + 0x6D,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2A,0x04,0x77,0xF2, + 0xC5,0xB3,0x51,0xA0,0x85,0x23,0x10,0x8D,0xEC,0x1F,0x01,0xCF,0x3C,0x94,0x87,0x44, + 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xB5,0xA9,0x53, + 0x08,0x10,0x38,0x1A,0xA5,0xB3,0x84,0xC9,0xEE,0xC4,0xAB,0x0F,0xB8,0x5F,0x68,0x10, + 0xA2,0x30,0x3A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x2E,0x30, + 0x2C,0x30,0x2A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x1E,0x68, + 0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63, + 0x6F,0x6D,0x2F,0x74,0x65,0x73,0x74,0x43,0x41,0x2E,0x64,0x65,0x72,0x30,0x0D,0x06, + 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x03,0x82,0x01,0x01, + 0x00,0x9D,0x05,0xC0,0xB6,0xDE,0x11,0x00,0xDB,0x29,0xB2,0xAC,0xE6,0xFD,0x8C,0x2D, + 0x88,0x79,0x75,0x8F,0xFD,0x7C,0x65,0x6D,0xAE,0xF7,0x19,0xF4,0x52,0x79,0x14,0x8C, + 0x57,0x39,0x50,0x53,0xFA,0xB9,0xCC,0x5B,0xEE,0x9C,0x23,0xC2,0x15,0xBD,0xB4,0x9A, + 0x0A,0x6D,0xC4,0x8C,0x39,0xA3,0xAE,0xD4,0x1D,0x9D,0x1A,0xBD,0x3C,0x6C,0x70,0x95, + 0x0B,0xFA,0xE6,0x0B,0x4E,0xB8,0x35,0x10,0x49,0xCC,0x3A,0x7C,0xE0,0x57,0x85,0xE0, + 0xD5,0x4E,0xB0,0x6B,0xB8,0xE0,0x37,0xF1,0xF1,0x6C,0x32,0x8E,0x8A,0x55,0x81,0x71, + 0x4B,0xC3,0x75,0x8D,0xFF,0x11,0x9C,0x2B,0xE9,0x71,0xA7,0xBA,0x01,0xDA,0xA0,0x4A, + 0x46,0xEC,0x86,0xC8,0x44,0x67,0x44,0x78,0x99,0x6B,0xFA,0x3A,0x26,0x09,0xA9,0xA5, + 0xAF,0x29,0x3A,0x2A,0x0E,0xD0,0x44,0x69,0xD7,0x8E,0xB3,0xB0,0xCF,0x90,0xC3,0xB7, + 0x8B,0xB4,0xD8,0xB8,0xEB,0x27,0x42,0x2B,0x91,0xDF,0x4D,0x59,0x56,0xD4,0x9F,0x0A, + 0x58,0x16,0x24,0x4B,0x96,0xEE,0xDE,0xCA,0xD2,0x3F,0xB9,0xC7,0x9B,0x4A,0x65,0x51, + 0xBC,0x6E,0x39,0xEE,0x39,0x11,0x8F,0xBC,0xB3,0x6C,0x17,0xF5,0xAD,0x2F,0x46,0x86, + 0x5F,0x76,0x17,0x43,0x70,0x55,0xCD,0x08,0x5A,0x81,0x93,0x16,0xDD,0xC7,0x14,0x34, + 0x87,0xFF,0xE5,0x13,0xA3,0xC4,0x5A,0xFD,0xF8,0x40,0x77,0xDC,0xBE,0xEC,0xB1,0x31, + 0x05,0xA6,0xE1,0x6F,0x2C,0x32,0xD2,0xD7,0x6D,0x4D,0xF2,0xDF,0x2E,0x5D,0x6E,0x31, + 0x7E,0x06,0x20,0x11,0xF9,0x7C,0x72,0xE3,0x47,0xBA,0x33,0xA7,0x0A,0x74,0x92,0x7F, + 0x74, +}; diff --git a/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c b/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c index 3f1c0bc5..a4c7a57f 100644 --- a/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c +++ b/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c @@ -102,6 +102,16 @@ static void test_v3(void) { ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); + /* Test v3 certs fail iAP SW Auth policy */ + CFReleaseNull(policy); + CFReleaseNull(trust); + policy = SecPolicyCreateiAPSWAuth(); + require_noerr(SecTrustCreateWithCertificates(certs, policy, &trust), trustFail); + require_noerr(SecTrustSetAnchorCertificates(trust, anchors), trustFail); + require_noerr(SecTrustSetVerifyDate(trust, date), trustFail); + require_noerr(SecTrustEvaluate(trust, &trustResult), trustFail); + is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); + trustFail: CFReleaseSafe(policy); CFReleaseSafe(trust); @@ -155,12 +165,116 @@ trustFail: CFReleaseSafe(v3CA); } +static void test_sw_auth_trust(void) { + SecCertificateRef sw_auth_test_CA = NULL, sw_auth_test_leaf = NULL; + isnt(sw_auth_test_CA = SecCertificateCreateWithBytes(NULL, _iAPSWAuthTestRoot, sizeof(_iAPSWAuthTestRoot)), + NULL, "create sw auth test ca"); + isnt(sw_auth_test_leaf = SecCertificateCreateWithBytes(NULL, _iAPSWAuth_leaf, sizeof(_iAPSWAuth_leaf)), + NULL, "create sw auth leaf"); + + /* Test SW Auth certs meet iAP SW Auth policy */ + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFArrayRef certs = NULL, anchors = NULL; + CFDateRef date = NULL; + SecTrustResultType trustResult; + + certs = CFArrayCreate(NULL, (const void **)&sw_auth_test_leaf, 1, &kCFTypeArrayCallBacks); + anchors = CFArrayCreate(NULL, (const void **)&sw_auth_test_CA, 1, &kCFTypeArrayCallBacks); + policy = SecPolicyCreateiAPSWAuth(); + require_noerr(SecTrustCreateWithCertificates(certs, policy, &trust), trustFail); + require_noerr(SecTrustSetAnchorCertificates(trust, anchors), trustFail); + require(date = CFDateCreate(NULL, 530000000.0), trustFail); /* 17 Oct 2017, BEFORE issuance */ + require_noerr(SecTrustSetVerifyDate(trust, date), trustFail); + require_noerr(SecTrustEvaluate(trust, &trustResult), trustFail); + is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); + + /* Test SW Auth certs fail iAP policy */ + CFReleaseNull(policy); + CFReleaseNull(trust); + policy = SecPolicyCreateiAP(); + require_noerr(SecTrustCreateWithCertificates(certs, policy, &trust), trustFail); + require_noerr(SecTrustSetAnchorCertificates(trust, anchors), trustFail); + require_noerr(SecTrustSetVerifyDate(trust, date), trustFail); + require_noerr(SecTrustEvaluate(trust, &trustResult), trustFail); + is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); + + /* Test SW Auth certs fail when not-yet-valid with expiration check */ + CFReleaseNull(policy); + CFReleaseNull(trust); + policy = SecPolicyCreateiAPSWAuthWithExpiration(true); + require_noerr(SecTrustCreateWithCertificates(certs, policy, &trust), trustFail); + require_noerr(SecTrustSetAnchorCertificates(trust, anchors), trustFail); + require_noerr(SecTrustSetVerifyDate(trust, date), trustFail); + require_noerr(SecTrustEvaluate(trust, &trustResult), trustFail); + is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); + +trustFail: + CFReleaseSafe(policy); + CFReleaseSafe(trust); + CFReleaseSafe(certs); + CFReleaseSafe(anchors); + CFReleaseSafe(date); + CFReleaseSafe(sw_auth_test_CA); + CFReleaseSafe(sw_auth_test_leaf); +} + +static void test_sw_auth_cert(void) { + SecCertificateRef good_leaf = NULL, bad_leaf = NULL; + isnt(good_leaf = SecCertificateCreateWithBytes(NULL, _iAPSWAuth_leaf, sizeof(_iAPSWAuth_leaf)), + NULL, "create good iAP SW Auth cert"); + isnt(bad_leaf = SecCertificateCreateWithBytes(NULL, _malformed_iAPSWAuth_leaf, sizeof(_malformed_iAPSWAuth_leaf)), + NULL, "create bad iAP SW Auth cert"); + + /* Test Auth version interface */ + ok(SecCertificateGetiAuthVersion(good_leaf) == kSeciAuthVersionSW, "Get version of well-formed SW Auth cert"); + ok(SecCertificateGetiAuthVersion(bad_leaf) == kSeciAuthVersionSW, "Get version of malformed SW Auth cert"); + + /* Test extension copying with malformed extensions */ + is(SecCertificateCopyiAPSWAuthCapabilities(bad_leaf, kSeciAPSWAuthGeneralCapabilities), NULL, + "Fail to get capabilities of malformed SW auth cert"); + is(SecCertificateCopyiAPSWAuthCapabilities(bad_leaf, kSeciAPSWAuthAirPlayCapabilities), NULL, + "Fail to get AirPlay capabilities of malformed SW auth cert"); + is(SecCertificateCopyiAPSWAuthCapabilities(bad_leaf, kSeciAPSWAuthHomeKitCapabilities), NULL, + "Fail to get HomeKit capabilities of malformed SW auth cert"); + + uint8_t byte0 = 0x00; + uint8_t byte1 = 0x01; + CFDataRef data0 = CFDataCreate(NULL, &byte0, 1); + CFDataRef data1 = CFDataCreate(NULL, &byte1, 1); + + /* Test extension copying with well-formed extensions */ + CFDataRef extensionValue = NULL; + isnt(extensionValue = SecCertificateCopyiAPSWAuthCapabilities(good_leaf, kSeciAPSWAuthGeneralCapabilities), NULL, + "Get capabilities of well-formed SW auth cert"); + ok(CFEqual(extensionValue, data1), "Got correct general extension value"); + CFReleaseNull(extensionValue); + + isnt(extensionValue = SecCertificateCopyiAPSWAuthCapabilities(good_leaf, kSeciAPSWAuthAirPlayCapabilities), NULL, + "Get AirPlay capabilities of well-formed SW auth cert"); + ok(CFEqual(extensionValue, data0), "Got correct AirPlay extension value"); + CFReleaseNull(extensionValue); + + isnt(extensionValue = SecCertificateCopyiAPSWAuthCapabilities(good_leaf, kSeciAPSWAuthHomeKitCapabilities), NULL, + "Get capabilities of well-formed SW auth cert"); + ok(CFEqual(extensionValue, data1), "Got correct HomeKit extension value"); + CFReleaseNull(extensionValue); + + CFReleaseNull(good_leaf); + CFReleaseNull(bad_leaf); + CFReleaseNull(data0); + CFReleaseNull(data1); +} + + int si_22_sectrust_iap(int argc, char *const *argv) { - plan_tests(14+20); + plan_tests(14+21+5+13); test_v1(); test_v3(); + test_sw_auth_trust(); + test_sw_auth_cert(); return 0; } diff --git a/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.h b/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.h index fe444c5c..3a1cf060 100644 --- a/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.h +++ b/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.h @@ -424,4 +424,149 @@ unsigned char _malformedV3Leaf[] = { 0x0A,0xCB,0xCD,0x6C,0x03,0x8A,0x73,0x95,0x74,0xB1,0x57,0x03,0x09,0x55,0x8D, }; +/* subject:/CN=Test Accessories Software Authentication Root CA/OU=Apple Certification Authority/O=Apple Inc./C=US */ +/* issuer :/CN=Test Accessories Software Authentication Root CA/OU=Apple Certification Authority/O=Apple Inc./C=US */ +uint8_t _iAPSWAuthTestRoot[584]={ + 0x30,0x82,0x02,0x44,0x30,0x82,0x01,0xEA,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x59, + 0x29,0x18,0xB6,0x20,0x80,0x90,0x94,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, + 0x04,0x03,0x02,0x30,0x81,0x85,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04,0x03,0x0C, + 0x30,0x54,0x65,0x73,0x74,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F,0x72,0x69,0x65, + 0x73,0x20,0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x41,0x75,0x74,0x68,0x65, + 0x6E,0x74,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, + 0x41,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,0x31,0x31,0x30,0x39,0x30,0x30,0x31,0x35,0x31,0x32,0x5A,0x17,0x0D,0x33,0x37, + 0x31,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x81,0x85,0x31,0x39, + 0x30,0x37,0x06,0x03,0x55,0x04,0x03,0x0C,0x30,0x54,0x65,0x73,0x74,0x20,0x41,0x63, + 0x63,0x65,0x73,0x73,0x6F,0x72,0x69,0x65,0x73,0x20,0x53,0x6F,0x66,0x74,0x77,0x61, + 0x72,0x65,0x20,0x41,0x75,0x74,0x68,0x65,0x6E,0x74,0x69,0x63,0x61,0x74,0x69,0x6F, + 0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,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,0x00,0x28, + 0x4C,0xD4,0xFA,0x57,0x5C,0xB5,0x62,0xE6,0x10,0x30,0x60,0xBB,0x4E,0x8E,0xE9,0x34, + 0x52,0xFC,0xAB,0x74,0x4C,0x62,0xDA,0xEE,0x66,0x47,0x5E,0x5D,0x0D,0x04,0x2A,0x22, + 0x49,0xC4,0xF0,0x2C,0x93,0xC6,0xA8,0x5E,0x26,0x69,0xAA,0x3C,0x43,0xF8,0x49,0xCC, + 0x89,0x03,0x98,0xB3,0x7A,0x90,0xC8,0x79,0xFD,0x5A,0x13,0xE7,0x26,0x8C,0xA3,0x42, + 0x30,0x40,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03, + 0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x6F,0x79, + 0x89,0xE2,0x11,0xB0,0x49,0xE2,0xC1,0x5C,0xC4,0xDC,0xC7,0xE0,0x62,0x9F,0x3B,0x0A, + 0xC6,0x8C,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,0x02,0x03,0x48, + 0x00,0x30,0x45,0x02,0x21,0x00,0x9A,0x4F,0xA8,0xC3,0xC2,0x06,0x7D,0x86,0x3D,0x6F, + 0x9B,0x02,0xD7,0xBC,0xD6,0x28,0xE2,0x22,0xAA,0x90,0x62,0x73,0xED,0x91,0x34,0xD7, + 0x62,0xF0,0x4D,0xD7,0xD4,0x38,0x02,0x20,0x23,0x7B,0x01,0x88,0xBB,0xB9,0xF2,0x00, + 0x04,0x20,0x9B,0xC7,0x69,0x97,0x4B,0xAE,0xC6,0xB0,0x2E,0x93,0xE3,0x9B,0x50,0x8B, + 0xC8,0x1E,0xA4,0x94,0xF6,0x97,0x78,0x78, +}; + +/* subject:/CN=0/O=TestPPID1234 */ +/* issuer :/CN=Test Accessories Software Authentication Root CA/OU=Apple Certification Authority/O=Apple Inc./C=US */ +uint8_t _malformed_iAPSWAuth_leaf[739]={ + 0x30,0x82,0x02,0xDF,0x30,0x82,0x02,0x85,0xA0,0x03,0x02,0x01,0x02,0x02,0x0A,0x12, + 0x34,0x56,0x78,0x90,0x12,0x34,0x56,0x78,0x90,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48, + 0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x85,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x30,0x54,0x65,0x73,0x74,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F,0x72, + 0x69,0x65,0x73,0x20,0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x41,0x75,0x74, + 0x68,0x65,0x6E,0x74,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x52,0x6F,0x6F,0x74, + 0x20,0x43,0x41,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,0x31,0x31,0x31,0x35,0x32,0x30,0x34,0x33,0x35,0x38,0x5A,0x17,0x0D, + 0x32,0x37,0x31,0x32,0x31,0x33,0x32,0x30,0x34,0x33,0x35,0x38,0x5A,0x30,0x23,0x31, + 0x0A,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x0C,0x01,0x30,0x31,0x15,0x30,0x13,0x06, + 0x03,0x55,0x04,0x0A,0x0C,0x0C,0x54,0x65,0x73,0x74,0x50,0x50,0x49,0x44,0x31,0x32, + 0x33,0x34,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,0xC1,0xBD,0x0B, + 0x4E,0xBA,0xD3,0xC6,0x8F,0x70,0x39,0x73,0xBF,0x58,0xB7,0x75,0x02,0x41,0x60,0x62, + 0x70,0x6A,0x4D,0xA6,0x5C,0xF6,0xE7,0x5B,0xA9,0xAF,0x50,0x60,0x35,0x90,0xED,0x7D, + 0x28,0xF1,0x3C,0xF5,0x1D,0x4B,0xF4,0x32,0x41,0x3E,0x05,0x79,0x0B,0xEB,0xDD,0x89, + 0xA0,0x30,0x11,0xC9,0xB0,0x3F,0x83,0x77,0xC4,0xB3,0x2B,0x0A,0xE4,0xA3,0x82,0x01, + 0x3C,0x30,0x82,0x01,0x38,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, + 0x6F,0x79,0x89,0xE2,0x11,0xB0,0x49,0xE2,0xC1,0x5C,0xC4,0xDC,0xC7,0xE0,0x62,0x9F, + 0x3B,0x0A,0xC6,0x8C,0x30,0x57,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, + 0x04,0x4B,0x30,0x49,0x30,0x47,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, + 0x86,0x3B,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,0x65,0x73,0x74,0x61,0x63,0x63,0x73, + 0x77,0x61,0x75,0x74,0x68,0x72,0x6F,0x6F,0x74,0x63,0x61,0x30,0x31,0x30,0x46,0x06, + 0x03,0x55,0x1D,0x1F,0x04,0x3F,0x30,0x3D,0x30,0x3B,0xA0,0x39,0xA0,0x37,0x86,0x35, + 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,0x63,0x63,0x73,0x77,0x61,0x75,0x74,0x68,0x72,0x6F,0x6F,0x74,0x63, + 0x61,0x2E,0x63,0x72,0x6C,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14, + 0x95,0x87,0xEF,0xFB,0xDF,0x1F,0x26,0x48,0x67,0x29,0xEC,0x94,0x70,0xD6,0x29,0x5D, + 0x9A,0x95,0xC8,0x88,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, + 0x03,0x02,0x07,0x80,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06, + 0x3B,0x01,0x04,0x03,0x0C,0x01,0x30,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7, + 0x63,0x64,0x06,0x3B,0x02,0x04,0x03,0x0C,0x01,0x30,0x30,0x11,0x06,0x0A,0x2A,0x86, + 0x48,0x86,0xF7,0x63,0x64,0x06,0x3B,0x03,0x04,0x03,0x0C,0x01,0x30,0x30,0x0A,0x06, + 0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x03,0x48,0x00,0x30,0x45,0x02,0x21, + 0x00,0x9B,0xF6,0xD2,0x7D,0x61,0x1F,0xFD,0x73,0x9C,0x1D,0x54,0x3F,0x3C,0x9A,0xDF, + 0xAA,0x1D,0xEA,0x35,0xF6,0x41,0xF8,0xB5,0xC5,0x0E,0x92,0x14,0xA3,0x87,0xED,0xE6, + 0xD2,0x02,0x20,0x60,0xDA,0x7A,0x30,0xC3,0xEB,0x24,0x58,0xE2,0xBF,0x83,0xFC,0x41, + 0x51,0xF3,0xFB,0x50,0xE1,0x0F,0x53,0x6A,0x41,0x7A,0x59,0xA9,0x04,0x01,0x84,0xF9, + 0x81,0x89,0x87, +}; + +/* subject:/CN=0/O=PPID1234 */ +/* issuer :/CN=Test Accessories Software Authentication Root CA/OU=Apple Certification Authority/O=Apple Inc./C=US */ +uint8_t _iAPSWAuth_leaf[735]={ + 0x30,0x82,0x02,0xDB,0x30,0x82,0x02,0x82,0xA0,0x03,0x02,0x01,0x02,0x02,0x0B,0x00, + 0x8A,0x71,0xFE,0xCD,0xA2,0xF3,0x00,0x00,0x00,0x00,0x30,0x0A,0x06,0x08,0x2A,0x86, + 0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x85,0x31,0x39,0x30,0x37,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x30,0x54,0x65,0x73,0x74,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F, + 0x72,0x69,0x65,0x73,0x20,0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x41,0x75, + 0x74,0x68,0x65,0x6E,0x74,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x52,0x6F,0x6F, + 0x74,0x20,0x43,0x41,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,0x31,0x32,0x31,0x32,0x30,0x32,0x35,0x36,0x35,0x30,0x5A,0x17, + 0x0D,0x32,0x38,0x30,0x31,0x30,0x39,0x30,0x32,0x35,0x36,0x35,0x30,0x5A,0x30,0x1F, + 0x31,0x0A,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x0C,0x01,0x30,0x31,0x11,0x30,0x0F, + 0x06,0x03,0x55,0x04,0x0A,0x0C,0x08,0x50,0x50,0x49,0x44,0x31,0x32,0x33,0x34,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,0x64,0xFA,0xB0,0xFD,0xAF,0xD3, + 0xBF,0x9A,0xF6,0x48,0x03,0x9D,0x6B,0xBB,0x55,0x81,0x5E,0x6C,0x47,0x7D,0x2E,0xD4, + 0xF2,0xAE,0xA9,0xD3,0xA7,0x13,0xFA,0x69,0x16,0x16,0xC9,0x46,0x16,0xA2,0x38,0xB7, + 0x39,0xAC,0xFE,0x0B,0x9B,0x01,0x81,0x8A,0x94,0xA5,0x49,0x44,0x48,0x22,0x50,0x13, + 0x6B,0x06,0x28,0x6E,0x2D,0x09,0x1A,0x40,0x62,0x35,0xA3,0x82,0x01,0x3C,0x30,0x82, + 0x01,0x38,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,0x6F,0x79,0x89, + 0xE2,0x11,0xB0,0x49,0xE2,0xC1,0x5C,0xC4,0xDC,0xC7,0xE0,0x62,0x9F,0x3B,0x0A,0xC6, + 0x8C,0x30,0x57,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x4B,0x30, + 0x49,0x30,0x47,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x3B,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,0x65,0x73,0x74,0x61,0x63,0x63,0x73,0x77,0x61,0x75, + 0x74,0x68,0x72,0x6F,0x6F,0x74,0x63,0x61,0x30,0x31,0x30,0x46,0x06,0x03,0x55,0x1D, + 0x1F,0x04,0x3F,0x30,0x3D,0x30,0x3B,0xA0,0x39,0xA0,0x37,0x86,0x35,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, + 0x63,0x63,0x73,0x77,0x61,0x75,0x74,0x68,0x72,0x6F,0x6F,0x74,0x63,0x61,0x2E,0x63, + 0x72,0x6C,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xE3,0xA0,0x9F, + 0x50,0x4D,0x31,0xB6,0xB3,0xED,0x16,0x5B,0xA3,0x91,0x68,0xB8,0xC2,0x65,0x40,0x73, + 0x4D,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07, + 0x80,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x3B,0x01,0x04, + 0x03,0x04,0x01,0x01,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06, + 0x3B,0x02,0x04,0x03,0x04,0x01,0x00,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7, + 0x63,0x64,0x06,0x3B,0x03,0x04,0x03,0x04,0x01,0x01,0x30,0x0A,0x06,0x08,0x2A,0x86, + 0x48,0xCE,0x3D,0x04,0x03,0x02,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x39,0x57,0x87, + 0x0B,0x53,0xB3,0x24,0x14,0x96,0x26,0xD2,0xA5,0x06,0xC2,0xA8,0x4C,0x5C,0x40,0xD4, + 0xC4,0x8D,0xEC,0x2D,0x2F,0x80,0xFB,0x2B,0xAF,0x56,0xF1,0x10,0x32,0x02,0x20,0x6D, + 0xCC,0xA8,0x41,0x92,0x89,0xD4,0xB8,0xEF,0xE5,0xB3,0x30,0xF7,0x94,0xBE,0x85,0x52, + 0xFE,0x75,0x5E,0xB2,0xEF,0x34,0x2F,0x71,0x8B,0xCD,0xD2,0xF0,0x9F,0xF7,0x63, +}; + #endif /* _SECURITY_SI_22_SECTRUST_IAP_H_ */ diff --git a/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c b/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c index e7990185..b5d82838 100644 --- a/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c +++ b/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c @@ -21,1247 +21,22 @@ #include "shared_regressions.h" -/* subject:/jurisdictionC=US/jurisdictionST=Delaware/businessCategory=Private Organization/serialNumber=3014267/C=US/postalCode=95131-2021/ST=California/L=San Jose/street=2211 N 1st St/O=PayPal, Inc./OU=CDN Support/CN=www.paypal.com */ -/* issuer :/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */ -static const uint8_t _c0[]={ - 0x30,0x82,0x07,0x64,0x30,0x82,0x06,0x4C,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x57, - 0xCB,0x7E,0x15,0xE2,0xE3,0xE2,0x44,0xD8,0x2B,0x01,0x63,0x29,0x46,0xEB,0xF0,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x77, - 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30, - 0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, - 0x20,0x43,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x1F,0x30,0x1D, - 0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20, - 0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x28,0x30, - 0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, - 0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20, - 0x43,0x41,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,0x39,0x32, - 0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x31,0x30,0x33,0x30, - 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x82,0x01,0x09,0x31,0x13,0x30,0x11,0x06, - 0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x55,0x53, - 0x31,0x19,0x30,0x17,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01, - 0x02,0x0C,0x08,0x44,0x65,0x6C,0x61,0x77,0x61,0x72,0x65,0x31,0x1D,0x30,0x1B,0x06, - 0x03,0x55,0x04,0x0F,0x13,0x14,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x4F,0x72, - 0x67,0x61,0x6E,0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,0x31,0x10,0x30,0x0E,0x06,0x03, - 0x55,0x04,0x05,0x13,0x07,0x33,0x30,0x31,0x34,0x32,0x36,0x37,0x31,0x0B,0x30,0x09, - 0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55, - 0x04,0x11,0x0C,0x0A,0x39,0x35,0x31,0x33,0x31,0x2D,0x32,0x30,0x32,0x31,0x31,0x13, - 0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72, - 0x6E,0x69,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x07,0x0C,0x08,0x53,0x61, - 0x6E,0x20,0x4A,0x6F,0x73,0x65,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x09,0x0C, - 0x0D,0x32,0x32,0x31,0x31,0x20,0x4E,0x20,0x31,0x73,0x74,0x20,0x53,0x74,0x31,0x15, - 0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0C,0x50,0x61,0x79,0x50,0x61,0x6C,0x2C, - 0x20,0x49,0x6E,0x63,0x2E,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B, - 0x43,0x44,0x4E,0x20,0x53,0x75,0x70,0x70,0x6F,0x72,0x74,0x31,0x17,0x30,0x15,0x06, - 0x03,0x55,0x04,0x03,0x0C,0x0E,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C, - 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,0xBF,0xF7,0x98,0x4B,0x4E,0xAA,0xF2,0x2F,0xC6,0x77,0xAB, - 0x26,0x76,0x60,0x2E,0xAB,0x50,0xBD,0x47,0xFF,0x8B,0x7C,0xB7,0x4A,0x75,0x0D,0x81, - 0xF7,0x46,0xE2,0x6B,0x03,0x9F,0xE4,0x07,0xFF,0xC0,0xAC,0xE5,0x15,0x7C,0x0B,0x81, - 0xAA,0xD0,0x32,0x88,0xB0,0x58,0x4E,0xEB,0xC1,0x13,0xCC,0x27,0xDD,0x1A,0x27,0x40, - 0xE8,0xF8,0x16,0x39,0x9A,0x4D,0x55,0xD5,0x0D,0x47,0x7C,0xD1,0x58,0xDB,0x41,0x8E, - 0x41,0x0E,0x3E,0xF2,0x3B,0x05,0x78,0x5D,0x8B,0xBF,0x28,0x71,0x41,0x11,0xC9,0x14, - 0xDB,0xE5,0xE2,0xAA,0x80,0x84,0xD0,0xE8,0xA7,0x2C,0xAA,0xC2,0x06,0xC8,0xDC,0xD3, - 0x18,0x35,0x42,0xA0,0x47,0xD5,0xB5,0xBA,0x57,0x66,0xC3,0x01,0x1F,0xC1,0x3A,0x58, - 0xE8,0x39,0x94,0xF5,0x5E,0x50,0x73,0x7E,0xB6,0x84,0x45,0x27,0xFC,0x52,0x4C,0xEF, - 0x1E,0x32,0x30,0x13,0x0C,0xF5,0x93,0xE5,0xB9,0xA8,0xA0,0x1C,0x05,0xA9,0x69,0xB7, - 0xA4,0x07,0x27,0xB9,0x6E,0x30,0x99,0x3A,0x6F,0x33,0xD7,0xFF,0x24,0xAE,0x02,0x12, - 0x08,0xF8,0x55,0x3F,0x30,0xEC,0xA2,0x5F,0x93,0x34,0x8B,0xAB,0x05,0xE6,0x8D,0xD5, - 0x93,0xBE,0x93,0x78,0x3E,0x97,0xA8,0x66,0xDC,0xA9,0x25,0x9B,0xF0,0x18,0x1A,0xFA, - 0xAE,0x80,0x99,0xC6,0x0F,0xE2,0x67,0xAA,0x26,0xA8,0xED,0xE8,0xFF,0x45,0x8F,0x45, - 0x0E,0xC8,0xC3,0x28,0x51,0x12,0xA6,0x17,0x1E,0x27,0xC8,0x61,0x71,0xC7,0x34,0x40, - 0xD0,0xC9,0xBA,0x49,0x72,0x9B,0xBD,0x57,0xCD,0xEA,0xD5,0x86,0x63,0x51,0x1D,0x48, - 0x14,0x70,0xBE,0xD4,0xD5,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x03,0x56,0x30,0x82, - 0x03,0x52,0x30,0x7C,0x06,0x03,0x55,0x1D,0x11,0x04,0x75,0x30,0x73,0x82,0x12,0x68, - 0x69,0x73,0x74,0x6F,0x72,0x79,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F, - 0x6D,0x82,0x0C,0x74,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82, - 0x0C,0x63,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x0D,0x63, - 0x36,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x14,0x64,0x65, - 0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63, - 0x6F,0x6D,0x82,0x0C,0x70,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D, - 0x82,0x0E,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D, - 0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x0E,0x06,0x03,0x55, - 0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55, - 0x1D,0x25,0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, - 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x6F,0x06,0x03,0x55,0x1D, - 0x20,0x04,0x68,0x30,0x66,0x30,0x5B,0x06,0x0B,0x60,0x86,0x48,0x01,0x86,0xF8,0x45, - 0x01,0x07,0x17,0x06,0x30,0x4C,0x30,0x23,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, - 0x02,0x01,0x16,0x17,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x64,0x2E,0x73,0x79, - 0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x63,0x70,0x73,0x30,0x25,0x06,0x08,0x2B, - 0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x19,0x0C,0x17,0x68,0x74,0x74,0x70,0x73, - 0x3A,0x2F,0x2F,0x64,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x72, - 0x70,0x61,0x30,0x07,0x06,0x05,0x67,0x81,0x0C,0x01,0x01,0x30,0x1F,0x06,0x03,0x55, - 0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59, - 0xA6,0x64,0x63,0xD6,0xCF,0x20,0x07,0x57,0xD5,0x91,0xE7,0x6A,0x30,0x2B,0x06,0x03, - 0x55,0x1D,0x1F,0x04,0x24,0x30,0x22,0x30,0x20,0xA0,0x1E,0xA0,0x1C,0x86,0x1A,0x68, - 0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x72,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63, - 0x6F,0x6D,0x2F,0x73,0x72,0x2E,0x63,0x72,0x6C,0x30,0x57,0x06,0x08,0x2B,0x06,0x01, - 0x05,0x05,0x07,0x01,0x01,0x04,0x4B,0x30,0x49,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01, - 0x05,0x05,0x07,0x30,0x01,0x86,0x13,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x72, - 0x2E,0x73,0x79,0x6D,0x63,0x64,0x2E,0x63,0x6F,0x6D,0x30,0x26,0x06,0x08,0x2B,0x06, - 0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73, - 0x72,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x73,0x72,0x2E,0x63, - 0x72,0x74,0x30,0x82,0x01,0x7E,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02, - 0x04,0x02,0x04,0x82,0x01,0x6E,0x04,0x82,0x01,0x6A,0x01,0x68,0x00,0x75,0x00,0xDD, - 0xEB,0x1D,0x2B,0x7A,0x0D,0x4F,0xA6,0x20,0x8B,0x81,0xAD,0x81,0x68,0x70,0x7E,0x2E, - 0x8E,0x9D,0x01,0xD5,0x5C,0x88,0x8D,0x3D,0x11,0xC4,0xCD,0xB6,0xEC,0xBE,0xCC,0x00, - 0x00,0x01,0x5E,0xAB,0x85,0x57,0xB1,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02, - 0x20,0x07,0xE3,0x40,0xE7,0x2A,0x3C,0x38,0xEC,0xF4,0xFB,0x7D,0xBC,0x99,0x23,0xBA, - 0xD6,0x39,0x0D,0x7B,0x87,0x4C,0xF0,0x8B,0xAC,0x88,0x76,0x16,0x98,0xAD,0xED,0xAC, - 0x34,0x02,0x20,0x5E,0xA4,0x5A,0xF6,0xBD,0xD0,0xF2,0x4D,0x77,0x31,0x31,0x65,0x94, - 0xC1,0x2C,0x2D,0x16,0x2D,0x4C,0x8A,0xF3,0xAA,0x2C,0x63,0x3A,0x26,0x94,0x8F,0x5C, - 0x04,0x32,0xB4,0x00,0x77,0x00,0xA4,0xB9,0x09,0x90,0xB4,0x18,0x58,0x14,0x87,0xBB, - 0x13,0xA2,0xCC,0x67,0x70,0x0A,0x3C,0x35,0x98,0x04,0xF9,0x1B,0xDF,0xB8,0xE3,0x77, - 0xCD,0x0E,0xC8,0x0D,0xDC,0x10,0x00,0x00,0x01,0x5E,0xAB,0x85,0x57,0xEC,0x00,0x00, - 0x04,0x03,0x00,0x48,0x30,0x46,0x02,0x21,0x00,0xE4,0x54,0x30,0xB7,0x22,0x75,0x2E, - 0x6B,0x3F,0xE9,0x65,0x5D,0x59,0x8B,0x0E,0x9F,0x44,0x9D,0x8C,0x05,0xB1,0xFB,0x11, - 0xD7,0x59,0x98,0x3C,0x35,0xEA,0x52,0xEA,0x9E,0x02,0x21,0x00,0xBD,0x07,0x6C,0x78, - 0x5B,0x81,0xFF,0x45,0x6E,0x8C,0x68,0x99,0x41,0x72,0xC1,0xE5,0x36,0x71,0x81,0x00, - 0x85,0x1D,0x2A,0xC4,0xFD,0x9E,0x7D,0x85,0xC0,0xD5,0x8F,0x6A,0x00,0x76,0x00,0xEE, - 0x4B,0xBD,0xB7,0x75,0xCE,0x60,0xBA,0xE1,0x42,0x69,0x1F,0xAB,0xE1,0x9E,0x66,0xA3, - 0x0F,0x7E,0x5F,0xB0,0x72,0xD8,0x83,0x00,0xC4,0x7B,0x89,0x7A,0xA8,0xFD,0xCB,0x00, - 0x00,0x01,0x5E,0xAB,0x85,0x59,0xB0,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02, - 0x21,0x00,0xD5,0x8C,0xD3,0x11,0xE6,0x08,0xAA,0xCC,0x98,0x35,0xFC,0xED,0x49,0xF0, - 0x34,0x8B,0xE2,0x68,0x0D,0x66,0x65,0x8F,0x1D,0x56,0x7A,0x7E,0xC7,0x35,0x19,0xD1, - 0xB7,0x0A,0x02,0x20,0x6A,0x96,0x22,0xEC,0x63,0x63,0x79,0xE5,0x5E,0x27,0x98,0x19, - 0xDE,0x4F,0xFC,0x69,0x0A,0x22,0x64,0x97,0x70,0x92,0x67,0x9C,0x7C,0xF4,0x00,0xD1, - 0xDF,0xC2,0x61,0xE6,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, - 0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x88,0x75,0x7C,0xEE,0x8C,0x6F,0x9E,0xE3, - 0xDA,0xB9,0x40,0x53,0x78,0xED,0x57,0x11,0x4C,0xE4,0x3F,0x11,0x4A,0xC3,0xDA,0x80, - 0x97,0xF4,0xF8,0x8E,0x0F,0x8E,0xB1,0x73,0x67,0x83,0xDE,0x3E,0x9E,0x2C,0x85,0x6B, - 0x02,0xB5,0x73,0x48,0x26,0x4D,0x43,0xD7,0x04,0xBD,0xC7,0x7D,0xC4,0xDC,0x03,0xB8, - 0x0B,0x35,0x7C,0x39,0x2C,0x42,0x24,0xB3,0xDC,0x15,0x78,0xF6,0x54,0x70,0xFC,0xE0, - 0x9B,0xF5,0x9F,0x30,0x08,0xB0,0x2F,0x4B,0xF1,0xA1,0x49,0x96,0x08,0x76,0x5C,0xAE, - 0xDC,0x3E,0x95,0x0D,0x1A,0x89,0x0C,0xDA,0x32,0xAD,0x2A,0x4B,0xD7,0x63,0x50,0x8C, - 0x0C,0xE3,0x08,0xEC,0x6F,0x78,0x55,0x67,0x05,0x68,0x65,0x22,0x39,0xE3,0x7E,0x36, - 0xD9,0x90,0xD2,0x3D,0x06,0x36,0xC7,0xDE,0xEE,0xF4,0xD6,0xDD,0xDA,0xC3,0xFB,0xAC, - 0x43,0xFE,0x2F,0x1C,0x64,0x9B,0xE2,0xDD,0xC0,0x89,0x8B,0x52,0x98,0x8D,0x0E,0xF6, - 0x09,0x2D,0xE4,0x4D,0x62,0x9C,0x16,0x22,0x96,0xFB,0x68,0x5B,0x94,0x87,0x87,0xCE, - 0x18,0x7E,0x41,0x60,0x79,0xA4,0x17,0x3E,0x71,0xF2,0xB1,0xA2,0x06,0xD8,0x71,0xD8, - 0x33,0x0B,0x6A,0xD4,0x67,0x68,0x24,0x3E,0xBA,0xC6,0x21,0x94,0x5D,0x6A,0xF6,0x21, - 0x84,0x5F,0xD0,0xFF,0xAC,0xE4,0x3D,0xAA,0xAD,0x95,0x85,0xFC,0x4B,0x69,0x30,0x72, - 0xB7,0xBA,0x4D,0xDA,0x3A,0xED,0xD9,0x7D,0x40,0x1D,0x02,0x29,0xB8,0xD5,0x0C,0x09, - 0x9E,0x0D,0x74,0x8B,0xFA,0x62,0x02,0x4A,0x88,0x6E,0x7C,0x13,0x56,0xBA,0x99,0x3F, - 0x13,0x78,0x48,0x82,0xAC,0x43,0x8E,0x61, -}; - - -/* subject:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */ -/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */ -static const uint8_t _c1[]= { - 0x30,0x82,0x05,0x2B,0x30,0x82,0x04,0x13,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x7E, - 0xE1,0x4A,0x6F,0x6F,0xEF,0xF2,0xD3,0x7F,0x3F,0xAD,0x65,0x4D,0x3A,0xDA,0xB4,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, - 0xCA,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, - 0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67, - 0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B, - 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74, - 0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04, - 0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69, - 0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72, - 0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20, - 0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56, - 0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20, - 0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43, - 0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74, - 0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x35,0x30,0x1E,0x17,0x0D,0x31, - 0x33,0x31,0x30,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x33, - 0x31,0x30,0x33,0x30,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x77,0x31,0x0B,0x30, - 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30,0x1B,0x06,0x03, - 0x55,0x04,0x0A,0x13,0x14,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20,0x43,0x6F, - 0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55, - 0x04,0x0B,0x13,0x16,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20,0x54,0x72,0x75, - 0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x28,0x30,0x26,0x06,0x03, - 0x55,0x04,0x03,0x13,0x1F,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20,0x43,0x6C, - 0x61,0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20,0x43,0x41,0x20, - 0x2D,0x20,0x47,0x33,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,0xD8,0xA1,0x65,0x74,0x23,0xE8,0x2B,0x64,0xE2,0x32,0xD7, - 0x33,0x37,0x3D,0x8E,0xF5,0x34,0x16,0x48,0xDD,0x4F,0x7F,0x87,0x1C,0xF8,0x44,0x23, - 0x13,0x8E,0xFB,0x11,0xD8,0x44,0x5A,0x18,0x71,0x8E,0x60,0x16,0x26,0x92,0x9B,0xFD, - 0x17,0x0B,0xE1,0x71,0x70,0x42,0xFE,0xBF,0xFA,0x1C,0xC0,0xAA,0xA3,0xA7,0xB5,0x71, - 0xE8,0xFF,0x18,0x83,0xF6,0xDF,0x10,0x0A,0x13,0x62,0xC8,0x3D,0x9C,0xA7,0xDE,0x2E, - 0x3F,0x0C,0xD9,0x1D,0xE7,0x2E,0xFB,0x2A,0xCE,0xC8,0x9A,0x7F,0x87,0xBF,0xD8,0x4C, - 0x04,0x15,0x32,0xC9,0xD1,0xCC,0x95,0x71,0xA0,0x4E,0x28,0x4F,0x84,0xD9,0x35,0xFB, - 0xE3,0x86,0x6F,0x94,0x53,0xE6,0x72,0x8A,0x63,0x67,0x2E,0xBE,0x69,0xF6,0xF7,0x6E, - 0x8E,0x9C,0x60,0x04,0xEB,0x29,0xFA,0xC4,0x47,0x42,0xD2,0x78,0x98,0xE3,0xEC,0x0B, - 0xA5,0x92,0xDC,0xB7,0x9A,0xBD,0x80,0x64,0x2B,0x38,0x7C,0x38,0x09,0x5B,0x66,0xF6, - 0x2D,0x95,0x7A,0x86,0xB2,0x34,0x2E,0x85,0x9E,0x90,0x0E,0x5F,0xB7,0x5D,0xA4,0x51, - 0x72,0x46,0x70,0x13,0xBF,0x67,0xF2,0xB6,0xA7,0x4D,0x14,0x1E,0x6C,0xB9,0x53,0xEE, - 0x23,0x1A,0x4E,0x8D,0x48,0x55,0x43,0x41,0xB1,0x89,0x75,0x6A,0x40,0x28,0xC5,0x7D, - 0xDD,0xD2,0x6E,0xD2,0x02,0x19,0x2F,0x7B,0x24,0x94,0x4B,0xEB,0xF1,0x1A,0xA9,0x9B, - 0xE3,0x23,0x9A,0xEA,0xFA,0x33,0xAB,0x0A,0x2C,0xB7,0xF4,0x60,0x08,0xDD,0x9F,0x1C, - 0xCD,0xDD,0x2D,0x01,0x66,0x80,0xAF,0xB3,0x2F,0x29,0x1D,0x23,0xB8,0x8A,0xE1,0xA1, - 0x70,0x07,0x0C,0x34,0x0F,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x5D,0x30,0x82, - 0x01,0x59,0x30,0x2F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x23, - 0x30,0x21,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x13, - 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x32,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E, - 0x63,0x6F,0x6D,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30, - 0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x65,0x06,0x03,0x55,0x1D,0x20,0x04,0x5E, - 0x30,0x5C,0x30,0x5A,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x52,0x30,0x26,0x06,0x08, - 0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F, - 0x2F,0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D, - 0x2F,0x63,0x70,0x73,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02, - 0x30,0x1C,0x1A,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73, - 0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x70,0x61,0x30,0x30, - 0x06,0x03,0x55,0x1D,0x1F,0x04,0x29,0x30,0x27,0x30,0x25,0xA0,0x23,0xA0,0x21,0x86, - 0x1F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x31,0x2E,0x73,0x79,0x6D,0x63,0x62, - 0x2E,0x63,0x6F,0x6D,0x2F,0x70,0x63,0x61,0x33,0x2D,0x67,0x35,0x2E,0x63,0x72,0x6C, - 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06, - 0x30,0x29,0x06,0x03,0x55,0x1D,0x11,0x04,0x22,0x30,0x20,0xA4,0x1E,0x30,0x1C,0x31, - 0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x53,0x79,0x6D,0x61,0x6E,0x74, - 0x65,0x63,0x50,0x4B,0x49,0x2D,0x31,0x2D,0x35,0x33,0x33,0x30,0x1D,0x06,0x03,0x55, - 0x1D,0x0E,0x04,0x16,0x04,0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59,0xA6,0x64, - 0x63,0xD6,0xCF,0x20,0x07,0x57,0xD5,0x91,0xE7,0x6A,0x30,0x1F,0x06,0x03,0x55,0x1D, - 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7F,0xD3,0x65,0xA7,0xC2,0xDD,0xEC,0xBB,0xF0, - 0x30,0x09,0xF3,0x43,0x39,0xFA,0x02,0xAF,0x33,0x31,0x33,0x30,0x0D,0x06,0x09,0x2A, - 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x42, - 0x01,0x55,0x7B,0xD0,0x16,0x1A,0x5D,0x58,0xE8,0xBB,0x9B,0xA8,0x4D,0xD7,0xF3,0xD7, - 0xEB,0x13,0x94,0x86,0xD6,0x7F,0x21,0x0B,0x47,0xBC,0x57,0x9B,0x92,0x5D,0x4F,0x05, - 0x9F,0x38,0xA4,0x10,0x7C,0xCF,0x83,0xBE,0x06,0x43,0x46,0x8D,0x08,0xBC,0x6A,0xD7, - 0x10,0xA6,0xFA,0xAB,0xAF,0x2F,0x61,0xA8,0x63,0xF2,0x65,0xDF,0x7F,0x4C,0x88,0x12, - 0x88,0x4F,0xB3,0x69,0xD9,0xFF,0x27,0xC0,0x0A,0x97,0x91,0x8F,0x56,0xFB,0x89,0xC4, - 0xA8,0xBB,0x92,0x2D,0x1B,0x73,0xB0,0xC6,0xAB,0x36,0xF4,0x96,0x6C,0x20,0x08,0xEF, - 0x0A,0x1E,0x66,0x24,0x45,0x4F,0x67,0x00,0x40,0xC8,0x07,0x54,0x74,0x33,0x3B,0xA6, - 0xAD,0xBB,0x23,0x9F,0x66,0xED,0xA2,0x44,0x70,0x34,0xFB,0x0E,0xEA,0x01,0xFD,0xCF, - 0x78,0x74,0xDF,0xA7,0xAD,0x55,0xB7,0x5F,0x4D,0xF6,0xD6,0x3F,0xE0,0x86,0xCE,0x24, - 0xC7,0x42,0xA9,0x13,0x14,0x44,0x35,0x4B,0xB6,0xDF,0xC9,0x60,0xAC,0x0C,0x7F,0xD9, - 0x93,0x21,0x4B,0xEE,0x9C,0xE4,0x49,0x02,0x98,0xD3,0x60,0x7B,0x5C,0xBC,0xD5,0x30, - 0x2F,0x07,0xCE,0x44,0x42,0xC4,0x0B,0x99,0xFE,0xE6,0x9F,0xFC,0xB0,0x78,0x86,0x51, - 0x6D,0xD1,0x2C,0x9D,0xC6,0x96,0xFB,0x85,0x82,0xBB,0x04,0x2F,0xF7,0x62,0x80,0xEF, - 0x62,0xDA,0x7F,0xF6,0x0E,0xAC,0x90,0xB8,0x56,0xBD,0x79,0x3F,0xF2,0x80,0x6E,0xA3, - 0xD9,0xB9,0x0F,0x5D,0x3A,0x07,0x1D,0x91,0x93,0x86,0x4B,0x29,0x4C,0xE1,0xDC,0xB5, - 0xE1,0xE0,0x33,0x9D,0xB3,0xCB,0x36,0x91,0x4B,0xFE,0xA1,0xB4,0xEE,0xF0,0xF9, -}; - -static const uint8_t _responderCert[]= { - 0x30,0x82,0x04,0x58,0x30,0x82,0x03,0x40,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x03, - 0x56,0x99,0xC9,0x07,0x45,0xC1,0xA9,0x4C,0x50,0x3A,0x24,0x28,0xD6,0x04,0x5D,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x77, - 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30, - 0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, - 0x20,0x43,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x1F,0x30,0x1D, - 0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20, - 0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x28,0x30, - 0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, - 0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20, - 0x43,0x41,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,0x37,0x31, - 0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x37,0x31,0x30,0x31,0x36, - 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55, - 0x04,0x03,0x13,0x2E,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20,0x43,0x6C,0x61, - 0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20,0x43,0x41,0x20,0x2D, - 0x20,0x47,0x33,0x20,0x4F,0x43,0x53,0x50,0x20,0x52,0x65,0x73,0x70,0x6F,0x6E,0x64, - 0x65,0x72,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,0xA1,0x49,0x87,0x17,0x74,0x89,0x30,0x97,0x77,0x0D,0x11,0x51,0x51, - 0x3A,0x80,0x2D,0x7C,0xEC,0xB2,0x4C,0xB1,0xE5,0x46,0x51,0x1C,0xF5,0x7A,0x02,0xB3, - 0x77,0x19,0x3B,0x7B,0x94,0x00,0x1A,0xA4,0xD1,0xB8,0xF0,0x07,0xF2,0x1B,0x8D,0x70, - 0xC0,0x81,0x44,0xB5,0x58,0xD8,0x34,0xEC,0x62,0xF7,0x8B,0x4B,0x3C,0x44,0x7D,0xD0, - 0x35,0xAE,0xEF,0x2B,0xFB,0x75,0xAF,0xB3,0x10,0x32,0xC8,0xF9,0x08,0x2C,0x5C,0x1B, - 0x07,0x56,0x7C,0x88,0x6D,0xEE,0x4C,0xD5,0x8F,0xD4,0x48,0x41,0xBB,0x03,0xA8,0xBF, - 0x20,0xE8,0x52,0xFB,0x24,0x5F,0x90,0x78,0xB8,0x87,0x0D,0xD5,0x17,0xAB,0xA8,0xF0, - 0xDB,0xF8,0x61,0x9F,0xF8,0x09,0x88,0x79,0x19,0x6F,0x57,0xC6,0x69,0x01,0x08,0xAA, - 0xC6,0xBF,0x8D,0x0C,0x2D,0xD3,0x54,0x89,0x03,0xC8,0xA8,0x55,0x00,0xC2,0x89,0xEC, - 0x8E,0xD8,0xD8,0x12,0x15,0x26,0x67,0x8E,0x88,0x0F,0x94,0xFA,0x57,0x50,0xE7,0xE9, - 0x7B,0x1B,0x94,0xF6,0xF1,0xE2,0x91,0x02,0x42,0x4F,0x3B,0x3E,0xB6,0xDD,0x3C,0x78, - 0xE7,0xC8,0x45,0x4F,0x7B,0x7D,0x41,0xD5,0x95,0x3C,0xD6,0x16,0x84,0xF5,0x16,0xF2, - 0x45,0x6C,0xBF,0x05,0x00,0x7E,0x92,0x70,0xB7,0x01,0x14,0x86,0x89,0x89,0x9D,0x6B, - 0xDC,0x5D,0xDF,0x30,0x25,0x7F,0xAA,0x93,0xC0,0xC7,0xC7,0x80,0x12,0xEE,0x47,0xF7, - 0x90,0x69,0x82,0x86,0xFA,0x22,0x11,0x45,0xAB,0xD1,0x50,0x4F,0xED,0x87,0xCA,0x99, - 0x20,0xB5,0xC1,0x8D,0xAC,0x01,0x41,0x5C,0x70,0x3C,0x4D,0xD7,0x8E,0xD6,0x8F,0x51, - 0x19,0x79,0xAB,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x1C,0x30,0x82,0x01,0x18, - 0x30,0x0F,0x06,0x09,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,0x04,0x02,0x05, - 0x00,0x30,0x22,0x06,0x03,0x55,0x1D,0x11,0x04,0x1B,0x30,0x19,0xA4,0x17,0x30,0x15, - 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x54,0x47,0x56,0x2D,0x45, - 0x2D,0x32,0x31,0x35,0x32,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, - 0x80,0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59,0xA6,0x64,0x63,0xD6,0xCF,0x20, - 0x07,0x57,0xD5,0x91,0xE7,0x6A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, - 0x14,0xE3,0x5E,0x00,0x73,0xB3,0x6F,0xFB,0x26,0x90,0x5A,0xE3,0xE5,0xF4,0xB5,0x99, - 0x95,0xEA,0x80,0xFA,0x9F,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, - 0x02,0x30,0x00,0x30,0x6E,0x06,0x03,0x55,0x1D,0x20,0x04,0x67,0x30,0x65,0x30,0x63, - 0x06,0x0B,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x17,0x03,0x30,0x54,0x30, - 0x26,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74, - 0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E, - 0x63,0x6F,0x6D,0x2F,0x63,0x70,0x73,0x30,0x2A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05, - 0x07,0x02,0x02,0x30,0x1E,0x1A,0x1C,0x20,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, - 0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,0x2F, - 0x72,0x70,0x61,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08, - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01, - 0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, - 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x3B,0x57,0xAB,0x23, - 0x8E,0x31,0x91,0x87,0x0E,0x02,0xC1,0x55,0xD4,0x53,0x58,0x16,0xEA,0x1B,0x77,0x61, - 0x68,0x88,0x96,0xC6,0x8D,0x4F,0x57,0xD8,0x80,0x04,0xD2,0xCB,0x41,0x84,0xE9,0x78, - 0xB1,0x21,0xD0,0xFD,0xB6,0x68,0x8C,0xB0,0xD5,0xED,0x28,0xB3,0xA9,0x9A,0x8A,0xBB, - 0x88,0x09,0x30,0x04,0xB1,0x29,0xC6,0xC9,0x13,0x4F,0xDB,0xDA,0x52,0x00,0x3A,0x61, - 0xEE,0xD5,0x6F,0xAB,0xDE,0x71,0x1B,0x8E,0xFA,0xE0,0x1F,0x09,0x9D,0x00,0xF1,0x1F, - 0xAC,0x88,0x73,0x86,0x37,0xDA,0x7A,0x05,0x3F,0xDB,0xD2,0xEB,0x47,0x0B,0xC9,0x39, - 0x74,0xA4,0x06,0xBD,0x50,0x63,0x52,0xEE,0x9F,0xE7,0x58,0x07,0x95,0x85,0x6D,0x43, - 0xE8,0x3B,0x7E,0x0D,0x36,0x65,0x2A,0xB1,0x62,0xB5,0xDB,0x31,0x49,0x38,0x7F,0x6D, - 0x4E,0xE0,0x9D,0x84,0x79,0x68,0xC3,0x1B,0xFB,0x89,0x54,0xFB,0x3C,0xEC,0xD1,0xF9, - 0xF1,0xC2,0x57,0xD4,0xBF,0xBE,0xA6,0x22,0xD2,0x84,0xC3,0xC2,0x0E,0x9E,0x0E,0x54, - 0x25,0x79,0x91,0x16,0x4E,0xBC,0x2B,0xD4,0x4F,0x63,0xB3,0x5B,0x7C,0x70,0x91,0xDE, - 0xE2,0x70,0x34,0xB9,0x21,0xB4,0x89,0xF6,0x98,0x12,0x9E,0x38,0xF8,0x36,0x29,0x9D, - 0x0A,0xEC,0xC6,0x69,0xD6,0xC6,0x2E,0xB8,0x38,0x07,0x3F,0xC5,0x52,0x8A,0xEE,0x6F, - 0x20,0xDE,0x62,0xA7,0x85,0xEC,0x05,0x4A,0x15,0x1B,0x3D,0xA6,0x79,0x09,0x76,0xB0, - 0x8B,0xDC,0x13,0xD1,0xD2,0x5E,0xAB,0x65,0x99,0x4D,0xA6,0x49,0x66,0xB8,0x2C,0x77, - 0xAC,0x85,0x71,0xA4,0x69,0x59,0xA6,0xD4,0xAD,0x61,0xA1,0xCE, -}; - -/* subject:/serialNumber=424761419/1.3.6.1.4.1.311.60.2.1.3=FR/1.3.6.1.4.1.311.60.2.1.2=Nord/1.3.6.1.4.1.311.60.2.1.1=ROUBAIX/2.5.4.15=V1.0, Clause 5.(b)/C=FR/postalCode=59100/ST=Nord/L=ROUBAIX/streetAddress=140 quai du Sartel/O=OVH/OU=0002 424761419 */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO EV SGC CA */ -static unsigned char ovh_certificate[1546]={ -0x30,0x82,0x06,0x06,0x30,0x82,0x04,0xEE,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x31, -0xF0,0x42,0x6A,0x0B,0xBB,0xE7,0x45,0xD4,0x0E,0x51,0x9B,0xE0,0xE5,0xC1,0xB4,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x73, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,0x30, -0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20, -0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,0x03, -0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,0x18, -0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x41, -0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04, -0x03,0x13,0x10,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x45,0x56,0x20,0x53,0x47,0x43, -0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x38,0x31,0x32,0x30,0x32,0x30,0x30,0x30, -0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39, -0x35,0x39,0x5A,0x30,0x82,0x01,0x48,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x05, -0x13,0x09,0x34,0x32,0x34,0x37,0x36,0x31,0x34,0x31,0x39,0x31,0x13,0x30,0x11,0x06, -0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x46,0x52, -0x31,0x15,0x30,0x13,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01, -0x02,0x13,0x04,0x4E,0x6F,0x72,0x64,0x31,0x18,0x30,0x16,0x06,0x0B,0x2B,0x06,0x01, -0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,0x13,0x07,0x52,0x4F,0x55,0x42,0x41,0x49, -0x58,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x0F,0x13,0x12,0x56,0x31,0x2E,0x30, -0x2C,0x20,0x43,0x6C,0x61,0x75,0x73,0x65,0x20,0x35,0x2E,0x28,0x62,0x29,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x52,0x31,0x0E,0x30,0x0C,0x06, -0x03,0x55,0x04,0x11,0x13,0x05,0x35,0x39,0x31,0x30,0x30,0x31,0x0D,0x30,0x0B,0x06, -0x03,0x55,0x04,0x08,0x13,0x04,0x4E,0x6F,0x72,0x64,0x31,0x10,0x30,0x0E,0x06,0x03, -0x55,0x04,0x07,0x13,0x07,0x52,0x4F,0x55,0x42,0x41,0x49,0x58,0x31,0x1B,0x30,0x19, -0x06,0x03,0x55,0x04,0x09,0x13,0x12,0x31,0x34,0x30,0x20,0x71,0x75,0x61,0x69,0x20, -0x64,0x75,0x20,0x53,0x61,0x72,0x74,0x65,0x6C,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55, -0x04,0x0A,0x13,0x03,0x4F,0x56,0x48,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0B, -0x13,0x0E,0x30,0x30,0x30,0x32,0x20,0x34,0x32,0x34,0x37,0x36,0x31,0x34,0x31,0x39, -0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x48,0x6F,0x73,0x74,0x65, -0x64,0x20,0x62,0x79,0x20,0x54,0x42,0x53,0x20,0x49,0x4E,0x54,0x45,0x52,0x4E,0x45, -0x54,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0B,0x13,0x0D,0x43,0x6F,0x6D,0x6F, -0x64,0x6F,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x31,0x14,0x30,0x12,0x06,0x03,0x55, -0x04,0x03,0x13,0x0B,0x77,0x77,0x77,0x2E,0x6F,0x76,0x68,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, -0xAF,0x7C,0x18,0x7E,0x00,0x52,0x8E,0x89,0x51,0x56,0x30,0xC8,0x83,0xED,0x53,0xAE, -0x19,0xB3,0xA2,0x09,0x1A,0x17,0x41,0x6A,0x72,0x26,0xBC,0x77,0x47,0x0A,0xEA,0xA7, -0x74,0x01,0x68,0x5D,0xC1,0x40,0x54,0x77,0xF2,0x03,0xAC,0xDA,0x1D,0x9F,0xAE,0xD0, -0x0F,0x13,0x28,0xDD,0xF6,0x98,0xF5,0xAF,0x3D,0x69,0xDE,0xF0,0xE6,0x34,0xFD,0xB9, -0x94,0x91,0x26,0x9D,0x56,0x9C,0xA5,0xD4,0xBA,0x04,0xFD,0xDA,0x5C,0x8D,0xCB,0x85, -0x81,0x9D,0xD0,0x85,0x62,0x83,0x41,0xB6,0xAC,0x14,0xC3,0xAA,0xAE,0xA7,0x54,0x84, -0xFD,0xED,0x9C,0xFC,0xB2,0x51,0xD1,0x43,0x5B,0xF3,0x6E,0xB9,0x6D,0xB1,0xE2,0x19, -0xB1,0xB4,0xC6,0x15,0x10,0x78,0xBB,0x68,0x8D,0x4D,0x8D,0xE5,0xB2,0x97,0xFD,0x50, -0xE1,0x07,0x14,0x0A,0xD3,0x28,0x0E,0x0A,0xFB,0xF3,0x18,0x65,0x2E,0xB1,0xD6,0xEE, -0x00,0x4D,0xB8,0xB7,0xB9,0x86,0x90,0x97,0xC2,0x66,0xCC,0x09,0x11,0xFC,0xD7,0x4B, -0xEF,0x4A,0x8B,0x9E,0x13,0xD0,0x5E,0x71,0x57,0xA9,0x39,0x91,0x6A,0xB2,0x60,0xC9, -0x45,0xED,0xD9,0xFA,0x35,0xFF,0xF8,0x28,0xBB,0x87,0x90,0x99,0xBB,0x45,0x30,0x4A, -0x15,0xC3,0x1D,0x6E,0xCD,0x02,0x1A,0x28,0x8E,0x89,0x1A,0x1A,0xC6,0x58,0xD8,0x78, -0x1F,0xF0,0x24,0xFE,0x79,0x26,0xA8,0xCF,0x10,0x1E,0x31,0x58,0xF6,0x21,0xBA,0x05, -0x31,0xF4,0x44,0x89,0x1B,0xC1,0x24,0x62,0x38,0xA8,0xCA,0x1A,0xCE,0x2F,0x2C,0xFA, -0xB6,0x4F,0x12,0xD4,0x30,0xC6,0xDC,0xC5,0x5B,0x1B,0x8D,0xA2,0xAB,0xCE,0xC3,0x03, -0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0xBD,0x30,0x82,0x01,0xB9,0x30,0x1F,0x06, -0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7F,0xF6,0x4C,0x36,0x28,0x14, -0xAE,0xCD,0x1E,0x37,0xAF,0xDE,0x5A,0xF2,0x5B,0xC3,0xA0,0xAC,0x2B,0xFE,0x30,0x1D, -0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xA4,0x72,0x61,0x0C,0x67,0xA4,0x90, -0xCC,0x81,0x5A,0xDB,0xDF,0x7E,0xE8,0x08,0xF3,0xDA,0x3A,0x1E,0x55,0x30,0x0E,0x06, -0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x0C,0x06, -0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x34,0x06,0x03,0x55, -0x1D,0x25,0x04,0x2D,0x30,0x2B,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, -0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x0A,0x2B,0x06,0x01,0x04, -0x01,0x82,0x37,0x0A,0x03,0x03,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04, -0x01,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04, -0x03,0x02,0x06,0xC0,0x30,0x46,0x06,0x03,0x55,0x1D,0x20,0x04,0x3F,0x30,0x3D,0x30, -0x3B,0x06,0x0C,0x2B,0x06,0x01,0x04,0x01,0xB2,0x31,0x01,0x02,0x01,0x05,0x01,0x30, -0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,0x68, -0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,0x6F, -0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x30,0x3A,0x06,0x03, -0x55,0x1D,0x1F,0x04,0x33,0x30,0x31,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68, -0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F, -0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x6F,0x6D,0x6F,0x64,0x6F,0x45,0x56,0x53, -0x47,0x43,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x6B,0x06,0x08,0x2B,0x06,0x01,0x05, -0x05,0x07,0x01,0x01,0x04,0x5F,0x30,0x5D,0x30,0x35,0x06,0x08,0x2B,0x06,0x01,0x05, -0x05,0x07,0x30,0x02,0x86,0x29,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x74, -0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x6F, -0x6D,0x6F,0x64,0x6F,0x45,0x56,0x53,0x47,0x43,0x43,0x41,0x2E,0x63,0x72,0x74,0x30, -0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74, -0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63, -0x61,0x2E,0x63,0x6F,0x6D,0x30,0x1F,0x06,0x03,0x55,0x1D,0x11,0x04,0x18,0x30,0x16, -0x82,0x0B,0x77,0x77,0x77,0x2E,0x6F,0x76,0x68,0x2E,0x63,0x6F,0x6D,0x82,0x07,0x6F, -0x76,0x68,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x85,0x1C,0xDD,0x46,0x8F,0x8A, -0x37,0x7F,0xB7,0x13,0x67,0xE2,0x83,0x0A,0xEC,0x6F,0x29,0x02,0xD2,0x03,0xE0,0x84, -0x66,0x28,0x37,0x0E,0xFF,0x61,0x14,0x0A,0xF5,0x62,0xBF,0x25,0x2B,0x01,0x3F,0xD2, -0x27,0xCC,0x6B,0xB3,0x79,0xC2,0x93,0x9D,0xA4,0x56,0x6E,0x0C,0x8B,0x25,0x49,0xAA, -0x8B,0xC9,0xDD,0x6A,0x68,0xFC,0x32,0xDC,0x83,0x17,0x10,0x87,0x90,0x06,0xC3,0xA7, -0x16,0x77,0x05,0x7D,0x42,0xD7,0xBE,0xA5,0x5F,0x89,0x90,0xA8,0xF8,0x3A,0xFE,0x2E, -0x95,0x7F,0x51,0x88,0x7D,0xFC,0xA3,0x8A,0x83,0xFF,0xD1,0x86,0xB2,0x30,0x3F,0x22, -0x77,0xD4,0xE2,0xD8,0x61,0x78,0x50,0x16,0xE1,0x38,0xAD,0x75,0x7F,0x64,0x3D,0x4B, -0x65,0x06,0x58,0x07,0xBF,0x1B,0x62,0xB2,0xE0,0xC9,0x55,0x08,0x6D,0x0D,0xF1,0x53, -0x25,0x25,0x12,0x50,0x07,0x84,0xEA,0x43,0x95,0x7D,0xF1,0x1B,0x80,0xFE,0xE4,0x2D, -0xA5,0x42,0x77,0x2F,0x9E,0x79,0x24,0x0A,0xB0,0xE5,0xCB,0xE7,0x9B,0xA6,0x09,0x7B, -0xD0,0x5B,0x72,0x43,0x6C,0x91,0x31,0x48,0x35,0x6C,0xA2,0xB6,0xF4,0x64,0xAD,0x7B, -0x7A,0x25,0x34,0xBA,0x2E,0xB4,0x52,0x2C,0x65,0x41,0xE5,0xCE,0xB2,0x53,0xEF,0xE7, -0xFF,0x0C,0x39,0x72,0x61,0x91,0x21,0xBB,0x75,0x9A,0x11,0xD0,0xAB,0xB3,0x94,0x08, -0x44,0xDA,0x78,0xF7,0x92,0x98,0x48,0xAD,0xE4,0xB6,0xBB,0x9F,0xFD,0x59,0x37,0xB6, -0x42,0x8E,0xEE,0x99,0x90,0xB2,0xA0,0xB5,0xF3,0x68,0xA7,0x54,0x46,0xB6,0x6C,0x05, -0x27,0x75,0x60,0x87,0x25,0x2E,0x2A,0x16,0xDA,0xA1, -}; - -/* This is the cert the ssl server returns to us. */ -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO EV SGC CA */ -/* issuer :/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC */ -static unsigned char comodo_ev_certificate[1232]={ -0x30,0x82,0x04,0xCC,0x30,0x82,0x03,0xB4,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x3B, -0x9F,0xB1,0xF2,0xC0,0x97,0x44,0x9D,0x61,0xA4,0x8F,0x5F,0xF9,0xA6,0xF5,0xE0,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, -0x93,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x13,0x02,0x55,0x54,0x31,0x17,0x30,0x15,0x06, -0x03,0x55,0x04,0x07,0x13,0x0E,0x53,0x61,0x6C,0x74,0x20,0x4C,0x61,0x6B,0x65,0x20, -0x43,0x69,0x74,0x79,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15,0x54, -0x68,0x65,0x20,0x55,0x53,0x45,0x52,0x54,0x52,0x55,0x53,0x54,0x20,0x4E,0x65,0x74, -0x77,0x6F,0x72,0x6B,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x68, -0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x75,0x73,0x65,0x72,0x74,0x72, -0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03, -0x13,0x12,0x55,0x54,0x4E,0x20,0x2D,0x20,0x44,0x41,0x54,0x41,0x43,0x6F,0x72,0x70, -0x20,0x53,0x47,0x43,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x30,0x31,0x30,0x30, -0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x32,0x34,0x31,0x39,0x30, -0x36,0x33,0x30,0x5A,0x30,0x73,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72, -0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72, -0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F, -0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D, -0x4F,0x44,0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x19, -0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20, -0x45,0x56,0x20,0x53,0x47,0x43,0x20,0x43,0x41,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,0xE8,0xCE,0xAA,0xA9,0x25,0xAF, -0x2E,0x8E,0xD1,0x79,0x95,0x5E,0xA4,0x88,0x24,0x4F,0xFD,0xB3,0x5C,0xAE,0x2A,0x9E, -0x4A,0x7B,0x40,0xE0,0xCC,0x50,0xE9,0x81,0x58,0x15,0xD2,0x87,0xF7,0xAD,0x85,0x7A, -0x69,0x52,0xA0,0x95,0x6E,0x8F,0x67,0x09,0x8E,0xF1,0xF3,0x5C,0x17,0xE3,0x49,0x42, -0xC8,0x12,0x67,0xA6,0x05,0xF8,0x37,0xA0,0x0F,0x16,0x61,0x0F,0x8F,0x31,0x52,0xC6, -0xE1,0x87,0xE1,0x4F,0xB9,0xDB,0xC9,0xFE,0x69,0x1B,0xD4,0xC9,0xF7,0x2D,0xAC,0x48, -0xD7,0x73,0x4A,0x04,0x95,0xE3,0xA1,0x37,0x87,0x52,0x5A,0x88,0xB3,0xD6,0x01,0x2C, -0xF1,0x03,0x70,0x2C,0x26,0x70,0x2B,0x47,0x3B,0x0A,0xAE,0x31,0x7A,0xD7,0xE5,0x14, -0x4E,0xAC,0x2F,0x30,0xE1,0x7C,0x6D,0x36,0xDA,0xA0,0xF5,0x83,0x62,0x5D,0x88,0x26, -0x0D,0x05,0x45,0x5E,0xCE,0xF7,0x8B,0xEB,0x95,0xB4,0xE0,0xEB,0x10,0x7A,0xD4,0xB9, -0x59,0x75,0x46,0x52,0xDD,0x86,0x74,0x84,0xCB,0x5F,0xD3,0x1C,0x41,0xEA,0xF0,0x9A, -0xDA,0x91,0x64,0x84,0xDF,0xDE,0x9F,0xF2,0xDD,0xD0,0xFA,0xA6,0x68,0x96,0xB7,0x3E, -0x97,0x2D,0x7F,0xB1,0xFB,0x8C,0x6C,0xA7,0xFE,0x72,0x82,0xD0,0xE3,0x8A,0xD3,0xBB, -0xE3,0xCE,0x01,0xB7,0x9D,0x67,0xE9,0xA9,0x13,0x9A,0x3B,0x21,0xED,0xF7,0x73,0x13, -0xE3,0x33,0x5D,0x7A,0x01,0xA9,0xCA,0x49,0xD0,0x4E,0x63,0x87,0x57,0x81,0x3A,0x17, -0x54,0x30,0xF6,0x02,0x5E,0x94,0xB6,0x60,0xD2,0x29,0xF9,0x4E,0xE7,0x29,0xA0,0xA0, -0x9D,0x2A,0x5B,0xEB,0x3F,0x89,0x2E,0x45,0xA2,0xFD,0x02,0x03,0x01,0x00,0x01,0xA3, -0x82,0x01,0x39,0x30,0x82,0x01,0x35,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, -0x30,0x16,0x80,0x14,0x53,0x32,0xD1,0xB3,0xCF,0x7F,0xFA,0xE0,0xF1,0xA0,0x5D,0x85, -0x4E,0x92,0xD2,0x9E,0x45,0x1D,0xB4,0x4F,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, -0x16,0x04,0x14,0x7F,0xF6,0x4C,0x36,0x28,0x14,0xAE,0xCD,0x1E,0x37,0xAF,0xDE,0x5A, -0xF2,0x5B,0xC3,0xA0,0xAC,0x2B,0xFE,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, -0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01, -0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x20,0x06,0x03,0x55, -0x1D,0x25,0x04,0x19,0x30,0x17,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A, -0x03,0x03,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,0x30,0x3E,0x06, -0x03,0x55,0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00, -0x30,0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D, -0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63, -0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x30,0x6D,0x06, -0x03,0x55,0x1D,0x1F,0x04,0x66,0x30,0x64,0x30,0x31,0xA0,0x2F,0xA0,0x2D,0x86,0x2B, -0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64, -0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x55,0x54,0x4E,0x2D,0x44,0x41,0x54,0x41, -0x43,0x6F,0x72,0x70,0x53,0x47,0x43,0x2E,0x63,0x72,0x6C,0x30,0x2F,0xA0,0x2D,0xA0, -0x2B,0x86,0x29,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F, -0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x55,0x54,0x4E,0x2D,0x44,0x41,0x54, -0x41,0x43,0x6F,0x72,0x70,0x53,0x47,0x43,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09, -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00, -0x63,0xCD,0x05,0x7E,0x6F,0x81,0x18,0xF9,0x50,0x25,0x8E,0x91,0x75,0x1B,0x1F,0xF7, -0x3E,0x02,0x54,0x5B,0xAF,0xD2,0xA3,0x15,0xFD,0xD6,0x1D,0x61,0x73,0x7A,0x9C,0x57, -0xFA,0xCB,0xB7,0xF9,0xE8,0x32,0xA2,0x02,0x5D,0x36,0xFE,0x34,0x1F,0x6C,0x8A,0xB3, -0x72,0x43,0x26,0x36,0x8F,0x4D,0x14,0x5E,0x34,0x8A,0xBB,0xFC,0x6B,0x69,0xC4,0x46, -0x76,0x07,0x04,0x75,0xA4,0xF2,0xA5,0xF8,0x91,0x46,0x2D,0xD5,0x28,0x71,0xE3,0xCC, -0xA6,0x2C,0x99,0x2F,0xD5,0xFD,0xA3,0x45,0xD8,0x1A,0x9A,0x04,0xFB,0x1D,0x90,0xEE, -0x57,0x5E,0x08,0x73,0xC0,0x7A,0x02,0x36,0x11,0xEA,0x06,0x44,0x1E,0x39,0xA1,0x2A, -0x3F,0x22,0x5C,0x91,0xF4,0x22,0x55,0xAF,0x9A,0x0B,0x07,0x56,0x2A,0x59,0x0B,0x71, -0x5D,0x43,0x16,0xF4,0xE6,0x4F,0xD5,0x50,0xB0,0xCF,0xAD,0xA0,0xF8,0xE2,0x0B,0x00, -0x3C,0x83,0xA9,0x4E,0x50,0x37,0xD9,0x9C,0x65,0x3E,0x8C,0xC5,0x3A,0xA9,0x51,0xF5, -0xEB,0x7B,0x56,0xCD,0xF9,0xD5,0xBC,0xE4,0x6B,0x29,0xAC,0x3E,0x09,0x8E,0xB8,0x8D, -0x76,0x24,0x11,0xA1,0x80,0x4A,0xF2,0xD9,0xEC,0x83,0xD0,0x91,0x03,0x2C,0x6B,0x2B, -0x11,0xD5,0xD0,0x90,0x81,0xBB,0xE6,0x17,0xBD,0xD0,0xCD,0x85,0x73,0x2D,0x8D,0xDE, -0x69,0x27,0xE7,0x7E,0xAF,0x39,0x5C,0x0F,0xF2,0xC5,0x7C,0x3D,0xFB,0xE4,0xB0,0xF7, -0x81,0x1F,0x30,0x54,0x68,0x20,0x9C,0x8C,0xC5,0x2A,0x5A,0x39,0x17,0xCD,0x30,0x68, -0x5D,0x45,0xD8,0xA7,0xB8,0x4B,0xFD,0xDC,0x2D,0x2D,0x04,0x01,0x8D,0x5D,0x78,0x28, -}; - -/* This is the cert we get when we get the url in the AIA extension of the ovh leaf. */ -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO EV SGC CA */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO Certification Authority */ -static unsigned char comodo_aia_certificate[1178]={ -0x30,0x82,0x04,0x96,0x30,0x82,0x03,0x7E,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x13, -0x62,0xE8,0xEB,0x54,0x1A,0x10,0x8C,0xB8,0xA8,0x0E,0xE5,0x9F,0xB1,0xD4,0x51,0x30, -0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, -0x81,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B, -0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72, -0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06, -0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30, -0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43, -0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x27,0x30,0x25,0x06,0x03,0x55, -0x04,0x03,0x13,0x1E,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x30,0x31,0x30,0x30,0x30,0x30, -0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, -0x39,0x5A,0x30,0x73,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47, -0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61, -0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10, -0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64, -0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44, -0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x19,0x30,0x17, -0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x45,0x56, -0x20,0x53,0x47,0x43,0x20,0x43,0x41,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,0xE8,0xCE,0xAA,0xA9,0x25,0xAF,0x2E,0x8E, -0xD1,0x79,0x95,0x5E,0xA4,0x88,0x24,0x4F,0xFD,0xB3,0x5C,0xAE,0x2A,0x9E,0x4A,0x7B, -0x40,0xE0,0xCC,0x50,0xE9,0x81,0x58,0x15,0xD2,0x87,0xF7,0xAD,0x85,0x7A,0x69,0x52, -0xA0,0x95,0x6E,0x8F,0x67,0x09,0x8E,0xF1,0xF3,0x5C,0x17,0xE3,0x49,0x42,0xC8,0x12, -0x67,0xA6,0x05,0xF8,0x37,0xA0,0x0F,0x16,0x61,0x0F,0x8F,0x31,0x52,0xC6,0xE1,0x87, -0xE1,0x4F,0xB9,0xDB,0xC9,0xFE,0x69,0x1B,0xD4,0xC9,0xF7,0x2D,0xAC,0x48,0xD7,0x73, -0x4A,0x04,0x95,0xE3,0xA1,0x37,0x87,0x52,0x5A,0x88,0xB3,0xD6,0x01,0x2C,0xF1,0x03, -0x70,0x2C,0x26,0x70,0x2B,0x47,0x3B,0x0A,0xAE,0x31,0x7A,0xD7,0xE5,0x14,0x4E,0xAC, -0x2F,0x30,0xE1,0x7C,0x6D,0x36,0xDA,0xA0,0xF5,0x83,0x62,0x5D,0x88,0x26,0x0D,0x05, -0x45,0x5E,0xCE,0xF7,0x8B,0xEB,0x95,0xB4,0xE0,0xEB,0x10,0x7A,0xD4,0xB9,0x59,0x75, -0x46,0x52,0xDD,0x86,0x74,0x84,0xCB,0x5F,0xD3,0x1C,0x41,0xEA,0xF0,0x9A,0xDA,0x91, -0x64,0x84,0xDF,0xDE,0x9F,0xF2,0xDD,0xD0,0xFA,0xA6,0x68,0x96,0xB7,0x3E,0x97,0x2D, -0x7F,0xB1,0xFB,0x8C,0x6C,0xA7,0xFE,0x72,0x82,0xD0,0xE3,0x8A,0xD3,0xBB,0xE3,0xCE, -0x01,0xB7,0x9D,0x67,0xE9,0xA9,0x13,0x9A,0x3B,0x21,0xED,0xF7,0x73,0x13,0xE3,0x33, -0x5D,0x7A,0x01,0xA9,0xCA,0x49,0xD0,0x4E,0x63,0x87,0x57,0x81,0x3A,0x17,0x54,0x30, -0xF6,0x02,0x5E,0x94,0xB6,0x60,0xD2,0x29,0xF9,0x4E,0xE7,0x29,0xA0,0xA0,0x9D,0x2A, -0x5B,0xEB,0x3F,0x89,0x2E,0x45,0xA2,0xFD,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01, -0x15,0x30,0x82,0x01,0x11,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, -0x80,0x14,0x0B,0x58,0xE5,0x8B,0xC6,0x4C,0x15,0x37,0xA4,0x40,0xA9,0x30,0xA9,0x21, -0xBE,0x47,0x36,0x5A,0x56,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, -0x14,0x7F,0xF6,0x4C,0x36,0x28,0x14,0xAE,0xCD,0x1E,0x37,0xAF,0xDE,0x5A,0xF2,0x5B, -0xC3,0xA0,0xAC,0x2B,0xFE,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04, -0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, -0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x20,0x06,0x03,0x55,0x1D,0x25, -0x04,0x19,0x30,0x17,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03, -0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,0x30,0x3E,0x06,0x03,0x55, -0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x2B, -0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,0x68,0x74, -0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,0x6F,0x6D, -0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x30,0x49,0x06,0x03,0x55, -0x1D,0x1F,0x04,0x42,0x30,0x40,0x30,0x3E,0xA0,0x3C,0xA0,0x3A,0x86,0x38,0x68,0x74, -0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63, -0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, -0x74,0x79,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x8C,0xD9,0xD9,0x52,0x33,0xEE, -0x07,0xF6,0xE1,0xEC,0xAB,0x15,0xE0,0x9F,0x15,0xD8,0x99,0x25,0xDB,0x19,0x95,0x25, -0x9B,0x43,0xBE,0x59,0x2B,0x81,0x29,0xC8,0xF8,0xF1,0x5F,0x8E,0x49,0x02,0x36,0x46, -0x1C,0xEB,0xF2,0xA1,0xFE,0xD1,0x0A,0x45,0xBA,0xD0,0xDB,0x50,0x44,0x0C,0x50,0xA3, -0x3C,0x6E,0x5F,0x84,0xD4,0x4F,0x1A,0xA8,0x69,0x8F,0x24,0x66,0x01,0xD2,0x0B,0xB4, -0x08,0x19,0xBA,0xBD,0x34,0x09,0x90,0x09,0x62,0x71,0xAD,0x39,0x8E,0xB8,0x78,0x79, -0xB1,0x24,0x78,0xB4,0xCD,0xA7,0x49,0xF9,0x6D,0x78,0x7F,0x70,0x87,0x82,0x91,0x35, -0xAC,0xB1,0x00,0x86,0x21,0x51,0xD2,0xCD,0x46,0xCB,0x3A,0x82,0xC0,0x48,0x1A,0xD3, -0x15,0x26,0xDB,0xF1,0x0F,0x82,0x71,0x66,0xE2,0x8B,0x77,0x54,0xA3,0x76,0x2F,0xD7, -0x6D,0xF8,0x0D,0x0E,0xCE,0x3A,0x4E,0x65,0x57,0x3F,0x1C,0x77,0x50,0xCA,0xBB,0x7A, -0x53,0xF7,0xFB,0x5F,0x3D,0x75,0x56,0xAA,0xD3,0xE3,0x1F,0x12,0xB5,0x1D,0xBF,0xC3, -0xDC,0xE1,0xF9,0x39,0x67,0x81,0xF1,0x33,0x9C,0xC8,0x1E,0xC5,0xE6,0xEE,0x2B,0xB9, -0xD9,0x58,0xC8,0xC7,0x2E,0xDF,0x48,0xD1,0xC9,0xE4,0xB3,0x1A,0x08,0x5F,0x9A,0x18, -0x6D,0x61,0xD3,0xB0,0xAD,0x27,0x5E,0x08,0x35,0x34,0x25,0xA1,0x9F,0x42,0xC8,0x75, -0x98,0xD3,0x02,0x64,0x55,0x94,0xE3,0xAF,0xD1,0xE7,0x4A,0xB9,0xE4,0xD9,0x06,0x6E, -0x71,0x28,0xF8,0xDD,0xAC,0xE5,0x45,0xDF,0xD8,0xE7,0x28,0x05,0xA1,0x68,0xCE,0xC1, -0x25,0x5B,0x85,0xFA,0x46,0x9D,0xFE,0xDB,0x64,0xF0, -}; - -static unsigned char revoked_ist_certificate[1515]={ -0x30,0x82,0x05,0xE7,0x30,0x82,0x04,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x7F, -0x00,0xCE,0x8A,0xD6,0x3F,0x5B,0x34,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x62,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04, -0x03,0x13,0x13,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x53,0x54,0x20,0x43,0x41,0x20, -0x32,0x20,0x2D,0x20,0x47,0x31,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0B,0x13, -0x17,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,0x13,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,0x34, -0x31,0x31,0x32,0x38,0x31,0x35,0x30,0x36,0x31,0x34,0x5A,0x17,0x0D,0x31,0x36,0x31, -0x32,0x32,0x37,0x31,0x35,0x30,0x36,0x31,0x34,0x5A,0x30,0x81,0xAB,0x31,0x4B,0x30, -0x49,0x06,0x03,0x55,0x04,0x03,0x0C,0x42,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E, -0x67,0x65,0x6F,0x74,0x72,0x75,0x73,0x74,0x2D,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2D, -0x63,0x61,0x2E,0x74,0x65,0x73,0x74,0x2D,0x70,0x61,0x67,0x65,0x73,0x2E,0x63,0x65, -0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x6D,0x61,0x6E,0x61,0x67,0x65,0x72, -0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x31,0x25,0x30,0x23,0x06,0x03, -0x55,0x04,0x0B,0x0C,0x1C,0x6D,0x61,0x6E,0x61,0x67,0x65,0x6D,0x65,0x6E,0x74,0x3A, -0x69,0x64,0x6D,0x73,0x2E,0x67,0x72,0x6F,0x75,0x70,0x2E,0x31,0x37,0x36,0x33,0x39, -0x39,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C, -0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C, -0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,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,0xA9,0xD7,0xE0,0x65,0x48,0x36,0x8A, -0x4B,0x6C,0xBB,0x16,0xAF,0xFD,0x09,0xA5,0x9C,0x30,0xDA,0xC5,0x9B,0x3D,0xD6,0xB4, -0x8E,0x6B,0xC2,0xF4,0xBF,0x30,0xA7,0xCC,0xF7,0xA1,0x23,0x58,0xA0,0x16,0xE8,0x31, -0x5F,0xE7,0xD2,0x21,0x3D,0x24,0x3D,0xF4,0x1E,0x82,0x46,0x45,0xA0,0xB8,0x2E,0xD7, -0xB6,0x86,0xD3,0x2A,0xBC,0x93,0x74,0x44,0xAB,0x1C,0x9F,0x86,0xBF,0x19,0xCE,0xA4, -0xD0,0xC9,0xB9,0x65,0x84,0x89,0x87,0xDE,0x77,0xDC,0xAE,0x85,0xA9,0xDE,0x5A,0xCF, -0xAF,0x46,0x80,0x45,0x72,0x68,0x87,0x55,0x5B,0x4D,0x49,0xE2,0x7B,0x25,0x31,0x22, -0x00,0x87,0xAB,0x72,0xEB,0x9A,0x2D,0x81,0x35,0x0E,0x76,0x82,0x5C,0x99,0x10,0xFB, -0xD6,0x3F,0x29,0xE8,0xFD,0x2E,0xAD,0xF6,0xF8,0xCF,0xC1,0x99,0x5F,0xDA,0xC1,0xB3, -0x90,0x70,0xA5,0x4B,0x23,0x4D,0xD6,0x1D,0xC9,0x73,0x27,0xD1,0xAE,0x38,0xA3,0xD0, -0x71,0x92,0xFF,0x89,0xA8,0xE5,0x51,0x3E,0x2F,0xB6,0xB4,0x02,0x20,0x54,0x62,0xA0, -0x69,0x6D,0xB6,0x10,0x8D,0xB7,0x13,0x2A,0x94,0x4E,0xED,0x73,0x8C,0x78,0x39,0xF6, -0x04,0xC0,0xF8,0x7A,0x75,0x2D,0x1E,0x82,0x7E,0x55,0x7B,0xE7,0xA7,0xFA,0x6E,0xB1, -0x53,0x81,0x75,0xB6,0x19,0xD8,0xD2,0xD3,0x8E,0x30,0x95,0x0D,0xD8,0xC9,0xBA,0x3F, -0x70,0x23,0xC3,0x7B,0xE2,0x6E,0xA9,0xA8,0x91,0x69,0x89,0x8D,0xEA,0x64,0x5D,0x8E, -0x49,0x43,0x30,0x99,0xBC,0x54,0x97,0xAC,0xEB,0x98,0x09,0x8C,0xE9,0xA7,0xE8,0xDC, -0xFC,0xE4,0xBE,0x20,0xDA,0xA1,0x88,0xB6,0x99,0x02,0x03,0x01,0x00,0x01,0xA3,0x82, -0x02,0x55,0x30,0x82,0x02,0x51,0x30,0x48,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, -0x01,0x01,0x04,0x3C,0x30,0x3A,0x30,0x38,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, -0x30,0x01,0x86,0x2C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E, -0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x6F,0x63,0x73,0x70,0x30,0x34, -0x2D,0x61,0x70,0x70,0x6C,0x65,0x69,0x73,0x74,0x63,0x61,0x32,0x67,0x31,0x30,0x31, -0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x75,0x81,0x7F,0xDF,0xDE, -0x90,0xE2,0xFB,0x67,0xA8,0x04,0xC9,0x82,0xE1,0x2A,0x13,0x08,0x3D,0xCE,0x8E,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,0xD8,0x7A,0x94,0x44,0x7C,0x90, -0x70,0x90,0x16,0x9E,0xDD,0x17,0x9C,0x01,0x44,0x03,0x86,0xD6,0x2A,0x29,0x30,0x81, -0xFF,0x06,0x03,0x55,0x1D,0x20,0x04,0x81,0xF7,0x30,0x81,0xF4,0x30,0x81,0xF1,0x06, -0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x0B,0x04,0x30,0x81,0xE2,0x30,0x81, -0xA4,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x81,0x97,0x0C,0x81, -0x94,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,0x61,0x73,0x73,0x75,0x6D, -0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,0x74,0x61,0x6E,0x63,0x65,0x20,0x6F,0x66, -0x20,0x61,0x6E,0x79,0x20,0x61,0x70,0x70,0x6C,0x69,0x63,0x61,0x62,0x6C,0x65,0x20, -0x74,0x65,0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,0x6E,0x64,0x69,0x74, -0x69,0x6F,0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x6E,0x64,0x2F, -0x6F,0x72,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E, -0x20,0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x73,0x74,0x61,0x74,0x65,0x6D, -0x65,0x6E,0x74,0x73,0x2E,0x30,0x39,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02, -0x01,0x16,0x2D,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,0x72,0x70,0x61, -0x30,0x37,0x06,0x03,0x55,0x1D,0x1F,0x04,0x30,0x30,0x2E,0x30,0x2C,0xA0,0x2A,0xA0, -0x28,0x86,0x26,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x61,0x70, -0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70,0x6C,0x65,0x69,0x73,0x74, -0x63,0x61,0x32,0x67,0x31,0x2E,0x63,0x72,0x6C,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F, -0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55,0x1D,0x25, -0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x06,0x08, -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x4D,0x06,0x03,0x55,0x1D,0x11,0x04, -0x46,0x30,0x44,0x82,0x42,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,0x67,0x65,0x6F, -0x74,0x72,0x75,0x73,0x74,0x2D,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2D,0x63,0x61,0x2E, -0x74,0x65,0x73,0x74,0x2D,0x70,0x61,0x67,0x65,0x73,0x2E,0x63,0x65,0x72,0x74,0x69, -0x66,0x69,0x63,0x61,0x74,0x65,0x6D,0x61,0x6E,0x61,0x67,0x65,0x72,0x2E,0x61,0x70, -0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, -0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xC0,0x5B,0xA6,0xAF,0x2C, -0x27,0xBA,0x49,0x8D,0x41,0xF6,0xC4,0x02,0xEE,0x9D,0xB1,0x48,0xC3,0x34,0x7B,0xF2, -0xD2,0x82,0x49,0xA5,0x13,0x5A,0x66,0xAD,0xC9,0x73,0xBF,0x6B,0xC9,0x30,0x86,0xBA, -0x7A,0xD2,0x9D,0x61,0xFE,0x04,0x07,0x15,0x66,0xC2,0x25,0xF7,0x6C,0x88,0xB1,0x0E, -0x22,0x11,0xF9,0x26,0xA7,0x4E,0x88,0x96,0x20,0x99,0xA6,0x51,0xEE,0x02,0x96,0xC7, -0xA4,0xCA,0xD4,0xAB,0xFC,0x5F,0x96,0x16,0x0D,0x8D,0xA0,0xA1,0x17,0x6E,0x77,0x92, -0xC9,0x64,0xD9,0xA2,0x5A,0x00,0x08,0xA6,0x55,0x73,0x2C,0xDD,0xD3,0x0C,0xA5,0xCA, -0x68,0x48,0xAE,0xCE,0x5F,0xF2,0x56,0x4A,0x66,0x57,0xB2,0x2D,0xB5,0xC6,0xFF,0x50, -0xD8,0x36,0x9C,0x31,0x31,0xE8,0xB2,0x07,0xE2,0x7B,0xC0,0xCE,0x72,0xA4,0x60,0x91, -0xBB,0x84,0xA7,0xA8,0xC0,0x1D,0x42,0xE8,0x1D,0xF5,0xD9,0x6B,0x85,0x67,0x23,0x20, -0xA6,0xF8,0x0F,0xBA,0x83,0x63,0x49,0xE2,0x79,0x23,0x90,0xFF,0x6B,0xEF,0xFA,0xB4, -0x04,0xA8,0x99,0x1E,0x5D,0x5A,0xCD,0x8C,0xBC,0x8E,0x30,0x41,0x7E,0xE7,0x4E,0xDB, -0x6F,0x4E,0xB7,0xBA,0xE0,0x5B,0x31,0xC4,0xD2,0x2D,0xD3,0x5D,0x82,0x95,0x44,0x7D, -0x11,0x60,0x75,0xCE,0x6D,0x12,0xDA,0x89,0x71,0x23,0x80,0x75,0xC0,0x13,0x67,0x27, -0xE8,0xE8,0xCA,0xE0,0xE3,0xFC,0x72,0x23,0x98,0xFA,0xF0,0x96,0x05,0x23,0xC9,0x03, -0xC8,0x29,0xA4,0xB1,0xE5,0x07,0xE6,0xE8,0x09,0x26,0xD1,0x8C,0xAF,0xE0,0x53,0xBB, -0xB4,0x1E,0x4D,0x5E,0xEA,0x9A,0x1E,0xE9,0x42,0x87,0x9F, -}; - -static unsigned char ist_intermediate_certificate[1092]={ -0x30,0x82,0x04,0x40,0x30,0x82,0x03,0x28,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x02, -0x3A,0x74,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, -0x00,0x30,0x42,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, -0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72, -0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04, -0x03,0x13,0x12,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62, -0x61,0x6C,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x34,0x30,0x36,0x31,0x36,0x31, -0x35,0x34,0x32,0x30,0x32,0x5A,0x17,0x0D,0x32,0x32,0x30,0x35,0x32,0x30,0x31,0x35, -0x34,0x32,0x30,0x32,0x5A,0x30,0x62,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03, -0x13,0x13,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x53,0x54,0x20,0x43,0x41,0x20,0x32, -0x20,0x2D,0x20,0x47,0x31,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,0x17, -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, -0x13,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,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,0xD0,0x93,0xA1,0x1D,0x47,0x43, -0x20,0x16,0xB2,0x0B,0x6B,0xEB,0xC3,0xD5,0xB4,0xE8,0xC7,0x98,0xCD,0xF3,0xDE,0xBF, -0xE8,0x4D,0xE9,0xE3,0x36,0x80,0x07,0xFC,0x45,0x1B,0x6A,0x7C,0x45,0x86,0xAE,0x56, -0xD3,0xA4,0x09,0x7F,0x61,0x0D,0x6B,0x5D,0x7E,0x52,0x6B,0x7D,0xB4,0xC8,0x39,0xC4, -0xF4,0x67,0x3A,0xF7,0x83,0xCE,0x19,0x6F,0x86,0x2F,0x7E,0x45,0x7E,0x47,0x1C,0x67, -0x52,0xCA,0x95,0x05,0x5D,0xE2,0x36,0x51,0x85,0xC0,0xD4,0x67,0x80,0x35,0x6F,0x15, -0xDD,0x3E,0xFD,0x1D,0xD2,0xFD,0x8F,0x34,0x50,0xD8,0xEC,0x76,0x2A,0xBE,0xE3,0xD3, -0xDA,0xE4,0xFD,0xC8,0xEB,0x28,0x02,0x96,0x11,0x97,0x17,0x61,0x1C,0xE9,0xC4,0x59, -0x3B,0x42,0xDC,0x32,0xD1,0x09,0x1D,0xDA,0xA6,0xD1,0x43,0x86,0xFF,0x5E,0xB2,0xBC, -0x8C,0xCF,0x66,0xDB,0x01,0x8B,0x02,0xAE,0x94,0x48,0xF3,0x38,0x8F,0xFD,0xEA,0x32, -0xA8,0x08,0xEC,0x86,0x97,0x51,0x94,0x24,0x3E,0x49,0x49,0x96,0x53,0xE8,0x79,0xA1, -0x40,0x81,0xE9,0x05,0xBB,0x93,0x95,0x51,0xFC,0xE3,0xFD,0x7C,0x11,0x4B,0xF7,0x9E, -0x08,0xB3,0x15,0x49,0x15,0x07,0xF9,0xD1,0x37,0xA0,0x9B,0x4B,0x32,0xF6,0xB5,0xC4, -0xDC,0x6A,0xD1,0xFC,0x0A,0xED,0xF6,0xE0,0xC5,0x29,0xA0,0xA8,0x8B,0x71,0xFE,0x0D, -0x92,0xBC,0xFE,0x54,0x70,0x18,0x0A,0x6D,0xC7,0xED,0x0C,0xFB,0xC9,0x2D,0x06,0xC3, -0x8C,0x85,0xFC,0xCB,0x86,0x5C,0xD6,0x36,0x8E,0x12,0x8B,0x09,0x7F,0xFB,0x19,0x1A, -0x38,0xD5,0xF0,0x94,0x30,0x7A,0x0F,0xA6,0x8C,0xF3,0x02,0x03,0x01,0x00,0x01,0xA3, -0x82,0x01,0x1D,0x30,0x82,0x01,0x19,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, -0x30,0x16,0x80,0x14,0xC0,0x7A,0x98,0x68,0x8D,0x89,0xFB,0xAB,0x05,0x64,0x0C,0x11, -0x7D,0xAA,0x7D,0x65,0xB8,0xCA,0xCC,0x4E,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, -0x16,0x04,0x14,0xD8,0x7A,0x94,0x44,0x7C,0x90,0x70,0x90,0x16,0x9E,0xDD,0x17,0x9C, -0x01,0x44,0x03,0x86,0xD6,0x2A,0x29,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01, -0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x0E,0x06,0x03,0x55, -0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x35,0x06,0x03,0x55, -0x1D,0x1F,0x04,0x2E,0x30,0x2C,0x30,0x2A,0xA0,0x28,0xA0,0x26,0x86,0x24,0x68,0x74, -0x74,0x70,0x3A,0x2F,0x2F,0x67,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D, -0x2F,0x63,0x72,0x6C,0x73,0x2F,0x67,0x74,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2E,0x63, -0x72,0x6C,0x30,0x2E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x22, -0x30,0x20,0x30,0x1E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x12, -0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x67,0x2E,0x73,0x79,0x6D,0x63,0x64,0x2E,0x63, -0x6F,0x6D,0x30,0x4C,0x06,0x03,0x55,0x1D,0x20,0x04,0x45,0x30,0x43,0x30,0x41,0x06, -0x0A,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x36,0x30,0x33,0x30,0x31,0x06, -0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x25,0x68,0x74,0x74,0x70,0x3A, -0x2F,0x2F,0x77,0x77,0x77,0x2E,0x67,0x65,0x6F,0x74,0x72,0x75,0x73,0x74,0x2E,0x63, -0x6F,0x6D,0x2F,0x72,0x65,0x73,0x6F,0x75,0x72,0x63,0x65,0x73,0x2F,0x63,0x70,0x73, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03, -0x82,0x01,0x01,0x00,0x16,0x47,0x73,0x6F,0x85,0xA2,0x62,0xE1,0xE7,0x2A,0x76,0xBB, -0x89,0x95,0x42,0x26,0x97,0xBC,0x4A,0xAC,0xAC,0x70,0x53,0x3A,0x3F,0x31,0x83,0x3D, -0x3C,0x1C,0xAB,0x9A,0xE2,0xB1,0x5D,0x1C,0x76,0x1A,0xA0,0x3C,0x0C,0x72,0x57,0xBE, -0xD3,0x9E,0x50,0xE0,0xC8,0x99,0xD6,0x58,0xD7,0x02,0xEA,0xCE,0x0D,0x29,0x54,0x7C, -0xCD,0xF5,0xC2,0xC6,0x90,0x29,0x55,0xA3,0x6F,0x14,0xA8,0x0B,0x42,0x0D,0x3A,0x98, -0x6D,0x06,0x78,0x9E,0xF0,0x6A,0xA3,0x1D,0x02,0x0A,0xA2,0x28,0xA4,0x8D,0xC2,0x81, -0x46,0x3E,0x6D,0x67,0xDA,0xDE,0x3F,0xFE,0x85,0x0E,0x42,0x2A,0x12,0xDE,0xB5,0xB7, -0xFB,0xB8,0x1B,0xA7,0x96,0xEC,0x77,0x9F,0xEC,0xD4,0x53,0x95,0x7A,0xFF,0x07,0xF4, -0xF2,0x0A,0x14,0xC0,0x51,0x52,0xB1,0xD6,0x8E,0x50,0x0B,0x1A,0x99,0x5C,0xBC,0x0B, -0xC9,0xBD,0xED,0xED,0xF8,0x5E,0xC1,0x56,0xDB,0x4D,0x7E,0x23,0xA4,0x11,0xA1,0x2C, -0xD4,0x1B,0x05,0x9A,0xE4,0x1B,0x52,0xF6,0x7C,0x38,0x99,0x05,0x4B,0xBA,0x72,0x8D, -0x42,0x89,0x60,0x04,0x66,0x2A,0xF4,0xFD,0x68,0xD7,0x6B,0xF7,0x99,0x41,0x28,0xD6, -0x6C,0x24,0xAB,0xE6,0x25,0x53,0x2E,0xC8,0x82,0x99,0xE2,0xA2,0x8F,0x23,0xBE,0x30, -0x83,0xB1,0x27,0x8B,0xFA,0x68,0x7F,0x01,0x49,0xE8,0xC6,0x98,0x6B,0x10,0x2E,0x98, -0x5E,0x8A,0xD7,0xCA,0x4B,0xB1,0xC7,0xC9,0x58,0x9A,0xD0,0x36,0xDB,0x96,0x95,0xEC, -0xB6,0x81,0xE4,0xF2,0xCD,0x6F,0x1B,0x79,0x87,0x4C,0x10,0x3C,0x89,0xE4,0x4D,0xFA, -0x54,0xDC,0xAA,0xA6, -}; - -unsigned char smime_leaf_certificate[1338]={ - 0x30,0x82,0x05,0x36,0x30,0x82,0x04,0x1E,0xA0,0x03,0x02,0x01,0x02,0x02,0x0D,0x14, - 0x00,0x01,0x00,0x02,0x9C,0xE1,0xB9,0xE0,0x7C,0xD1,0x7B,0xEC,0x30,0x0D,0x06,0x09, - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x7C,0x31,0x0B,0x30, - 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03, - 0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E, - 0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04, - 0x0B,0x13,0x1C,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65, - 0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,0x43,0x41,0x31, - 0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75, - 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31, - 0x20,0x4C,0x31,0x20,0x43,0x41,0x20,0x49,0x58,0x30,0x1E,0x17,0x0D,0x31,0x30,0x31, - 0x31,0x31,0x32,0x30,0x36,0x33,0x36,0x34,0x35,0x5A,0x17,0x0D,0x31,0x31,0x31,0x31, - 0x31,0x33,0x30,0x36,0x33,0x36,0x34,0x35,0x5A,0x30,0x24,0x31,0x0B,0x30,0x09,0x06, - 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04, - 0x03,0x13,0x0C,0x51,0x75,0x69,0x6E,0x6E,0x20,0x54,0x61,0x79,0x6C,0x6F,0x72,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, - 0xC1,0x11,0xAA,0x04,0xCF,0x04,0xA0,0x07,0xF3,0x43,0x2A,0xB2,0x27,0x1A,0x13,0x35, - 0x97,0x9A,0xBA,0x34,0xE5,0x84,0xF3,0xD5,0xE5,0xD9,0xAB,0x23,0x8D,0xB4,0x7E,0x68, - 0x5C,0xF2,0x9A,0xF1,0x08,0x9B,0x04,0x34,0xC1,0x09,0x14,0x68,0xD8,0x9C,0xC1,0x6C, - 0x27,0xF5,0x92,0x54,0xAF,0x66,0x65,0xF1,0x50,0xAA,0x7E,0xE3,0xFC,0xC1,0xB0,0x3E, - 0xEF,0xAA,0x86,0x58,0x4F,0xE7,0x86,0x0A,0x74,0xA6,0x97,0xBD,0x7D,0xF6,0xCE,0xA6, - 0x8B,0xF7,0xC0,0x90,0x6E,0x50,0x69,0x36,0x65,0x82,0x0F,0x65,0xA7,0x2C,0x16,0xFA, - 0x6C,0xCA,0x54,0x45,0x7C,0x06,0x20,0x72,0xF0,0x00,0x7B,0xD7,0x17,0xCD,0x94,0x64, - 0x6A,0xB7,0x28,0xF3,0x62,0xB1,0x29,0xAE,0x0C,0x8A,0x2F,0x3C,0x06,0x89,0xE8,0x81, - 0x77,0xAD,0x1F,0x65,0xED,0x6F,0x51,0x64,0x65,0x68,0x76,0xD8,0xEE,0xEC,0xA6,0x28, - 0xA9,0x1C,0x4F,0x98,0x4A,0x6D,0xD0,0xC8,0x5C,0x59,0x17,0x9B,0xF8,0x6D,0xF5,0x93, - 0xD3,0x4C,0x2A,0x37,0x80,0x65,0xB4,0x34,0xBA,0x64,0x2F,0xA1,0x8E,0x1C,0x6A,0x88, - 0x7C,0xA3,0xDB,0xDD,0x00,0x9B,0x78,0x51,0x7B,0xA6,0x8D,0xDD,0x43,0x9B,0xB2,0x2E, - 0x4B,0x1E,0xB3,0x34,0x37,0x3F,0x63,0x08,0x8C,0xC8,0xCF,0xD0,0xB0,0x8C,0xBF,0x8F, - 0xA7,0x49,0xBD,0x48,0x1D,0xB5,0x1E,0x6A,0x42,0x48,0x16,0x9A,0x7C,0xD3,0x55,0x6B, - 0xFF,0xD6,0xBA,0x70,0xF3,0x5F,0x1F,0x57,0x16,0xE0,0x1C,0xF1,0x73,0x22,0xD9,0x33, - 0xA7,0x20,0xE8,0xED,0x52,0x2A,0xE9,0x6F,0xCF,0xFB,0x76,0xAC,0xB8,0x5D,0x9B,0xAB, - 0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0x0D,0x30,0x82,0x02,0x09,0x30,0x81,0xA5, - 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x81,0x98,0x30,0x81,0x95, - 0x30,0x51,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x45,0x68,0x74, - 0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65, - 0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x65,0x72,0x74,0x73,0x65,0x72,0x76, - 0x69,0x63,0x65,0x73,0x2F,0x63,0x61,0x63,0x65,0x72,0x74,0x73,0x2F,0x74,0x63,0x5F, - 0x63,0x6C,0x61,0x73,0x73,0x31,0x5F,0x4C,0x31,0x5F,0x43,0x41,0x5F,0x49,0x58,0x2E, - 0x63,0x72,0x74,0x30,0x40,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86, - 0x34,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x69,0x78,0x2E, - 0x74,0x63,0x63,0x6C,0x61,0x73,0x73,0x31,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65, - 0x72,0x73,0x61,0x6C,0x2D,0x69,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74, - 0x65,0x72,0x2E,0x64,0x65,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, - 0x80,0x14,0xE9,0xB8,0x28,0x1D,0x46,0xCF,0xFC,0xCD,0xF8,0x4E,0x9B,0xC5,0xEE,0x4B, - 0x60,0xEB,0xD8,0x3B,0x3F,0xD1,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF, - 0x04,0x02,0x30,0x00,0x30,0x4A,0x06,0x03,0x55,0x1D,0x20,0x04,0x43,0x30,0x41,0x30, - 0x3F,0x06,0x09,0x2A,0x82,0x14,0x00,0x2C,0x01,0x01,0x01,0x01,0x30,0x32,0x30,0x30, - 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x24,0x68,0x74,0x74,0x70, - 0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74, - 0x65,0x72,0x2E,0x64,0x65,0x2F,0x67,0x75,0x69,0x64,0x65,0x6C,0x69,0x6E,0x65,0x73, - 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x04,0xF0, - 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xF8,0x4D,0x7F,0xDE,0xFA, - 0x21,0x2E,0xAF,0x96,0xBB,0xAA,0x9B,0x22,0x56,0x80,0xF0,0x8E,0xD4,0x6A,0x52,0x30, - 0x62,0x06,0x03,0x55,0x1D,0x1F,0x04,0x5B,0x30,0x59,0x30,0x57,0xA0,0x55,0xA0,0x53, - 0x86,0x51,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x69,0x78,0x2E, - 0x74,0x63,0x63,0x6C,0x61,0x73,0x73,0x31,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65, - 0x72,0x73,0x61,0x6C,0x2D,0x69,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74, - 0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C,0x2F,0x76,0x32,0x2F,0x74,0x63,0x5F, - 0x43,0x6C,0x61,0x73,0x73,0x31,0x5F,0x4C,0x31,0x5F,0x43,0x41,0x5F,0x49,0x58,0x2E, - 0x63,0x72,0x6C,0x30,0x33,0x06,0x03,0x55,0x1D,0x25,0x04,0x2C,0x30,0x2A,0x06,0x08, - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, - 0x03,0x04,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,0x06,0x0A,0x2B,0x06, - 0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,0x30,0x1C,0x06,0x03,0x55,0x1D,0x11,0x04, - 0x15,0x30,0x13,0x81,0x11,0x71,0x74,0x61,0x79,0x6C,0x6F,0x72,0x40,0x61,0x70,0x70, - 0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, - 0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x0D,0xCF,0x33,0xAB,0x3D,0xD3, - 0xD2,0x06,0x2C,0x20,0x3C,0xEC,0x0C,0xE4,0xA5,0x19,0x86,0xB3,0xA7,0xA9,0xA6,0xE9, - 0xDC,0xB4,0x35,0xBB,0x0D,0x67,0xD5,0xBD,0x5F,0x93,0xD9,0x2E,0xA0,0x05,0x2A,0xED, - 0xAE,0x41,0xD9,0xEE,0x30,0xA8,0x82,0x50,0xD0,0x4B,0x04,0x6B,0x37,0xAE,0xC0,0x10, - 0x89,0x05,0x68,0x82,0x91,0x2B,0x5B,0xE2,0x7D,0xA6,0x87,0xF7,0x26,0x96,0xBA,0x2A, - 0x52,0x03,0x97,0xF6,0x2E,0x0D,0x81,0x65,0x24,0x10,0xD5,0x8C,0xB3,0xCD,0x19,0x58, - 0xAF,0x3A,0x3D,0x2F,0x10,0x30,0x79,0x6A,0xD6,0x08,0x8F,0x8B,0x9D,0x1D,0xF8,0x19, - 0xE4,0x24,0x2B,0xE0,0x7F,0x73,0xE1,0x50,0x9C,0x53,0xE1,0x46,0xC7,0xA7,0xBD,0x71, - 0xCD,0xFF,0x39,0xA0,0x50,0xA5,0xA8,0xD9,0x50,0x39,0x6C,0x36,0x1C,0x13,0x89,0x8A, - 0x0D,0x9D,0x06,0x1B,0xAA,0x59,0x40,0xC1,0xAF,0xED,0x66,0x31,0xB8,0xA0,0x9F,0xCF, - 0xA6,0x8A,0x2E,0xC2,0x1A,0x4B,0xDB,0x62,0x15,0x6E,0x10,0x2F,0x82,0x3C,0xF8,0xA2, - 0x18,0x63,0xCC,0x67,0x13,0x42,0x07,0x43,0xDB,0x20,0x13,0xC7,0xAC,0xCE,0xCB,0xEA, - 0x7E,0x53,0xA6,0x01,0x81,0xB2,0x6E,0x92,0x2B,0x0C,0xF9,0x01,0x2C,0x11,0xC9,0x00, - 0x10,0x58,0x64,0x56,0x91,0xAC,0xAA,0xF6,0xE0,0x73,0xC7,0x59,0xEC,0xCE,0x51,0x7E, - 0xAD,0x9F,0x04,0xA4,0x38,0x74,0x65,0xD0,0x23,0xBD,0x6E,0xDF,0x64,0x79,0xE2,0xA3, - 0x37,0x19,0x2F,0x8C,0x41,0x8B,0x5F,0x6D,0x84,0x61,0x54,0xD1,0x26,0x18,0x70,0xAD, - 0xE5,0xF4,0xCD,0x59,0xED,0x9E,0xE0,0xC9,0x9F,0xD3, -}; - -unsigned char smime_CA_certificate[1500]={ - 0x30,0x82,0x05,0xD8,0x30,0x82,0x04,0xC0,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x06, - 0xE8,0x00,0x01,0x00,0x02,0x4A,0x96,0x2D,0x24,0x0C,0xFE,0xC5,0xC9,0x30,0x0D,0x06, - 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x79,0x31,0x0B, - 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06, - 0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, - 0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55, - 0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74, - 0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31, - 0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75, - 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73, - 0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x30,0x1E,0x17,0x0D,0x30,0x39,0x31,0x31,0x30, - 0x33,0x31,0x34,0x30,0x38,0x31,0x39,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31, - 0x32,0x31,0x35,0x39,0x35,0x39,0x5A,0x30,0x7C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, - 0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13, - 0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20, - 0x47,0x6D,0x62,0x48,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,0x54, - 0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C, - 0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,0x43,0x41,0x31,0x28,0x30,0x26,0x06, - 0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, - 0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20, - 0x43,0x41,0x20,0x49,0x58,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,0xBB,0xE6,0x90,0x6E,0xCF,0x62,0xE9,0xE9,0x0B,0xAA, - 0xB6,0x10,0xD5,0x47,0xE5,0x7C,0x5D,0x2B,0x27,0x71,0x9A,0x68,0xCD,0x55,0x6D,0xE4, - 0xA2,0xEF,0xE4,0xFE,0xF2,0x7A,0x63,0x11,0xC2,0x57,0x8A,0xC8,0x7D,0xCF,0x8E,0x66, - 0x1F,0x65,0x45,0x4B,0xEB,0x80,0x62,0x69,0xBD,0x46,0x8E,0x8B,0xC5,0x6E,0x5A,0x95, - 0x18,0x2A,0xDE,0xA7,0xF1,0x1F,0x75,0x1A,0x27,0xAB,0x6D,0x32,0x53,0xE3,0xFB,0x4D, - 0x58,0x62,0x2C,0xFF,0x19,0xE5,0xC7,0xA0,0x0D,0x9A,0x2D,0x21,0x88,0x59,0x84,0xCD, - 0x1D,0xF1,0xC3,0xC8,0x8A,0x3E,0xB0,0xE5,0xDE,0x08,0x24,0xCF,0xFC,0x40,0x2C,0xBA, - 0x41,0x23,0x94,0xBB,0x80,0x12,0x89,0x35,0x48,0xB6,0x86,0x04,0xE0,0x01,0x4F,0x8C, - 0xBA,0xA9,0x98,0xFC,0x1C,0x89,0xED,0x1F,0x8A,0xA1,0xC7,0x86,0x98,0x26,0x1E,0x72, - 0x65,0x6B,0xFE,0xCF,0x65,0xD9,0x0C,0x64,0x4B,0x1A,0x09,0xF5,0x43,0x11,0x60,0x66, - 0x26,0xE3,0x33,0x56,0x9A,0xC9,0x3D,0x3E,0x34,0x6A,0x78,0xC6,0xE5,0x50,0x4B,0xC8, - 0xCD,0x88,0xE4,0x39,0x6C,0x50,0x26,0x9E,0x40,0x2C,0xB6,0x3B,0x7C,0x37,0xB2,0xA7, - 0xF5,0xDD,0xDC,0xB3,0x51,0xCB,0xF4,0xDC,0x82,0x02,0xB8,0xD7,0x3A,0xDE,0xDA,0x30, - 0x5C,0x0D,0xF5,0x42,0xDD,0x13,0x69,0x53,0x54,0xE9,0x80,0x26,0x42,0x33,0x1E,0xA5, - 0xD7,0xCC,0x6E,0xCA,0x66,0x09,0x9F,0x86,0xF0,0x3D,0xBE,0xC6,0x8A,0x61,0x10,0xF3, - 0xD1,0xFF,0x5B,0xE4,0xB2,0xDB,0x2D,0xB2,0x65,0x0C,0xA9,0x7D,0x17,0xAC,0xBA,0x27, - 0x4D,0x42,0x5C,0xCE,0x09,0x4F,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0x59,0x30, - 0x82,0x02,0x55,0x30,0x81,0x9A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, - 0x04,0x81,0x8D,0x30,0x81,0x8A,0x30,0x52,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, - 0x30,0x02,0x86,0x46,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74, - 0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x65, - 0x72,0x74,0x73,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2F,0x63,0x61,0x63,0x65,0x72, - 0x74,0x73,0x2F,0x74,0x63,0x5F,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x5F, - 0x72,0x6F,0x6F,0x74,0x5F,0x49,0x2E,0x63,0x72,0x74,0x30,0x34,0x06,0x08,0x2B,0x06, - 0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x28,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F, - 0x63,0x73,0x70,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x2D, - 0x49,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65, - 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x92,0xA4,0x75, - 0x2C,0xA4,0x9E,0xBE,0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75, - 0x73,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01, - 0x01,0xFF,0x02,0x01,0x00,0x30,0x52,0x06,0x03,0x55,0x1D,0x20,0x04,0x4B,0x30,0x49, - 0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x3F,0x06,0x09,0x2A,0x82,0x14,0x00, - 0x2C,0x01,0x01,0x01,0x01,0x30,0x32,0x30,0x30,0x06,0x08,0x2B,0x06,0x01,0x05,0x05, - 0x07,0x02,0x01,0x16,0x24,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E, - 0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x67, - 0x75,0x69,0x64,0x65,0x6C,0x69,0x6E,0x65,0x73,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F, - 0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E, - 0x04,0x16,0x04,0x14,0xE9,0xB8,0x28,0x1D,0x46,0xCF,0xFC,0xCD,0xF8,0x4E,0x9B,0xC5, - 0xEE,0x4B,0x60,0xEB,0xD8,0x3B,0x3F,0xD1,0x30,0x81,0xFD,0x06,0x03,0x55,0x1D,0x1F, - 0x04,0x81,0xF5,0x30,0x81,0xF2,0x30,0x81,0xEF,0xA0,0x81,0xEC,0xA0,0x81,0xE9,0x86, - 0x46,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x74,0x63,0x75,0x6E, - 0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x2D,0x49,0x2E,0x74,0x72,0x75,0x73,0x74,0x63, - 0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C,0x2F,0x76,0x32,0x2F, - 0x74,0x63,0x5F,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x5F,0x72,0x6F,0x6F, - 0x74,0x5F,0x49,0x2E,0x63,0x72,0x6C,0x86,0x81,0x9E,0x6C,0x64,0x61,0x70,0x3A,0x2F, - 0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72, - 0x2E,0x64,0x65,0x2F,0x43,0x4E,0x3D,0x54,0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73, - 0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25,0x32,0x30,0x55,0x6E,0x69,0x76,0x65,0x72, - 0x73,0x61,0x6C,0x25,0x32,0x30,0x43,0x41,0x25,0x32,0x30,0x49,0x2C,0x4F,0x3D,0x54, - 0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25, - 0x32,0x30,0x47,0x6D,0x62,0x48,0x2C,0x4F,0x55,0x3D,0x72,0x6F,0x6F,0x74,0x63,0x65, - 0x72,0x74,0x73,0x2C,0x44,0x43,0x3D,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74, - 0x65,0x72,0x2C,0x44,0x43,0x3D,0x64,0x65,0x3F,0x63,0x65,0x72,0x74,0x69,0x66,0x69, - 0x63,0x61,0x74,0x65,0x52,0x65,0x76,0x6F,0x63,0x61,0x74,0x69,0x6F,0x6E,0x4C,0x69, - 0x73,0x74,0x3F,0x62,0x61,0x73,0x65,0x3F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, - 0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x39,0xC8,0xC4,0x9B, - 0xEE,0xBE,0x98,0xEE,0x48,0x72,0x6F,0x8D,0xE7,0x71,0xB6,0x0E,0x90,0x8C,0xD3,0xB2, - 0xC1,0x15,0x21,0xA8,0x46,0x90,0x68,0x5F,0x4A,0x04,0xF1,0x3A,0xC9,0x68,0x84,0x21, - 0xD8,0xA5,0xE6,0x04,0x75,0x5D,0x9F,0xD2,0xD4,0xF2,0x4B,0x77,0x43,0x32,0xDC,0x95, - 0xCB,0x60,0xBF,0x02,0x55,0xD0,0xAC,0x1C,0xB0,0xC5,0x14,0x97,0x9B,0x65,0x0A,0xC3, - 0x0F,0xA5,0x1D,0xEC,0xD8,0x49,0x39,0x95,0xB5,0xA9,0xBE,0xFA,0xF4,0x1E,0xAB,0x56, - 0xE7,0xA6,0xE5,0x01,0x08,0x88,0x35,0x5F,0x67,0x05,0xDD,0x44,0x24,0x50,0x12,0x22, - 0x44,0x63,0x79,0xF1,0x9B,0x57,0x69,0xCE,0xAB,0xD6,0x33,0x51,0x4F,0x8D,0xF0,0x70, - 0x3B,0x8E,0xAD,0x51,0x3A,0x17,0x7F,0x35,0x96,0x6B,0x68,0x68,0x63,0xB6,0x1C,0x0A, - 0xC9,0xF8,0xDF,0x1D,0x5E,0xCF,0x2B,0x11,0xA5,0x63,0xED,0xCC,0xD0,0xC6,0xD3,0x20, - 0x6F,0xAA,0xFC,0x68,0x48,0x7E,0x6D,0x1E,0xB8,0x3A,0x45,0xAA,0x12,0x86,0xF3,0xC7, - 0xBD,0x00,0xB5,0xEB,0xFE,0xEA,0x12,0x9F,0x73,0x33,0x78,0xE7,0x28,0x39,0x68,0xD3, - 0xA5,0x6D,0xDA,0x76,0xD1,0x4E,0xE1,0x55,0x95,0x80,0xA6,0xE0,0x1B,0xB8,0xCD,0xAC, - 0x56,0xEF,0x45,0x59,0x47,0x98,0x52,0xDB,0x3A,0x6E,0x26,0xB2,0x31,0x39,0x69,0x75, - 0xB1,0x2E,0x24,0xF0,0xA4,0x9D,0x97,0x88,0x5E,0x33,0x29,0xC6,0xB5,0xBC,0x07,0x40, - 0x3A,0x0C,0x3D,0xBA,0xCF,0x74,0x8C,0x4B,0x4E,0x7A,0x21,0xFA,0x1B,0x38,0xCD,0xC4, - 0x43,0x2F,0x6F,0xB4,0xDF,0x78,0xEE,0x99,0x92,0xE7,0x3A,0x1C, -}; - -unsigned char smime_root_certificate[993]={ - 0x30,0x82,0x03,0xDD,0x30,0x82,0x02,0xC5,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x1D, - 0xA2,0x00,0x01,0x00,0x02,0xEC,0xB7,0x60,0x80,0x78,0x8D,0xB6,0x06,0x30,0x0D,0x06, - 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x79,0x31,0x0B, - 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06, - 0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, - 0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55, - 0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74, - 0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31, - 0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75, - 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73, - 0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x33,0x32, - 0x32,0x31,0x35,0x35,0x34,0x32,0x38,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31, - 0x32,0x32,0x35,0x39,0x35,0x39,0x5A,0x30,0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, - 0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13, - 0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20, - 0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x0B,0x13,0x1B,0x54, - 0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E, - 0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,0x26,0x30,0x24,0x06,0x03, - 0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E, - 0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41, - 0x20,0x49,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,0xA4,0x77,0x23,0x96,0x44,0xAF,0x90,0xF4,0x31,0xA7,0x10,0xF4,0x26, - 0x87,0x9C,0xF3,0x38,0xD9,0x0F,0x5E,0xDE,0xCF,0x41,0xE8,0x31,0xAD,0xC6,0x74,0x91, - 0x24,0x96,0x78,0x1E,0x09,0xA0,0x9B,0x9A,0x95,0x4A,0x4A,0xF5,0x62,0x7C,0x02,0xA8, - 0xCA,0xAC,0xFB,0x5A,0x04,0x76,0x39,0xDE,0x5F,0xF1,0xF9,0xB3,0xBF,0xF3,0x03,0x58, - 0x55,0xD2,0xAA,0xB7,0xE3,0x04,0x22,0xD1,0xF8,0x94,0xDA,0x22,0x08,0x00,0x8D,0xD3, - 0x7C,0x26,0x5D,0xCC,0x77,0x79,0xE7,0x2C,0x78,0x39,0xA8,0x26,0x73,0x0E,0xA2,0x5D, - 0x25,0x69,0x85,0x4F,0x55,0x0E,0x9A,0xEF,0xC6,0xB9,0x44,0xE1,0x57,0x3D,0xDF,0x1F, - 0x54,0x22,0xE5,0x6F,0x65,0xAA,0x33,0x84,0x3A,0xF3,0xCE,0x7A,0xBE,0x55,0x97,0xAE, - 0x8D,0x12,0x0F,0x14,0x33,0xE2,0x50,0x70,0xC3,0x49,0x87,0x13,0xBC,0x51,0xDE,0xD7, - 0x98,0x12,0x5A,0xEF,0x3A,0x83,0x33,0x92,0x06,0x75,0x8B,0x92,0x7C,0x12,0x68,0x7B, - 0x70,0x6A,0x0F,0xB5,0x9B,0xB6,0x77,0x5B,0x48,0x59,0x9D,0xE4,0xEF,0x5A,0xAD,0xF3, - 0xC1,0x9E,0xD4,0xD7,0x45,0x4E,0xCA,0x56,0x34,0x21,0xBC,0x3E,0x17,0x5B,0x6F,0x77, - 0x0C,0x48,0x01,0x43,0x29,0xB0,0xDD,0x3F,0x96,0x6E,0xE6,0x95,0xAA,0x0C,0xC0,0x20, - 0xB6,0xFD,0x3E,0x36,0x27,0x9C,0xE3,0x5C,0xCF,0x4E,0x81,0xDC,0x19,0xBB,0x91,0x90, - 0x7D,0xEC,0xE6,0x97,0x04,0x1E,0x93,0xCC,0x22,0x49,0xD7,0x97,0x86,0xB6,0x13,0x0A, - 0x3C,0x43,0x23,0x77,0x7E,0xF0,0xDC,0xE6,0xCD,0x24,0x1F,0x3B,0x83,0x9B,0x34,0x3A, - 0x83,0x34,0xE3,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x1F,0x06,0x03, - 0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE, - 0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,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,0x86,0x30,0x1D, - 0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE, - 0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,0x30,0x0D,0x06, - 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01, - 0x00,0x28,0xD2,0xE0,0x86,0xD5,0xE6,0xF8,0x7B,0xF0,0x97,0xDC,0x22,0x6B,0x3B,0x95, - 0x14,0x56,0x0F,0x11,0x30,0xA5,0x9A,0x4F,0x3A,0xB0,0x3A,0xE0,0x06,0xCB,0x65,0xF5, - 0xED,0xC6,0x97,0x27,0xFE,0x25,0xF2,0x57,0xE6,0x5E,0x95,0x8C,0x3E,0x64,0x60,0x15, - 0x5A,0x7F,0x2F,0x0D,0x01,0xC5,0xB1,0x60,0xFD,0x45,0x35,0xCF,0xF0,0xB2,0xBF,0x06, - 0xD9,0xEF,0x5A,0xBE,0xB3,0x62,0x21,0xB4,0xD7,0xAB,0x35,0x7C,0x53,0x3E,0xA6,0x27, - 0xF1,0xA1,0x2D,0xDA,0x1A,0x23,0x9D,0xCC,0xDD,0xEC,0x3C,0x2D,0x9E,0x27,0x34,0x5D, - 0x0F,0xC2,0x36,0x79,0xBC,0xC9,0x4A,0x62,0x2D,0xED,0x6B,0xD9,0x7D,0x41,0x43,0x7C, - 0xB6,0xAA,0xCA,0xED,0x61,0xB1,0x37,0x82,0x15,0x09,0x1A,0x8A,0x16,0x30,0xD8,0xEC, - 0xC9,0xD6,0x47,0x72,0x78,0x4B,0x10,0x46,0x14,0x8E,0x5F,0x0E,0xAF,0xEC,0xC7,0x2F, - 0xAB,0x10,0xD7,0xB6,0xF1,0x6E,0xEC,0x86,0xB2,0xC2,0xE8,0x0D,0x92,0x73,0xDC,0xA2, - 0xF4,0x0F,0x3A,0xBF,0x61,0x23,0x10,0x89,0x9C,0x48,0x40,0x6E,0x70,0x00,0xB3,0xD3, - 0xBA,0x37,0x44,0x58,0x11,0x7A,0x02,0x6A,0x88,0xF0,0x37,0x34,0xF0,0x19,0xE9,0xAC, - 0xD4,0x65,0x73,0xF6,0x69,0x8C,0x64,0x94,0x3A,0x79,0x85,0x29,0xB0,0x16,0x2B,0x0C, - 0x82,0x3F,0x06,0x9C,0xC7,0xFD,0x10,0x2B,0x9E,0x0F,0x2C,0xB6,0x9E,0xE3,0x15,0xBF, - 0xD9,0x36,0x1C,0xBA,0x25,0x1A,0x52,0x3D,0x1A,0xEC,0x22,0x0C,0x1C,0xE0,0xA4,0xA2, - 0x3D,0xF0,0xE8,0x39,0xCF,0x81,0xC0,0x7B,0xED,0x5D,0x1F,0x6F,0xC5,0xD0,0x0B,0xD7, - 0x98, -}; - -/* subject:/C=US/ST=California/L=Walnut Creek/O=Lucas Garron/CN=revoked.badssl.com */ -/* issuer :/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA */ -uint8_t _probablyRevokedLeaf[]={ - 0x30,0x82,0x06,0xA1,0x30,0x82,0x05,0x89,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01, - 0xAF,0x1E,0xFB,0xDD,0x5E,0xAE,0x09,0x52,0x32,0x0B,0x24,0xFE,0x6B,0x55,0x68,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x4D, - 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, - 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, - 0x20,0x49,0x6E,0x63,0x31,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x03,0x13,0x1E,0x44, - 0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,0x53,0x65,0x63, - 0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17, - 0x0D,0x31,0x36,0x30,0x39,0x30,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D, - 0x31,0x39,0x30,0x39,0x31,0x31,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x30,0x6D,0x31, - 0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11, - 0x06,0x03,0x55,0x04,0x08,0x13,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69, - 0x61,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x07,0x13,0x0C,0x57,0x61,0x6C,0x6E, - 0x75,0x74,0x20,0x43,0x72,0x65,0x65,0x6B,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04, - 0x0A,0x13,0x0C,0x4C,0x75,0x63,0x61,0x73,0x20,0x47,0x61,0x72,0x72,0x6F,0x6E,0x31, - 0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12,0x72,0x65,0x76,0x6F,0x6B,0x65, - 0x64,0x2E,0x62,0x61,0x64,0x73,0x73,0x6C,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,0xC7,0x31,0x65, - 0xE4,0x55,0xCF,0x69,0x90,0x9F,0x6E,0x1F,0xD8,0x6A,0x13,0x7E,0x74,0xBF,0x13,0x3A, - 0x54,0x64,0x0F,0x74,0x24,0x3D,0xDC,0x60,0xB8,0xA7,0x45,0x01,0xB7,0xC8,0x6A,0x03, - 0xAC,0x64,0x4A,0x65,0xF0,0x7C,0x81,0x81,0x83,0x0A,0xD9,0xDD,0x31,0x20,0x82,0x48, - 0xA6,0x33,0x63,0xEE,0x2B,0x74,0xEA,0xB4,0xE6,0xC7,0x1C,0xB2,0x5E,0xE4,0x28,0x3A, - 0x7A,0x3D,0x20,0x19,0x03,0xB7,0x15,0x3F,0x4F,0xC9,0x26,0xEC,0xB7,0xCB,0xBF,0x48, - 0x6E,0x5F,0x34,0x70,0x56,0xC4,0x86,0xC7,0xE3,0x52,0x9A,0x21,0x33,0x2F,0x10,0x13, - 0xF3,0x25,0x0C,0x1E,0x94,0x35,0x2E,0xE8,0xD0,0xD1,0xB5,0xA0,0x77,0x40,0x91,0x2E, - 0xE9,0xBA,0xF8,0xFF,0x4E,0xF5,0xFB,0xF2,0x7A,0x04,0xA7,0xE6,0xC6,0xCE,0x3F,0x0F, - 0x10,0x18,0x32,0xC8,0x06,0xBC,0x15,0xB3,0xBE,0x69,0xAC,0x75,0x7D,0x42,0xA0,0x8C, - 0x2E,0xC3,0xAC,0xE1,0x20,0x4F,0x1E,0x36,0x9C,0x9A,0x2E,0xA2,0xFD,0x79,0x80,0xB6, - 0x62,0xF8,0xC0,0xB2,0x03,0xA9,0x29,0x50,0xCC,0xD5,0x25,0x8A,0x33,0x5E,0xE0,0x78, - 0x13,0x18,0xC0,0x80,0x17,0x09,0x95,0xBD,0xA2,0xFE,0x92,0x15,0x07,0x20,0x7A,0x81, - 0xCE,0xDB,0x0E,0x81,0x29,0x89,0xD4,0xC8,0xEC,0xB3,0xB3,0x79,0x0E,0xF2,0xCE,0x25, - 0xE7,0xEE,0xBE,0x21,0x7D,0xAF,0x0C,0x13,0x94,0x29,0xDE,0x35,0x9A,0x1E,0xD8,0x84, - 0x18,0x5A,0x5C,0x1A,0x94,0x82,0xCE,0x9A,0x61,0xD6,0x9D,0xEC,0xF8,0xEE,0xAD,0x3F, - 0x09,0x5B,0x73,0xEC,0xA2,0x9B,0xFA,0xDC,0x62,0xF1,0x58,0x1F,0x7D,0x02,0x03,0x01, - 0x00,0x01,0xA3,0x82,0x03,0x5B,0x30,0x82,0x03,0x57,0x30,0x1F,0x06,0x03,0x55,0x1D, - 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x0F,0x80,0x61,0x1C,0x82,0x31,0x61,0xD5,0x2F, - 0x28,0xE7,0x8D,0x46,0x38,0xB4,0x2C,0xE1,0xC6,0xD9,0xE2,0x30,0x1D,0x06,0x03,0x55, - 0x1D,0x0E,0x04,0x16,0x04,0x14,0xF4,0x48,0x7D,0x07,0x45,0x1A,0x32,0x07,0x90,0x91, - 0xAC,0x05,0xB8,0x9F,0xA9,0x11,0xF0,0x7E,0x11,0x36,0x30,0x1D,0x06,0x03,0x55,0x1D, - 0x11,0x04,0x16,0x30,0x14,0x82,0x12,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,0x62, - 0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F, - 0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55,0x1D,0x25, - 0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x06,0x08, - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x6B,0x06,0x03,0x55,0x1D,0x1F,0x04, - 0x64,0x30,0x62,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,0x74,0x74,0x70,0x3A, - 0x2F,0x2F,0x63,0x72,0x6C,0x33,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E, - 0x63,0x6F,0x6D,0x2F,0x73,0x73,0x63,0x61,0x2D,0x73,0x68,0x61,0x32,0x2D,0x67,0x35, - 0x2E,0x63,0x72,0x6C,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,0x74,0x74,0x70, - 0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x34,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74, - 0x2E,0x63,0x6F,0x6D,0x2F,0x73,0x73,0x63,0x61,0x2D,0x73,0x68,0x61,0x32,0x2D,0x67, - 0x35,0x2E,0x63,0x72,0x6C,0x30,0x4C,0x06,0x03,0x55,0x1D,0x20,0x04,0x45,0x30,0x43, - 0x30,0x37,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xFD,0x6C,0x01,0x01,0x30,0x2A,0x30, - 0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,0x68,0x74,0x74, - 0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72, - 0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x50,0x53,0x30,0x08,0x06,0x06,0x67,0x81,0x0C, - 0x01,0x02,0x03,0x30,0x7C,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04, - 0x70,0x30,0x6E,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86, - 0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x64,0x69,0x67, - 0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x46,0x06,0x08,0x2B,0x06,0x01, - 0x05,0x05,0x07,0x30,0x02,0x86,0x3A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x61, - 0x63,0x65,0x72,0x74,0x73,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63, - 0x6F,0x6D,0x2F,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x53,0x48,0x41,0x32,0x53, - 0x65,0x63,0x75,0x72,0x65,0x53,0x65,0x72,0x76,0x65,0x72,0x43,0x41,0x2E,0x63,0x72, - 0x74,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30, - 0x82,0x01,0x7E,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,0x04, - 0x82,0x01,0x6E,0x04,0x82,0x01,0x6A,0x01,0x68,0x00,0x75,0x00,0xA4,0xB9,0x09,0x90, - 0xB4,0x18,0x58,0x14,0x87,0xBB,0x13,0xA2,0xCC,0x67,0x70,0x0A,0x3C,0x35,0x98,0x04, - 0xF9,0x1B,0xDF,0xB8,0xE3,0x77,0xCD,0x0E,0xC8,0x0D,0xDC,0x10,0x00,0x00,0x01,0x56, - 0xEC,0xA1,0x37,0xDA,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02,0x20,0x3F,0x6C, - 0xA8,0xF5,0xC4,0x7C,0x01,0x4C,0xC3,0x5A,0x28,0x27,0x50,0x47,0x63,0xD9,0xAC,0xE1, - 0xBE,0x2D,0xBF,0x87,0x78,0xCB,0x3A,0x80,0x97,0x24,0x74,0xCD,0x16,0xF7,0x02,0x20, - 0x71,0xFF,0x93,0xA2,0xB5,0x54,0x7E,0x7F,0x53,0x45,0x7F,0x59,0x5A,0x60,0x18,0x21, - 0x5C,0xAB,0x7D,0x1F,0x08,0xB2,0x54,0xA0,0xB3,0xC4,0x88,0xA5,0x83,0xD2,0x63,0x55, - 0x00,0x77,0x00,0x68,0xF6,0x98,0xF8,0x1F,0x64,0x82,0xBE,0x3A,0x8C,0xEE,0xB9,0x28, - 0x1D,0x4C,0xFC,0x71,0x51,0x5D,0x67,0x93,0xD4,0x44,0xD1,0x0A,0x67,0xAC,0xBB,0x4F, - 0x4F,0xFB,0xC4,0x00,0x00,0x01,0x56,0xEC,0xA1,0x37,0xA1,0x00,0x00,0x04,0x03,0x00, - 0x48,0x30,0x46,0x02,0x21,0x00,0xFE,0x59,0x97,0x22,0x4C,0x6C,0x0F,0x39,0x05,0xD9, - 0xE4,0xCA,0x7E,0x3B,0xD3,0xB3,0x47,0x1B,0x61,0x72,0xB6,0x3A,0x4F,0xD6,0xF2,0xA3, - 0x57,0x49,0x48,0x4F,0x6A,0x6D,0x02,0x21,0x00,0x8F,0x14,0x1B,0x3C,0x1B,0x89,0xA3, - 0x1D,0x70,0xEC,0xD4,0xD7,0x11,0xBC,0xF9,0x0B,0x3C,0x60,0xAC,0x8C,0x84,0x73,0x24, - 0x6B,0x0E,0x37,0x6E,0x53,0x7F,0x9D,0x7F,0x34,0x00,0x76,0x00,0x56,0x14,0x06,0x9A, - 0x2F,0xD7,0xC2,0xEC,0xD3,0xF5,0xE1,0xBD,0x44,0xB2,0x3E,0xC7,0x46,0x76,0xB9,0xBC, - 0x99,0x11,0x5C,0xC0,0xEF,0x94,0x98,0x55,0xD6,0x89,0xD0,0xDD,0x00,0x00,0x01,0x56, - 0xEC,0xA1,0x38,0x7F,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x20,0x0E,0xBF, - 0x53,0x59,0x17,0x0C,0xEC,0x66,0x0C,0x5E,0x87,0xBB,0x8F,0x5F,0xB6,0x76,0x86,0xF2, - 0x5C,0xFC,0xBC,0xA8,0xB9,0xC0,0xDF,0xBC,0x1A,0x3B,0xEE,0x11,0xF2,0xD0,0x02,0x21, - 0x00,0x87,0x25,0x39,0xE4,0x32,0x99,0x48,0xCA,0x20,0x1B,0x13,0x96,0x1D,0xC3,0x2C, - 0x98,0x6B,0x1B,0xC0,0xCC,0xE5,0x67,0x22,0xBD,0x92,0x14,0xE9,0x68,0xCD,0x95,0x82, - 0x32,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00, - 0x03,0x82,0x01,0x01,0x00,0x5A,0xA0,0x49,0x88,0xAD,0x60,0x1F,0x08,0x53,0x4C,0xD9, - 0xB8,0xDC,0xF5,0x40,0x41,0xAD,0xEF,0xC8,0x7B,0x01,0x3B,0x13,0x70,0x44,0x99,0xF6, - 0x5C,0x23,0x46,0xF7,0x3A,0xC8,0x7D,0xC9,0x21,0xAD,0x3A,0x49,0x45,0x82,0x1E,0x5D, - 0x3B,0x1E,0x9B,0x6A,0x0A,0x3E,0x61,0x2D,0xF6,0xB1,0x99,0x74,0x2F,0x91,0xF9,0xD5, - 0xF1,0x9F,0xAE,0x74,0x26,0x8B,0x3C,0xA7,0x8C,0xBE,0x28,0xFE,0xAC,0x3B,0x70,0xAE, - 0x08,0x56,0x71,0xAC,0x55,0x7C,0x40,0x89,0x02,0x2D,0x61,0x2A,0xFD,0x54,0x72,0xBF, - 0x1A,0x5C,0x70,0x19,0x90,0x15,0xA4,0x76,0xA0,0x7F,0x56,0x1C,0xC1,0xF0,0x8D,0x5E, - 0x99,0x3D,0x83,0x41,0x54,0x68,0xE5,0x62,0xC1,0x5A,0xA2,0x64,0x8C,0x01,0x64,0x7A, - 0x23,0xB9,0x3F,0xBF,0x22,0xCF,0x1F,0xC0,0x47,0x80,0x1F,0x94,0xD5,0xF2,0x30,0x84, - 0xFB,0x07,0x02,0xFA,0x5B,0xA0,0xBA,0x09,0x04,0x98,0x4E,0xF3,0x25,0x56,0x4C,0xC4, - 0x7E,0xE0,0x27,0xD8,0xE8,0x32,0x8F,0xB3,0x3C,0x5A,0x92,0x4B,0xC0,0x77,0x2D,0xB0, - 0xE5,0xAE,0x1F,0xAF,0x1D,0x7F,0x21,0x9C,0x65,0x26,0xBE,0x0C,0xBA,0xE8,0x0D,0xC1, - 0xD2,0x67,0xB4,0xB9,0x33,0xD1,0x4A,0xEE,0xFC,0xB8,0xAF,0x03,0x5B,0xC8,0x3E,0xBC, - 0xFA,0x09,0x9D,0x04,0xCE,0x3E,0xA6,0xB5,0xC4,0x74,0x3B,0x31,0x7A,0xF3,0x2C,0x42, - 0xB3,0xC7,0x73,0xDB,0xAA,0x75,0x2E,0x8D,0x8A,0x9E,0x79,0x33,0xBE,0xD7,0xB6,0x14, - 0x9B,0x26,0xAB,0x7B,0x9E,0x14,0xB3,0x55,0xE6,0x4B,0xBB,0x86,0x94,0x11,0x74,0x02, - 0x35,0xB4,0x52,0x70,0x9B, -}; - -/* subject:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA */ -/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ -uint8_t _digiCertSha2SubCA[] ={ - 0x30,0x82,0x04,0x94,0x30,0x82,0x03,0x7C,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01, - 0xFD,0xA3,0xEB,0x6E,0xCA,0x75,0xC8,0x88,0x43,0x8B,0x72,0x4B,0xCF,0xBC,0x91,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x61, - 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, - 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, - 0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77, - 0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31, - 0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,0x69,0x43,0x65, - 0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, - 0x41,0x30,0x1E,0x17,0x0D,0x31,0x33,0x30,0x33,0x30,0x38,0x31,0x32,0x30,0x30,0x30, - 0x30,0x5A,0x17,0x0D,0x32,0x33,0x30,0x33,0x30,0x38,0x31,0x32,0x30,0x30,0x30,0x30, - 0x5A,0x30,0x4D,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, - 0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43, - 0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x03, - 0x13,0x1E,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20, - 0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41, - 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,0xDC,0xAE,0x58,0x90,0x4D,0xC1,0xC4,0x30,0x15,0x90,0x35,0x5B,0x6E,0x3C,0x82, - 0x15,0xF5,0x2C,0x5C,0xBD,0xE3,0xDB,0xFF,0x71,0x43,0xFA,0x64,0x25,0x80,0xD4,0xEE, - 0x18,0xA2,0x4D,0xF0,0x66,0xD0,0x0A,0x73,0x6E,0x11,0x98,0x36,0x17,0x64,0xAF,0x37, - 0x9D,0xFD,0xFA,0x41,0x84,0xAF,0xC7,0xAF,0x8C,0xFE,0x1A,0x73,0x4D,0xCF,0x33,0x97, - 0x90,0xA2,0x96,0x87,0x53,0x83,0x2B,0xB9,0xA6,0x75,0x48,0x2D,0x1D,0x56,0x37,0x7B, - 0xDA,0x31,0x32,0x1A,0xD7,0xAC,0xAB,0x06,0xF4,0xAA,0x5D,0x4B,0xB7,0x47,0x46,0xDD, - 0x2A,0x93,0xC3,0x90,0x2E,0x79,0x80,0x80,0xEF,0x13,0x04,0x6A,0x14,0x3B,0xB5,0x9B, - 0x92,0xBE,0xC2,0x07,0x65,0x4E,0xFC,0xDA,0xFC,0xFF,0x7A,0xAE,0xDC,0x5C,0x7E,0x55, - 0x31,0x0C,0xE8,0x39,0x07,0xA4,0xD7,0xBE,0x2F,0xD3,0x0B,0x6A,0xD2,0xB1,0xDF,0x5F, - 0xFE,0x57,0x74,0x53,0x3B,0x35,0x80,0xDD,0xAE,0x8E,0x44,0x98,0xB3,0x9F,0x0E,0xD3, - 0xDA,0xE0,0xD7,0xF4,0x6B,0x29,0xAB,0x44,0xA7,0x4B,0x58,0x84,0x6D,0x92,0x4B,0x81, - 0xC3,0xDA,0x73,0x8B,0x12,0x97,0x48,0x90,0x04,0x45,0x75,0x1A,0xDD,0x37,0x31,0x97, - 0x92,0xE8,0xCD,0x54,0x0D,0x3B,0xE4,0xC1,0x3F,0x39,0x5E,0x2E,0xB8,0xF3,0x5C,0x7E, - 0x10,0x8E,0x86,0x41,0x00,0x8D,0x45,0x66,0x47,0xB0,0xA1,0x65,0xCE,0xA0,0xAA,0x29, - 0x09,0x4E,0xF3,0x97,0xEB,0xE8,0x2E,0xAB,0x0F,0x72,0xA7,0x30,0x0E,0xFA,0xC7,0xF4, - 0xFD,0x14,0x77,0xC3,0xA4,0x5B,0x28,0x57,0xC2,0xB3,0xF9,0x82,0xFD,0xB7,0x45,0x58, - 0x9B,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x5A,0x30,0x82,0x01,0x56,0x30,0x12, - 0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02, - 0x01,0x00,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02, - 0x01,0x86,0x30,0x34,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28, - 0x30,0x26,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18, - 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x64,0x69,0x67,0x69, - 0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x7B,0x06,0x03,0x55,0x1D,0x1F,0x04, - 0x74,0x30,0x72,0x30,0x37,0xA0,0x35,0xA0,0x33,0x86,0x31,0x68,0x74,0x74,0x70,0x3A, - 0x2F,0x2F,0x63,0x72,0x6C,0x33,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E, - 0x63,0x6F,0x6D,0x2F,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x47,0x6C,0x6F,0x62, - 0x61,0x6C,0x52,0x6F,0x6F,0x74,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x37,0xA0,0x35, - 0xA0,0x33,0x86,0x31,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x34,0x2E, - 0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x44,0x69,0x67, - 0x69,0x43,0x65,0x72,0x74,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x52,0x6F,0x6F,0x74,0x43, - 0x41,0x2E,0x63,0x72,0x6C,0x30,0x3D,0x06,0x03,0x55,0x1D,0x20,0x04,0x36,0x30,0x34, - 0x30,0x32,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06, - 0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F, - 0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D, - 0x2F,0x43,0x50,0x53,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x0F, - 0x80,0x61,0x1C,0x82,0x31,0x61,0xD5,0x2F,0x28,0xE7,0x8D,0x46,0x38,0xB4,0x2C,0xE1, - 0xC6,0xD9,0xE2,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, - 0x03,0xDE,0x50,0x35,0x56,0xD1,0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97, - 0xB2,0x3D,0xD1,0x55,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, - 0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x23,0x3E,0xDF,0x4B,0xD2,0x31,0x42,0xA5, - 0xB6,0x7E,0x42,0x5C,0x1A,0x44,0xCC,0x69,0xD1,0x68,0xB4,0x5D,0x4B,0xE0,0x04,0x21, - 0x6C,0x4B,0xE2,0x6D,0xCC,0xB1,0xE0,0x97,0x8F,0xA6,0x53,0x09,0xCD,0xAA,0x2A,0x65, - 0xE5,0x39,0x4F,0x1E,0x83,0xA5,0x6E,0x5C,0x98,0xA2,0x24,0x26,0xE6,0xFB,0xA1,0xED, - 0x93,0xC7,0x2E,0x02,0xC6,0x4D,0x4A,0xBF,0xB0,0x42,0xDF,0x78,0xDA,0xB3,0xA8,0xF9, - 0x6D,0xFF,0x21,0x85,0x53,0x36,0x60,0x4C,0x76,0xCE,0xEC,0x38,0xDC,0xD6,0x51,0x80, - 0xF0,0xC5,0xD6,0xE5,0xD4,0x4D,0x27,0x64,0xAB,0x9B,0xC7,0x3E,0x71,0xFB,0x48,0x97, - 0xB8,0x33,0x6D,0xC9,0x13,0x07,0xEE,0x96,0xA2,0x1B,0x18,0x15,0xF6,0x5C,0x4C,0x40, - 0xED,0xB3,0xC2,0xEC,0xFF,0x71,0xC1,0xE3,0x47,0xFF,0xD4,0xB9,0x00,0xB4,0x37,0x42, - 0xDA,0x20,0xC9,0xEA,0x6E,0x8A,0xEE,0x14,0x06,0xAE,0x7D,0xA2,0x59,0x98,0x88,0xA8, - 0x1B,0x6F,0x2D,0xF4,0xF2,0xC9,0x14,0x5F,0x26,0xCF,0x2C,0x8D,0x7E,0xED,0x37,0xC0, - 0xA9,0xD5,0x39,0xB9,0x82,0xBF,0x19,0x0C,0xEA,0x34,0xAF,0x00,0x21,0x68,0xF8,0xAD, - 0x73,0xE2,0xC9,0x32,0xDA,0x38,0x25,0x0B,0x55,0xD3,0x9A,0x1D,0xF0,0x68,0x86,0xED, - 0x2E,0x41,0x34,0xEF,0x7C,0xA5,0x50,0x1D,0xBF,0x3A,0xF9,0xD3,0xC1,0x08,0x0C,0xE6, - 0xED,0x1E,0x8A,0x58,0x25,0xE4,0xB8,0x77,0xAD,0x2D,0x6E,0xF5,0x52,0xDD,0xB4,0x74, - 0x8F,0xAB,0x49,0x2E,0x9D,0x3B,0x93,0x34,0x28,0x1F,0x78,0xCE,0x94,0xEA,0xC7,0xBD, - 0xD3,0xC9,0x6D,0x1C,0xDE,0x5C,0x32,0xF3, -}; - -/* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ -/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ -uint8_t _digiCertGlobalRoot[] ={ - 0x30,0x82,0x03,0xAF,0x30,0x82,0x02,0x97,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x08, - 0x3B,0xE0,0x56,0x90,0x42,0x46,0xB1,0xA1,0x75,0x6A,0xC9,0x59,0x91,0xC7,0x4A,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x61, - 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, - 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, - 0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77, - 0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31, - 0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,0x69,0x43,0x65, - 0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, - 0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30, - 0x30,0x5A,0x17,0x0D,0x33,0x31,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30, - 0x5A,0x30,0x61,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, - 0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43, - 0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B, - 0x13,0x10,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63, - 0x6F,0x6D,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67, - 0x69,0x43,0x65,0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F, - 0x74,0x20,0x43,0x41,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,0x3B,0xE1,0x11,0x72,0xDE,0xA8,0xA4,0xD3,0xA3,0x57, - 0xAA,0x50,0xA2,0x8F,0x0B,0x77,0x90,0xC9,0xA2,0xA5,0xEE,0x12,0xCE,0x96,0x5B,0x01, - 0x09,0x20,0xCC,0x01,0x93,0xA7,0x4E,0x30,0xB7,0x53,0xF7,0x43,0xC4,0x69,0x00,0x57, - 0x9D,0xE2,0x8D,0x22,0xDD,0x87,0x06,0x40,0x00,0x81,0x09,0xCE,0xCE,0x1B,0x83,0xBF, - 0xDF,0xCD,0x3B,0x71,0x46,0xE2,0xD6,0x66,0xC7,0x05,0xB3,0x76,0x27,0x16,0x8F,0x7B, - 0x9E,0x1E,0x95,0x7D,0xEE,0xB7,0x48,0xA3,0x08,0xDA,0xD6,0xAF,0x7A,0x0C,0x39,0x06, - 0x65,0x7F,0x4A,0x5D,0x1F,0xBC,0x17,0xF8,0xAB,0xBE,0xEE,0x28,0xD7,0x74,0x7F,0x7A, - 0x78,0x99,0x59,0x85,0x68,0x6E,0x5C,0x23,0x32,0x4B,0xBF,0x4E,0xC0,0xE8,0x5A,0x6D, - 0xE3,0x70,0xBF,0x77,0x10,0xBF,0xFC,0x01,0xF6,0x85,0xD9,0xA8,0x44,0x10,0x58,0x32, - 0xA9,0x75,0x18,0xD5,0xD1,0xA2,0xBE,0x47,0xE2,0x27,0x6A,0xF4,0x9A,0x33,0xF8,0x49, - 0x08,0x60,0x8B,0xD4,0x5F,0xB4,0x3A,0x84,0xBF,0xA1,0xAA,0x4A,0x4C,0x7D,0x3E,0xCF, - 0x4F,0x5F,0x6C,0x76,0x5E,0xA0,0x4B,0x37,0x91,0x9E,0xDC,0x22,0xE6,0x6D,0xCE,0x14, - 0x1A,0x8E,0x6A,0xCB,0xFE,0xCD,0xB3,0x14,0x64,0x17,0xC7,0x5B,0x29,0x9E,0x32,0xBF, - 0xF2,0xEE,0xFA,0xD3,0x0B,0x42,0xD4,0xAB,0xB7,0x41,0x32,0xDA,0x0C,0xD4,0xEF,0xF8, - 0x81,0xD5,0xBB,0x8D,0x58,0x3F,0xB5,0x1B,0xE8,0x49,0x28,0xA2,0x70,0xDA,0x31,0x04, - 0xDD,0xF7,0xB2,0x16,0xF2,0x4C,0x0A,0x4E,0x07,0xA8,0xED,0x4A,0x3D,0x5E,0xB5,0x7F, - 0xA3,0x90,0xC3,0xAF,0x27,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0E, - 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F, - 0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30, - 0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x03,0xDE,0x50,0x35,0x56,0xD1, - 0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30,0x1F, - 0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x03,0xDE,0x50,0x35,0x56, - 0xD1,0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82, - 0x01,0x01,0x00,0xCB,0x9C,0x37,0xAA,0x48,0x13,0x12,0x0A,0xFA,0xDD,0x44,0x9C,0x4F, - 0x52,0xB0,0xF4,0xDF,0xAE,0x04,0xF5,0x79,0x79,0x08,0xA3,0x24,0x18,0xFC,0x4B,0x2B, - 0x84,0xC0,0x2D,0xB9,0xD5,0xC7,0xFE,0xF4,0xC1,0x1F,0x58,0xCB,0xB8,0x6D,0x9C,0x7A, - 0x74,0xE7,0x98,0x29,0xAB,0x11,0xB5,0xE3,0x70,0xA0,0xA1,0xCD,0x4C,0x88,0x99,0x93, - 0x8C,0x91,0x70,0xE2,0xAB,0x0F,0x1C,0xBE,0x93,0xA9,0xFF,0x63,0xD5,0xE4,0x07,0x60, - 0xD3,0xA3,0xBF,0x9D,0x5B,0x09,0xF1,0xD5,0x8E,0xE3,0x53,0xF4,0x8E,0x63,0xFA,0x3F, - 0xA7,0xDB,0xB4,0x66,0xDF,0x62,0x66,0xD6,0xD1,0x6E,0x41,0x8D,0xF2,0x2D,0xB5,0xEA, - 0x77,0x4A,0x9F,0x9D,0x58,0xE2,0x2B,0x59,0xC0,0x40,0x23,0xED,0x2D,0x28,0x82,0x45, - 0x3E,0x79,0x54,0x92,0x26,0x98,0xE0,0x80,0x48,0xA8,0x37,0xEF,0xF0,0xD6,0x79,0x60, - 0x16,0xDE,0xAC,0xE8,0x0E,0xCD,0x6E,0xAC,0x44,0x17,0x38,0x2F,0x49,0xDA,0xE1,0x45, - 0x3E,0x2A,0xB9,0x36,0x53,0xCF,0x3A,0x50,0x06,0xF7,0x2E,0xE8,0xC4,0x57,0x49,0x6C, - 0x61,0x21,0x18,0xD5,0x04,0xAD,0x78,0x3C,0x2C,0x3A,0x80,0x6B,0xA7,0xEB,0xAF,0x15, - 0x14,0xE9,0xD8,0x89,0xC1,0xB9,0x38,0x6C,0xE2,0x91,0x6C,0x8A,0xFF,0x64,0xB9,0x77, - 0x25,0x57,0x30,0xC0,0x1B,0x24,0xA3,0xE1,0xDC,0xE9,0xDF,0x47,0x7C,0xB5,0xB4,0x24, - 0x08,0x05,0x30,0xEC,0x2D,0xBD,0x0B,0xBF,0x45,0xBF,0x50,0xB9,0xA9,0xF3,0xEB,0x98, - 0x01,0x12,0xAD,0xC8,0x88,0xC6,0x98,0x34,0x5F,0x8D,0x0A,0x3C,0xC6,0xE9,0xD5,0x95, - 0x95,0x6D,0xDE, -}; +#include "si-23-sectrust-ocsp.h" static void tests(void) { SecTrustRef trust; SecCertificateRef cert0, cert1, responderCert; - isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), + isnt(cert0 = SecCertificateCreateWithBytes(NULL, _ocsp_c0, sizeof(_ocsp_c0)), NULL, "create cert0"); - isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), + isnt(cert1 = SecCertificateCreateWithBytes(NULL, _ocsp_c1, sizeof(_ocsp_c1)), NULL, "create cert1"); CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFArrayAppendValue(certs, cert0); CFArrayAppendValue(certs, cert1); - SecPolicyRef sslPolicy = SecPolicyCreateSSL(false, CFSTR("www.paypal.com")); + SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, CFSTR("www.paypal.com")); SecPolicyRef ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod); const void *v_policies[] = { sslPolicy, ocspPolicy }; CFArrayRef policies = CFArrayCreate(NULL, v_policies, @@ -1281,11 +56,11 @@ static void tests(void) is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); - /* Certificates are only EV if they are also CT. These aren't CT. */ + /* Certificates are only EV if they are also CT. */ CFDictionaryRef info = SecTrustCopyInfo(trust); CFBooleanRef ev = (CFBooleanRef)CFDictionaryGetValue(info, kSecTrustInfoExtendedValidationKey); - ok(!ev, "extended validation succeeded"); + ok(ev, "extended validation succeeded"); SecPolicyRef ocspSignerPolicy; ok(ocspSignerPolicy = SecPolicyCreateOCSPSigner(), @@ -1337,7 +112,7 @@ static void test_revocation() { CFArrayAppendValue(rcerts, rcert0); CFArrayAppendValue(rcerts, rcert1); - SecPolicyRef sslPolicy = SecPolicyCreateSSL(false, CFSTR("revoked.geotrust-global-ca.test-pages.certificatemanager.apple.com")); + SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, CFSTR("revoked.geotrust-global-ca.test-pages.certificatemanager.apple.com")); SecPolicyRef ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod); const void *v_policies[] = { sslPolicy, ocspPolicy }; CFArrayRef policies = CFArrayCreate(NULL, v_policies, @@ -1421,11 +196,11 @@ static void test_forced_revocation() SecCertificateRef smime_root_cert; // Import certificates from byte array above - isnt(smime_leaf_cert = SecCertificateCreateWithBytes(NULL, smime_leaf_certificate, sizeof(smime_leaf_certificate)), + isnt(smime_leaf_cert = SecCertificateCreateWithBytes(NULL, ocsp_smime_leaf_certificate, sizeof(ocsp_smime_leaf_certificate)), NULL, "SMIME Leaf Cert"); - isnt(smime_CA_cert = SecCertificateCreateWithBytes(NULL, smime_CA_certificate, sizeof(smime_CA_certificate)), + isnt(smime_CA_cert = SecCertificateCreateWithBytes(NULL, ocsp_smime_CA_certificate, sizeof(ocsp_smime_CA_certificate)), NULL, "SMIME CA Cert"); - isnt(smime_root_cert = SecCertificateCreateWithBytes(NULL, smime_root_certificate, sizeof(smime_root_certificate)), + isnt(smime_root_cert = SecCertificateCreateWithBytes(NULL, ocsp_smime_root_certificate, sizeof(ocsp_smime_root_certificate)), NULL, "SMIME Root Cert"); SecPolicyRef smimePolicy = SecPolicyCreateWithProperties(kSecPolicyAppleSMIME, NULL); @@ -1475,8 +250,11 @@ static void test_forced_revocation() ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate"); // Check results - // %%% This is now expected to fail, since the "TC TrustCenter Class 1 L1 CA IX" CA is revoked - // and the revocation information is present in the Valid database. + // NOTE: We now expect a fatal error, since the "TC TrustCenter Class 1 L1 CA IX" CA + // is revoked. That CA is no longer present in Valid since the TC root was removed + // from the trust store, and as of May 2018, its OCSP server no longer resolves in DNS. + // However, the OCSP URI for the CA's issuer is still active and reports the CA as revoked. + // is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure"); CFReleaseNull(trust); @@ -1496,8 +274,11 @@ static void test_forced_revocation() ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate"); // Check results - // %%% This is now expected to fail, since the "TC TrustCenter Class 1 L1 CA IX" CA is revoked - // and the revocation information is present in the Valid database. + // NOTE: We now expect a fatal error, since the "TC TrustCenter Class 1 L1 CA IX" CA + // is revoked. That CA is no longer present in Valid since the TC root was removed + // from the trust store, and as of May 2018, its OCSP server no longer resolves in DNS. + // However, the OCSP URI for the CA's issuer is still active and reports the CA as revoked. + // is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure"); CFReleaseNull(trust); @@ -1544,7 +325,7 @@ static void test_aia(void) { SecCertificateRef ovh = NULL, comodo_ev = NULL, comodo_aia = NULL; CFMutableArrayRef certs = NULL, policies = NULL; SecPolicyRef sslPolicy = NULL, revPolicy = NULL; - CFDateRef jan1st2009 = NULL; + CFDateRef verifyDate = NULL; CFDictionaryRef info = NULL; SecTrustRef trust = NULL; SecTrustResultType trustResult = kSecTrustResultInvalid; @@ -1562,19 +343,19 @@ static void test_aia(void) { &kCFTypeArrayCallBacks); policies = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - sslPolicy = SecPolicyCreateSSL(false, CFSTR("www.ovh.com")); + sslPolicy = SecPolicyCreateSSL(false, NULL); // For now, use SSL client policy to avoid SHA-1 deprecation revPolicy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod); CFArrayAppendValue(policies, sslPolicy); CFArrayAppendValue(policies, revPolicy); - /* Jan 1st 2009. */ - jan1st2009 = CFDateCreate(NULL, 252288000.0); + /* May 9th 2018. */ + verifyDate = CFDateCreate(NULL, 547600500); /* First run with no intermediate and disallow network fetching. * Evaluation should fail because it couldn't get the intermediate. */ CFArrayAppendValue(certs, ovh); ok_status(SecTrustCreateWithCertificates(certs, policies, &trust), "create trust"); - ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date"); + ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date"); ok_status(SecTrustSetNetworkFetchAllowed(trust, false), "set no network"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, @@ -1592,14 +373,14 @@ static void test_aia(void) { CFArrayAppendValue(certs, comodo_ev); ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust), "create trust"); - ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date"); + ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); info = SecTrustCopyInfo(trust); ev = (CFBooleanRef)CFDictionaryGetValue(info, kSecTrustInfoExtendedValidationKey); - ok(!ev, "extended validation succeeded due to caissuers fetch"); + ok(ev, "extended validation succeeded due to caissuers fetch"); //display_anchor_digest(trust); CFReleaseSafe(info); CFReleaseSafe(trust); @@ -1610,14 +391,14 @@ static void test_aia(void) { CFArrayAppendValue(certs, comodo_aia); ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust), "re-create trust with aia intermediate"); - ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date"); + ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); info = SecTrustCopyInfo(trust); ev = (CFBooleanRef)CFDictionaryGetValue(info, kSecTrustInfoExtendedValidationKey); - ok(!ev, "extended validation succeeded"); + ok(ev, "extended validation succeeded"); //display_anchor_digest(trust); CFReleaseSafe(info); CFReleaseSafe(trust); @@ -1628,14 +409,14 @@ static void test_aia(void) { CFArrayRemoveValueAtIndex(certs, 1); ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust), "re-create trust with aia intermediate"); - ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date"); + ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); info = SecTrustCopyInfo(trust); ev = (CFBooleanRef)CFDictionaryGetValue(info, kSecTrustInfoExtendedValidationKey); - ok(!ev, "extended validation succeeded"); + ok(ev, "extended validation succeeded"); //display_anchor_digest(trust); CFReleaseSafe(info); CFReleaseSafe(trust); @@ -1648,45 +429,47 @@ static void test_aia(void) { CFReleaseSafe(comodo_aia); CFReleaseSafe(comodo_ev); CFReleaseSafe(ovh); - CFReleaseSafe(jan1st2009); + CFReleaseSafe(verifyDate); } -static int ping_host(char *host_name){ - - struct sockaddr_in pin; - struct hostent *nlp_host; - int sd; - int port; - int retries = 5; - - port=80; - - //tries 5 times then give up - while ((nlp_host=gethostbyname(host_name))==0 && retries--){ - printf("Resolve Error! (%s) %d\n", host_name, h_errno); - sleep(1); - } +static void test_aia_https(void) { + SecCertificateRef leaf = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFArrayRef certs = NULL; + CFDateRef verifyDate = NULL; + CFErrorRef error = NULL; - if(nlp_host==0) - return 0; + leaf = SecCertificateCreateWithBytes(NULL, _caissuer_https, sizeof(_caissuer_https)); + const void *v_certs[] = { leaf }; - bzero(&pin,sizeof(pin)); - pin.sin_family=AF_INET; - pin.sin_addr.s_addr=htonl(INADDR_ANY); - pin.sin_addr.s_addr=((struct in_addr *)(nlp_host->h_addr))->s_addr; - pin.sin_port=htons(port); + certs = CFArrayCreate(NULL, v_certs, 1, &kCFTypeArrayCallBacks); + policy = SecPolicyCreateSSL(true, CFSTR("example.com")); + require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object")); - sd=socket(AF_INET,SOCK_STREAM,0); + verifyDate = CFDateCreate(NULL, 546700000.0); // April 29, 2018 at 6:06:40 AM PDT + require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date")); - if (connect(sd,(struct sockaddr*)&pin,sizeof(pin))==-1){ - printf("connect error! (%s) %d\n", host_name, errno); - close(sd); - return 0; - } - else{ - close(sd); - return 1; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + /* Evaluate trust. This cert does not chain to anything trusted and we can't fetch an + * intermediate because the URI is https. */ + is(SecTrustEvaluateWithError(trust, &error), false, "leaf with missing intermediate and https CAIssuer URI succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecCreateChainFailed, "got wrong error code for revoked cert, got %ld, expected %d", + (long)CFErrorGetCode(error), errSecCreateChainFailed); + } else { + fail("expected trust evaluation to fail and it did not."); } +#pragma clang diagnostic pop + +errOut: + CFReleaseNull(leaf); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(certs); + CFReleaseNull(verifyDate); + CFReleaseNull(error); } static void test_set_fetch_allowed(void) { @@ -1733,8 +516,12 @@ static void test_set_fetch_allowed(void) { /* Evaluate trust. SetFetchAllowed should have reset the trust result, so now we should re-do the evaluation and get a revoked failure. */ is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded"); - is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d", - (long)CFErrorGetCode(error), errSecCertificateRevoked); + if (error) { + is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d", + (long)CFErrorGetCode(error), errSecCertificateRevoked); + } else { + fail("expected trust evaluation to fail and it did not."); + } #pragma clang diagnostic pop @@ -1792,7 +579,11 @@ static void test_check_if_trusted(void) { * due to the temporal validity failure, but not due to revocation since we couldn't check for this * untrusted chain. */ is(SecTrustEvaluateWithError(trust, &error), false, "not yet valid cert succeeded trust evaluation"); - is(CFErrorGetCode(error), errSecCertificateExpired, "got wrong error code for expired cert"); + if (error) { + is(CFErrorGetCode(error), errSecCertificateExpired, "got wrong error code for expired cert"); + } else { + fail("expected trust evaluation to fail and it did not."); + } CFReleaseNull(error); /* Set verify date within validity period */ @@ -1801,8 +592,12 @@ static void test_check_if_trusted(void) { /* Evaluate trust. Now that we trust the chain, we should do a revocation check and get a revocation failure. */ is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded"); - is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d", - (long)CFErrorGetCode(error), errSecCertificateRevoked); + if (error) { + is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d", + (long)CFErrorGetCode(error), errSecCertificateRevoked); + } else { + fail("expected trust evaluation to fail and it did not."); + } #pragma clang diagnostic pop errOut: @@ -1820,6 +615,175 @@ errOut: CFReleaseNull(error); } +static void test_cache(void) { + SecCertificateRef leaf = NULL, subCA = NULL, root = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFArrayRef certs = NULL, anchors = NULL; + CFDateRef verifyDate = NULL; + CFErrorRef error = NULL; + + leaf = SecCertificateCreateWithBytes(NULL, _probablyRevokedLeaf, sizeof(_probablyRevokedLeaf)); + subCA = SecCertificateCreateWithBytes(NULL, _digiCertSha2SubCA, sizeof(_digiCertSha2SubCA)); + root = SecCertificateCreateWithBytes(NULL, _digiCertGlobalRoot, sizeof(_digiCertGlobalRoot)); + + const void *v_certs[] = { leaf, subCA }; + const void *v_anchors[] = { root }; + + certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks); + policy = SecPolicyCreateSSL(true, CFSTR("revoked.badssl.com")); + require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object")); + + anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks); + require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors")); + + verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT + require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date")); + + /* Clear the OCSP cache in case there are old responses for this cert. */ + ok(SecTrustFlushResponseCache(&error), "OCSP cache flush failed"); + CFReleaseNull(error); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + /* Evaluate trust. This cert is revoked, but is only listed as "probably revoked" by valid.apple.com. + * This cert should come back as revoked after a network-based fetch. */ + is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d", + (long)CFErrorGetCode(error), errSecCertificateRevoked); + } else { + fail("expected trust evaluation to fail and it did not."); + } + + /* Set no fetch allowed, so we're relying on the cached response from above */ + require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed")); + + /* Evaluate trust. Cached response should tell us that it's revoked. */ + is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with cached response succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d", + (long)CFErrorGetCode(error), errSecCertificateRevoked); + } else { + fail("expected trust evaluation to fail and it did not."); + } + +#pragma clang diagnostic pop + +errOut: + CFReleaseNull(leaf); + CFReleaseNull(subCA); + CFReleaseNull(root); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(certs); + CFReleaseNull(anchors); + CFReleaseNull(verifyDate); + CFReleaseNull(error); +} + +static void test_stapled_revoked_response(void) { + SecCertificateRef leaf = NULL, subCA = NULL, root = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFArrayRef certs = NULL, anchors = NULL; + CFDateRef verifyDate = NULL; + CFErrorRef error = NULL; + CFDataRef ocspResponse = NULL; + + leaf = SecCertificateCreateWithBytes(NULL, _probablyRevokedLeaf, sizeof(_probablyRevokedLeaf)); + subCA = SecCertificateCreateWithBytes(NULL, _digiCertSha2SubCA, sizeof(_digiCertSha2SubCA)); + root = SecCertificateCreateWithBytes(NULL, _digiCertGlobalRoot, sizeof(_digiCertGlobalRoot)); + + const void *v_certs[] = { leaf, subCA }; + const void *v_anchors[] = { root }; + + certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks); + policy = SecPolicyCreateSSL(true, CFSTR("revoked.badssl.com")); + require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object")); + + anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks); + require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors")); + + verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT + require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date")); + + /* Set the stapled response */ + ocspResponse = CFDataCreate(NULL, _digicertOCSPResponse, sizeof(_digicertOCSPResponse)); + ok_status(SecTrustSetOCSPResponse(trust, ocspResponse), "failed to set OCSP response"); + + /* Clear the OCSP cache in case there are old responses for this cert. */ + ok(SecTrustFlushResponseCache(&error), "OCSP cache flush failed"); + CFReleaseNull(error); + + /* Set no fetch allowed, so we're relying on the stapled response from above */ + require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed")); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + /* Evaluate trust. This cert is revoked, but is only listed as "probably revoked" by valid.apple.com. + * This cert should come back as revoked because of the stapled revoked response. */ + is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with stapled response succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d", + (long)CFErrorGetCode(error), errSecCertificateRevoked); + } else { + fail("expected trust evaluation to fail and it did not."); + } + +#pragma clang diagnostic pop + +errOut: + CFReleaseNull(leaf); + CFReleaseNull(subCA); + CFReleaseNull(root); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(certs); + CFReleaseNull(anchors); + CFReleaseNull(verifyDate); + CFReleaseNull(error); + CFReleaseNull(ocspResponse); +} + +static int ping_host(char *host_name){ + + struct sockaddr_in pin; + struct hostent *nlp_host; + int sd; + int port; + int retries = 5; + + port=80; + + //tries 5 times then give up + while ((nlp_host=gethostbyname(host_name))==0 && retries--){ + printf("Resolve Error! (%s) %d\n", host_name, h_errno); + sleep(1); + } + + if(nlp_host==0) + return 0; + + bzero(&pin,sizeof(pin)); + pin.sin_family=AF_INET; + pin.sin_addr.s_addr=htonl(INADDR_ANY); + pin.sin_addr.s_addr=((struct in_addr *)(nlp_host->h_addr))->s_addr; + pin.sin_port=htons(port); + + sd=socket(AF_INET,SOCK_STREAM,0); + + if (connect(sd,(struct sockaddr*)&pin,sizeof(pin))==-1){ + printf("connect error! (%s) %d\n", host_name, errno); + close(sd); + return 0; + } + else{ + close(sd); + return 1; + } +} + int si_23_sectrust_ocsp(int argc, char *const *argv) { char *hosts[] = { @@ -1834,7 +798,7 @@ int si_23_sectrust_ocsp(int argc, char *const *argv) unsigned host_cnt = 0; - plan_tests(82); + plan_tests(93); for (host_cnt = 0; host_cnt < sizeof(hosts)/sizeof(hosts[0]); host_cnt ++) { if(!ping_host(hosts[host_cnt])) { @@ -1845,10 +809,13 @@ int si_23_sectrust_ocsp(int argc, char *const *argv) tests(); test_aia(); + test_aia_https(); test_revocation(); test_forced_revocation(); test_set_fetch_allowed(); test_check_if_trusted(); + test_cache(); + test_stapled_revoked_response(); return 0; } diff --git a/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.h b/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.h new file mode 100644 index 00000000..e12d2ac1 --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.h @@ -0,0 +1,1423 @@ +/* + * Copyright (c) 2018 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@ + */ + + +#ifndef _SECURITY_SI_23_SECTRUST_OCSP_H_ +#define _SECURITY_SI_23_SECTRUST_OCSP_H_ + +/* subject:/jurisdictionC=US/jurisdictionST=Delaware/businessCategory=Private Organization/serialNumber=3014267/C=US/postalCode=95131-2021/ST=California/L=San Jose/street=2211 N 1st St/O=PayPal, Inc./OU=CDN Support/CN=www.paypal.com */ +/* issuer :/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */ +static const uint8_t _ocsp_c0[]={ + 0x30,0x82,0x07,0x64,0x30,0x82,0x06,0x4C,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x57, + 0xCB,0x7E,0x15,0xE2,0xE3,0xE2,0x44,0xD8,0x2B,0x01,0x63,0x29,0x46,0xEB,0xF0,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x77, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30, + 0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, + 0x20,0x43,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x1F,0x30,0x1D, + 0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20, + 0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x28,0x30, + 0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, + 0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20, + 0x43,0x41,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,0x39,0x32, + 0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x31,0x30,0x33,0x30, + 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x82,0x01,0x09,0x31,0x13,0x30,0x11,0x06, + 0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x55,0x53, + 0x31,0x19,0x30,0x17,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01, + 0x02,0x0C,0x08,0x44,0x65,0x6C,0x61,0x77,0x61,0x72,0x65,0x31,0x1D,0x30,0x1B,0x06, + 0x03,0x55,0x04,0x0F,0x13,0x14,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x4F,0x72, + 0x67,0x61,0x6E,0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,0x31,0x10,0x30,0x0E,0x06,0x03, + 0x55,0x04,0x05,0x13,0x07,0x33,0x30,0x31,0x34,0x32,0x36,0x37,0x31,0x0B,0x30,0x09, + 0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55, + 0x04,0x11,0x0C,0x0A,0x39,0x35,0x31,0x33,0x31,0x2D,0x32,0x30,0x32,0x31,0x31,0x13, + 0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72, + 0x6E,0x69,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x07,0x0C,0x08,0x53,0x61, + 0x6E,0x20,0x4A,0x6F,0x73,0x65,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x09,0x0C, + 0x0D,0x32,0x32,0x31,0x31,0x20,0x4E,0x20,0x31,0x73,0x74,0x20,0x53,0x74,0x31,0x15, + 0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0C,0x50,0x61,0x79,0x50,0x61,0x6C,0x2C, + 0x20,0x49,0x6E,0x63,0x2E,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B, + 0x43,0x44,0x4E,0x20,0x53,0x75,0x70,0x70,0x6F,0x72,0x74,0x31,0x17,0x30,0x15,0x06, + 0x03,0x55,0x04,0x03,0x0C,0x0E,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C, + 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,0xBF,0xF7,0x98,0x4B,0x4E,0xAA,0xF2,0x2F,0xC6,0x77,0xAB, + 0x26,0x76,0x60,0x2E,0xAB,0x50,0xBD,0x47,0xFF,0x8B,0x7C,0xB7,0x4A,0x75,0x0D,0x81, + 0xF7,0x46,0xE2,0x6B,0x03,0x9F,0xE4,0x07,0xFF,0xC0,0xAC,0xE5,0x15,0x7C,0x0B,0x81, + 0xAA,0xD0,0x32,0x88,0xB0,0x58,0x4E,0xEB,0xC1,0x13,0xCC,0x27,0xDD,0x1A,0x27,0x40, + 0xE8,0xF8,0x16,0x39,0x9A,0x4D,0x55,0xD5,0x0D,0x47,0x7C,0xD1,0x58,0xDB,0x41,0x8E, + 0x41,0x0E,0x3E,0xF2,0x3B,0x05,0x78,0x5D,0x8B,0xBF,0x28,0x71,0x41,0x11,0xC9,0x14, + 0xDB,0xE5,0xE2,0xAA,0x80,0x84,0xD0,0xE8,0xA7,0x2C,0xAA,0xC2,0x06,0xC8,0xDC,0xD3, + 0x18,0x35,0x42,0xA0,0x47,0xD5,0xB5,0xBA,0x57,0x66,0xC3,0x01,0x1F,0xC1,0x3A,0x58, + 0xE8,0x39,0x94,0xF5,0x5E,0x50,0x73,0x7E,0xB6,0x84,0x45,0x27,0xFC,0x52,0x4C,0xEF, + 0x1E,0x32,0x30,0x13,0x0C,0xF5,0x93,0xE5,0xB9,0xA8,0xA0,0x1C,0x05,0xA9,0x69,0xB7, + 0xA4,0x07,0x27,0xB9,0x6E,0x30,0x99,0x3A,0x6F,0x33,0xD7,0xFF,0x24,0xAE,0x02,0x12, + 0x08,0xF8,0x55,0x3F,0x30,0xEC,0xA2,0x5F,0x93,0x34,0x8B,0xAB,0x05,0xE6,0x8D,0xD5, + 0x93,0xBE,0x93,0x78,0x3E,0x97,0xA8,0x66,0xDC,0xA9,0x25,0x9B,0xF0,0x18,0x1A,0xFA, + 0xAE,0x80,0x99,0xC6,0x0F,0xE2,0x67,0xAA,0x26,0xA8,0xED,0xE8,0xFF,0x45,0x8F,0x45, + 0x0E,0xC8,0xC3,0x28,0x51,0x12,0xA6,0x17,0x1E,0x27,0xC8,0x61,0x71,0xC7,0x34,0x40, + 0xD0,0xC9,0xBA,0x49,0x72,0x9B,0xBD,0x57,0xCD,0xEA,0xD5,0x86,0x63,0x51,0x1D,0x48, + 0x14,0x70,0xBE,0xD4,0xD5,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x03,0x56,0x30,0x82, + 0x03,0x52,0x30,0x7C,0x06,0x03,0x55,0x1D,0x11,0x04,0x75,0x30,0x73,0x82,0x12,0x68, + 0x69,0x73,0x74,0x6F,0x72,0x79,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F, + 0x6D,0x82,0x0C,0x74,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82, + 0x0C,0x63,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x0D,0x63, + 0x36,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x14,0x64,0x65, + 0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63, + 0x6F,0x6D,0x82,0x0C,0x70,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D, + 0x82,0x0E,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D, + 0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x0E,0x06,0x03,0x55, + 0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x25,0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, + 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x6F,0x06,0x03,0x55,0x1D, + 0x20,0x04,0x68,0x30,0x66,0x30,0x5B,0x06,0x0B,0x60,0x86,0x48,0x01,0x86,0xF8,0x45, + 0x01,0x07,0x17,0x06,0x30,0x4C,0x30,0x23,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, + 0x02,0x01,0x16,0x17,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x64,0x2E,0x73,0x79, + 0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x63,0x70,0x73,0x30,0x25,0x06,0x08,0x2B, + 0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x19,0x0C,0x17,0x68,0x74,0x74,0x70,0x73, + 0x3A,0x2F,0x2F,0x64,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x72, + 0x70,0x61,0x30,0x07,0x06,0x05,0x67,0x81,0x0C,0x01,0x01,0x30,0x1F,0x06,0x03,0x55, + 0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59, + 0xA6,0x64,0x63,0xD6,0xCF,0x20,0x07,0x57,0xD5,0x91,0xE7,0x6A,0x30,0x2B,0x06,0x03, + 0x55,0x1D,0x1F,0x04,0x24,0x30,0x22,0x30,0x20,0xA0,0x1E,0xA0,0x1C,0x86,0x1A,0x68, + 0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x72,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63, + 0x6F,0x6D,0x2F,0x73,0x72,0x2E,0x63,0x72,0x6C,0x30,0x57,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x01,0x01,0x04,0x4B,0x30,0x49,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x30,0x01,0x86,0x13,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x72, + 0x2E,0x73,0x79,0x6D,0x63,0x64,0x2E,0x63,0x6F,0x6D,0x30,0x26,0x06,0x08,0x2B,0x06, + 0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73, + 0x72,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x73,0x72,0x2E,0x63, + 0x72,0x74,0x30,0x82,0x01,0x7E,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02, + 0x04,0x02,0x04,0x82,0x01,0x6E,0x04,0x82,0x01,0x6A,0x01,0x68,0x00,0x75,0x00,0xDD, + 0xEB,0x1D,0x2B,0x7A,0x0D,0x4F,0xA6,0x20,0x8B,0x81,0xAD,0x81,0x68,0x70,0x7E,0x2E, + 0x8E,0x9D,0x01,0xD5,0x5C,0x88,0x8D,0x3D,0x11,0xC4,0xCD,0xB6,0xEC,0xBE,0xCC,0x00, + 0x00,0x01,0x5E,0xAB,0x85,0x57,0xB1,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02, + 0x20,0x07,0xE3,0x40,0xE7,0x2A,0x3C,0x38,0xEC,0xF4,0xFB,0x7D,0xBC,0x99,0x23,0xBA, + 0xD6,0x39,0x0D,0x7B,0x87,0x4C,0xF0,0x8B,0xAC,0x88,0x76,0x16,0x98,0xAD,0xED,0xAC, + 0x34,0x02,0x20,0x5E,0xA4,0x5A,0xF6,0xBD,0xD0,0xF2,0x4D,0x77,0x31,0x31,0x65,0x94, + 0xC1,0x2C,0x2D,0x16,0x2D,0x4C,0x8A,0xF3,0xAA,0x2C,0x63,0x3A,0x26,0x94,0x8F,0x5C, + 0x04,0x32,0xB4,0x00,0x77,0x00,0xA4,0xB9,0x09,0x90,0xB4,0x18,0x58,0x14,0x87,0xBB, + 0x13,0xA2,0xCC,0x67,0x70,0x0A,0x3C,0x35,0x98,0x04,0xF9,0x1B,0xDF,0xB8,0xE3,0x77, + 0xCD,0x0E,0xC8,0x0D,0xDC,0x10,0x00,0x00,0x01,0x5E,0xAB,0x85,0x57,0xEC,0x00,0x00, + 0x04,0x03,0x00,0x48,0x30,0x46,0x02,0x21,0x00,0xE4,0x54,0x30,0xB7,0x22,0x75,0x2E, + 0x6B,0x3F,0xE9,0x65,0x5D,0x59,0x8B,0x0E,0x9F,0x44,0x9D,0x8C,0x05,0xB1,0xFB,0x11, + 0xD7,0x59,0x98,0x3C,0x35,0xEA,0x52,0xEA,0x9E,0x02,0x21,0x00,0xBD,0x07,0x6C,0x78, + 0x5B,0x81,0xFF,0x45,0x6E,0x8C,0x68,0x99,0x41,0x72,0xC1,0xE5,0x36,0x71,0x81,0x00, + 0x85,0x1D,0x2A,0xC4,0xFD,0x9E,0x7D,0x85,0xC0,0xD5,0x8F,0x6A,0x00,0x76,0x00,0xEE, + 0x4B,0xBD,0xB7,0x75,0xCE,0x60,0xBA,0xE1,0x42,0x69,0x1F,0xAB,0xE1,0x9E,0x66,0xA3, + 0x0F,0x7E,0x5F,0xB0,0x72,0xD8,0x83,0x00,0xC4,0x7B,0x89,0x7A,0xA8,0xFD,0xCB,0x00, + 0x00,0x01,0x5E,0xAB,0x85,0x59,0xB0,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02, + 0x21,0x00,0xD5,0x8C,0xD3,0x11,0xE6,0x08,0xAA,0xCC,0x98,0x35,0xFC,0xED,0x49,0xF0, + 0x34,0x8B,0xE2,0x68,0x0D,0x66,0x65,0x8F,0x1D,0x56,0x7A,0x7E,0xC7,0x35,0x19,0xD1, + 0xB7,0x0A,0x02,0x20,0x6A,0x96,0x22,0xEC,0x63,0x63,0x79,0xE5,0x5E,0x27,0x98,0x19, + 0xDE,0x4F,0xFC,0x69,0x0A,0x22,0x64,0x97,0x70,0x92,0x67,0x9C,0x7C,0xF4,0x00,0xD1, + 0xDF,0xC2,0x61,0xE6,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, + 0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x88,0x75,0x7C,0xEE,0x8C,0x6F,0x9E,0xE3, + 0xDA,0xB9,0x40,0x53,0x78,0xED,0x57,0x11,0x4C,0xE4,0x3F,0x11,0x4A,0xC3,0xDA,0x80, + 0x97,0xF4,0xF8,0x8E,0x0F,0x8E,0xB1,0x73,0x67,0x83,0xDE,0x3E,0x9E,0x2C,0x85,0x6B, + 0x02,0xB5,0x73,0x48,0x26,0x4D,0x43,0xD7,0x04,0xBD,0xC7,0x7D,0xC4,0xDC,0x03,0xB8, + 0x0B,0x35,0x7C,0x39,0x2C,0x42,0x24,0xB3,0xDC,0x15,0x78,0xF6,0x54,0x70,0xFC,0xE0, + 0x9B,0xF5,0x9F,0x30,0x08,0xB0,0x2F,0x4B,0xF1,0xA1,0x49,0x96,0x08,0x76,0x5C,0xAE, + 0xDC,0x3E,0x95,0x0D,0x1A,0x89,0x0C,0xDA,0x32,0xAD,0x2A,0x4B,0xD7,0x63,0x50,0x8C, + 0x0C,0xE3,0x08,0xEC,0x6F,0x78,0x55,0x67,0x05,0x68,0x65,0x22,0x39,0xE3,0x7E,0x36, + 0xD9,0x90,0xD2,0x3D,0x06,0x36,0xC7,0xDE,0xEE,0xF4,0xD6,0xDD,0xDA,0xC3,0xFB,0xAC, + 0x43,0xFE,0x2F,0x1C,0x64,0x9B,0xE2,0xDD,0xC0,0x89,0x8B,0x52,0x98,0x8D,0x0E,0xF6, + 0x09,0x2D,0xE4,0x4D,0x62,0x9C,0x16,0x22,0x96,0xFB,0x68,0x5B,0x94,0x87,0x87,0xCE, + 0x18,0x7E,0x41,0x60,0x79,0xA4,0x17,0x3E,0x71,0xF2,0xB1,0xA2,0x06,0xD8,0x71,0xD8, + 0x33,0x0B,0x6A,0xD4,0x67,0x68,0x24,0x3E,0xBA,0xC6,0x21,0x94,0x5D,0x6A,0xF6,0x21, + 0x84,0x5F,0xD0,0xFF,0xAC,0xE4,0x3D,0xAA,0xAD,0x95,0x85,0xFC,0x4B,0x69,0x30,0x72, + 0xB7,0xBA,0x4D,0xDA,0x3A,0xED,0xD9,0x7D,0x40,0x1D,0x02,0x29,0xB8,0xD5,0x0C,0x09, + 0x9E,0x0D,0x74,0x8B,0xFA,0x62,0x02,0x4A,0x88,0x6E,0x7C,0x13,0x56,0xBA,0x99,0x3F, + 0x13,0x78,0x48,0x82,0xAC,0x43,0x8E,0x61, +}; + + +/* subject:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */ +/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */ +static const uint8_t _ocsp_c1[]= { + 0x30,0x82,0x05,0x2B,0x30,0x82,0x04,0x13,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x7E, + 0xE1,0x4A,0x6F,0x6F,0xEF,0xF2,0xD3,0x7F,0x3F,0xAD,0x65,0x4D,0x3A,0xDA,0xB4,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, + 0xCA,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, + 0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67, + 0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B, + 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74, + 0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04, + 0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69, + 0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72, + 0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20, + 0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56, + 0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20, + 0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43, + 0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74, + 0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x35,0x30,0x1E,0x17,0x0D,0x31, + 0x33,0x31,0x30,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x33, + 0x31,0x30,0x33,0x30,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x77,0x31,0x0B,0x30, + 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30,0x1B,0x06,0x03, + 0x55,0x04,0x0A,0x13,0x14,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20,0x43,0x6F, + 0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55, + 0x04,0x0B,0x13,0x16,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20,0x54,0x72,0x75, + 0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x28,0x30,0x26,0x06,0x03, + 0x55,0x04,0x03,0x13,0x1F,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20,0x43,0x6C, + 0x61,0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20,0x43,0x41,0x20, + 0x2D,0x20,0x47,0x33,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,0xD8,0xA1,0x65,0x74,0x23,0xE8,0x2B,0x64,0xE2,0x32,0xD7, + 0x33,0x37,0x3D,0x8E,0xF5,0x34,0x16,0x48,0xDD,0x4F,0x7F,0x87,0x1C,0xF8,0x44,0x23, + 0x13,0x8E,0xFB,0x11,0xD8,0x44,0x5A,0x18,0x71,0x8E,0x60,0x16,0x26,0x92,0x9B,0xFD, + 0x17,0x0B,0xE1,0x71,0x70,0x42,0xFE,0xBF,0xFA,0x1C,0xC0,0xAA,0xA3,0xA7,0xB5,0x71, + 0xE8,0xFF,0x18,0x83,0xF6,0xDF,0x10,0x0A,0x13,0x62,0xC8,0x3D,0x9C,0xA7,0xDE,0x2E, + 0x3F,0x0C,0xD9,0x1D,0xE7,0x2E,0xFB,0x2A,0xCE,0xC8,0x9A,0x7F,0x87,0xBF,0xD8,0x4C, + 0x04,0x15,0x32,0xC9,0xD1,0xCC,0x95,0x71,0xA0,0x4E,0x28,0x4F,0x84,0xD9,0x35,0xFB, + 0xE3,0x86,0x6F,0x94,0x53,0xE6,0x72,0x8A,0x63,0x67,0x2E,0xBE,0x69,0xF6,0xF7,0x6E, + 0x8E,0x9C,0x60,0x04,0xEB,0x29,0xFA,0xC4,0x47,0x42,0xD2,0x78,0x98,0xE3,0xEC,0x0B, + 0xA5,0x92,0xDC,0xB7,0x9A,0xBD,0x80,0x64,0x2B,0x38,0x7C,0x38,0x09,0x5B,0x66,0xF6, + 0x2D,0x95,0x7A,0x86,0xB2,0x34,0x2E,0x85,0x9E,0x90,0x0E,0x5F,0xB7,0x5D,0xA4,0x51, + 0x72,0x46,0x70,0x13,0xBF,0x67,0xF2,0xB6,0xA7,0x4D,0x14,0x1E,0x6C,0xB9,0x53,0xEE, + 0x23,0x1A,0x4E,0x8D,0x48,0x55,0x43,0x41,0xB1,0x89,0x75,0x6A,0x40,0x28,0xC5,0x7D, + 0xDD,0xD2,0x6E,0xD2,0x02,0x19,0x2F,0x7B,0x24,0x94,0x4B,0xEB,0xF1,0x1A,0xA9,0x9B, + 0xE3,0x23,0x9A,0xEA,0xFA,0x33,0xAB,0x0A,0x2C,0xB7,0xF4,0x60,0x08,0xDD,0x9F,0x1C, + 0xCD,0xDD,0x2D,0x01,0x66,0x80,0xAF,0xB3,0x2F,0x29,0x1D,0x23,0xB8,0x8A,0xE1,0xA1, + 0x70,0x07,0x0C,0x34,0x0F,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x5D,0x30,0x82, + 0x01,0x59,0x30,0x2F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x23, + 0x30,0x21,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x13, + 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x32,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E, + 0x63,0x6F,0x6D,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30, + 0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x65,0x06,0x03,0x55,0x1D,0x20,0x04,0x5E, + 0x30,0x5C,0x30,0x5A,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x52,0x30,0x26,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F, + 0x2F,0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D, + 0x2F,0x63,0x70,0x73,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02, + 0x30,0x1C,0x1A,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73, + 0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x70,0x61,0x30,0x30, + 0x06,0x03,0x55,0x1D,0x1F,0x04,0x29,0x30,0x27,0x30,0x25,0xA0,0x23,0xA0,0x21,0x86, + 0x1F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x31,0x2E,0x73,0x79,0x6D,0x63,0x62, + 0x2E,0x63,0x6F,0x6D,0x2F,0x70,0x63,0x61,0x33,0x2D,0x67,0x35,0x2E,0x63,0x72,0x6C, + 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06, + 0x30,0x29,0x06,0x03,0x55,0x1D,0x11,0x04,0x22,0x30,0x20,0xA4,0x1E,0x30,0x1C,0x31, + 0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x53,0x79,0x6D,0x61,0x6E,0x74, + 0x65,0x63,0x50,0x4B,0x49,0x2D,0x31,0x2D,0x35,0x33,0x33,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x0E,0x04,0x16,0x04,0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59,0xA6,0x64, + 0x63,0xD6,0xCF,0x20,0x07,0x57,0xD5,0x91,0xE7,0x6A,0x30,0x1F,0x06,0x03,0x55,0x1D, + 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7F,0xD3,0x65,0xA7,0xC2,0xDD,0xEC,0xBB,0xF0, + 0x30,0x09,0xF3,0x43,0x39,0xFA,0x02,0xAF,0x33,0x31,0x33,0x30,0x0D,0x06,0x09,0x2A, + 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x42, + 0x01,0x55,0x7B,0xD0,0x16,0x1A,0x5D,0x58,0xE8,0xBB,0x9B,0xA8,0x4D,0xD7,0xF3,0xD7, + 0xEB,0x13,0x94,0x86,0xD6,0x7F,0x21,0x0B,0x47,0xBC,0x57,0x9B,0x92,0x5D,0x4F,0x05, + 0x9F,0x38,0xA4,0x10,0x7C,0xCF,0x83,0xBE,0x06,0x43,0x46,0x8D,0x08,0xBC,0x6A,0xD7, + 0x10,0xA6,0xFA,0xAB,0xAF,0x2F,0x61,0xA8,0x63,0xF2,0x65,0xDF,0x7F,0x4C,0x88,0x12, + 0x88,0x4F,0xB3,0x69,0xD9,0xFF,0x27,0xC0,0x0A,0x97,0x91,0x8F,0x56,0xFB,0x89,0xC4, + 0xA8,0xBB,0x92,0x2D,0x1B,0x73,0xB0,0xC6,0xAB,0x36,0xF4,0x96,0x6C,0x20,0x08,0xEF, + 0x0A,0x1E,0x66,0x24,0x45,0x4F,0x67,0x00,0x40,0xC8,0x07,0x54,0x74,0x33,0x3B,0xA6, + 0xAD,0xBB,0x23,0x9F,0x66,0xED,0xA2,0x44,0x70,0x34,0xFB,0x0E,0xEA,0x01,0xFD,0xCF, + 0x78,0x74,0xDF,0xA7,0xAD,0x55,0xB7,0x5F,0x4D,0xF6,0xD6,0x3F,0xE0,0x86,0xCE,0x24, + 0xC7,0x42,0xA9,0x13,0x14,0x44,0x35,0x4B,0xB6,0xDF,0xC9,0x60,0xAC,0x0C,0x7F,0xD9, + 0x93,0x21,0x4B,0xEE,0x9C,0xE4,0x49,0x02,0x98,0xD3,0x60,0x7B,0x5C,0xBC,0xD5,0x30, + 0x2F,0x07,0xCE,0x44,0x42,0xC4,0x0B,0x99,0xFE,0xE6,0x9F,0xFC,0xB0,0x78,0x86,0x51, + 0x6D,0xD1,0x2C,0x9D,0xC6,0x96,0xFB,0x85,0x82,0xBB,0x04,0x2F,0xF7,0x62,0x80,0xEF, + 0x62,0xDA,0x7F,0xF6,0x0E,0xAC,0x90,0xB8,0x56,0xBD,0x79,0x3F,0xF2,0x80,0x6E,0xA3, + 0xD9,0xB9,0x0F,0x5D,0x3A,0x07,0x1D,0x91,0x93,0x86,0x4B,0x29,0x4C,0xE1,0xDC,0xB5, + 0xE1,0xE0,0x33,0x9D,0xB3,0xCB,0x36,0x91,0x4B,0xFE,0xA1,0xB4,0xEE,0xF0,0xF9, +}; + +static const uint8_t _responderCert[]= { + 0x30,0x82,0x04,0x58,0x30,0x82,0x03,0x40,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x03, + 0x56,0x99,0xC9,0x07,0x45,0xC1,0xA9,0x4C,0x50,0x3A,0x24,0x28,0xD6,0x04,0x5D,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x77, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30, + 0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, + 0x20,0x43,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x1F,0x30,0x1D, + 0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20, + 0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x28,0x30, + 0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, + 0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20, + 0x43,0x41,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,0x37,0x31, + 0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x37,0x31,0x30,0x31,0x36, + 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55, + 0x04,0x03,0x13,0x2E,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20,0x43,0x6C,0x61, + 0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20,0x43,0x41,0x20,0x2D, + 0x20,0x47,0x33,0x20,0x4F,0x43,0x53,0x50,0x20,0x52,0x65,0x73,0x70,0x6F,0x6E,0x64, + 0x65,0x72,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,0xA1,0x49,0x87,0x17,0x74,0x89,0x30,0x97,0x77,0x0D,0x11,0x51,0x51, + 0x3A,0x80,0x2D,0x7C,0xEC,0xB2,0x4C,0xB1,0xE5,0x46,0x51,0x1C,0xF5,0x7A,0x02,0xB3, + 0x77,0x19,0x3B,0x7B,0x94,0x00,0x1A,0xA4,0xD1,0xB8,0xF0,0x07,0xF2,0x1B,0x8D,0x70, + 0xC0,0x81,0x44,0xB5,0x58,0xD8,0x34,0xEC,0x62,0xF7,0x8B,0x4B,0x3C,0x44,0x7D,0xD0, + 0x35,0xAE,0xEF,0x2B,0xFB,0x75,0xAF,0xB3,0x10,0x32,0xC8,0xF9,0x08,0x2C,0x5C,0x1B, + 0x07,0x56,0x7C,0x88,0x6D,0xEE,0x4C,0xD5,0x8F,0xD4,0x48,0x41,0xBB,0x03,0xA8,0xBF, + 0x20,0xE8,0x52,0xFB,0x24,0x5F,0x90,0x78,0xB8,0x87,0x0D,0xD5,0x17,0xAB,0xA8,0xF0, + 0xDB,0xF8,0x61,0x9F,0xF8,0x09,0x88,0x79,0x19,0x6F,0x57,0xC6,0x69,0x01,0x08,0xAA, + 0xC6,0xBF,0x8D,0x0C,0x2D,0xD3,0x54,0x89,0x03,0xC8,0xA8,0x55,0x00,0xC2,0x89,0xEC, + 0x8E,0xD8,0xD8,0x12,0x15,0x26,0x67,0x8E,0x88,0x0F,0x94,0xFA,0x57,0x50,0xE7,0xE9, + 0x7B,0x1B,0x94,0xF6,0xF1,0xE2,0x91,0x02,0x42,0x4F,0x3B,0x3E,0xB6,0xDD,0x3C,0x78, + 0xE7,0xC8,0x45,0x4F,0x7B,0x7D,0x41,0xD5,0x95,0x3C,0xD6,0x16,0x84,0xF5,0x16,0xF2, + 0x45,0x6C,0xBF,0x05,0x00,0x7E,0x92,0x70,0xB7,0x01,0x14,0x86,0x89,0x89,0x9D,0x6B, + 0xDC,0x5D,0xDF,0x30,0x25,0x7F,0xAA,0x93,0xC0,0xC7,0xC7,0x80,0x12,0xEE,0x47,0xF7, + 0x90,0x69,0x82,0x86,0xFA,0x22,0x11,0x45,0xAB,0xD1,0x50,0x4F,0xED,0x87,0xCA,0x99, + 0x20,0xB5,0xC1,0x8D,0xAC,0x01,0x41,0x5C,0x70,0x3C,0x4D,0xD7,0x8E,0xD6,0x8F,0x51, + 0x19,0x79,0xAB,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x1C,0x30,0x82,0x01,0x18, + 0x30,0x0F,0x06,0x09,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,0x04,0x02,0x05, + 0x00,0x30,0x22,0x06,0x03,0x55,0x1D,0x11,0x04,0x1B,0x30,0x19,0xA4,0x17,0x30,0x15, + 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x54,0x47,0x56,0x2D,0x45, + 0x2D,0x32,0x31,0x35,0x32,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, + 0x80,0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59,0xA6,0x64,0x63,0xD6,0xCF,0x20, + 0x07,0x57,0xD5,0x91,0xE7,0x6A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, + 0x14,0xE3,0x5E,0x00,0x73,0xB3,0x6F,0xFB,0x26,0x90,0x5A,0xE3,0xE5,0xF4,0xB5,0x99, + 0x95,0xEA,0x80,0xFA,0x9F,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, + 0x02,0x30,0x00,0x30,0x6E,0x06,0x03,0x55,0x1D,0x20,0x04,0x67,0x30,0x65,0x30,0x63, + 0x06,0x0B,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x17,0x03,0x30,0x54,0x30, + 0x26,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74, + 0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E, + 0x63,0x6F,0x6D,0x2F,0x63,0x70,0x73,0x30,0x2A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05, + 0x07,0x02,0x02,0x30,0x1E,0x1A,0x1C,0x20,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, + 0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,0x2F, + 0x72,0x70,0x61,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01, + 0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x3B,0x57,0xAB,0x23, + 0x8E,0x31,0x91,0x87,0x0E,0x02,0xC1,0x55,0xD4,0x53,0x58,0x16,0xEA,0x1B,0x77,0x61, + 0x68,0x88,0x96,0xC6,0x8D,0x4F,0x57,0xD8,0x80,0x04,0xD2,0xCB,0x41,0x84,0xE9,0x78, + 0xB1,0x21,0xD0,0xFD,0xB6,0x68,0x8C,0xB0,0xD5,0xED,0x28,0xB3,0xA9,0x9A,0x8A,0xBB, + 0x88,0x09,0x30,0x04,0xB1,0x29,0xC6,0xC9,0x13,0x4F,0xDB,0xDA,0x52,0x00,0x3A,0x61, + 0xEE,0xD5,0x6F,0xAB,0xDE,0x71,0x1B,0x8E,0xFA,0xE0,0x1F,0x09,0x9D,0x00,0xF1,0x1F, + 0xAC,0x88,0x73,0x86,0x37,0xDA,0x7A,0x05,0x3F,0xDB,0xD2,0xEB,0x47,0x0B,0xC9,0x39, + 0x74,0xA4,0x06,0xBD,0x50,0x63,0x52,0xEE,0x9F,0xE7,0x58,0x07,0x95,0x85,0x6D,0x43, + 0xE8,0x3B,0x7E,0x0D,0x36,0x65,0x2A,0xB1,0x62,0xB5,0xDB,0x31,0x49,0x38,0x7F,0x6D, + 0x4E,0xE0,0x9D,0x84,0x79,0x68,0xC3,0x1B,0xFB,0x89,0x54,0xFB,0x3C,0xEC,0xD1,0xF9, + 0xF1,0xC2,0x57,0xD4,0xBF,0xBE,0xA6,0x22,0xD2,0x84,0xC3,0xC2,0x0E,0x9E,0x0E,0x54, + 0x25,0x79,0x91,0x16,0x4E,0xBC,0x2B,0xD4,0x4F,0x63,0xB3,0x5B,0x7C,0x70,0x91,0xDE, + 0xE2,0x70,0x34,0xB9,0x21,0xB4,0x89,0xF6,0x98,0x12,0x9E,0x38,0xF8,0x36,0x29,0x9D, + 0x0A,0xEC,0xC6,0x69,0xD6,0xC6,0x2E,0xB8,0x38,0x07,0x3F,0xC5,0x52,0x8A,0xEE,0x6F, + 0x20,0xDE,0x62,0xA7,0x85,0xEC,0x05,0x4A,0x15,0x1B,0x3D,0xA6,0x79,0x09,0x76,0xB0, + 0x8B,0xDC,0x13,0xD1,0xD2,0x5E,0xAB,0x65,0x99,0x4D,0xA6,0x49,0x66,0xB8,0x2C,0x77, + 0xAC,0x85,0x71,0xA4,0x69,0x59,0xA6,0xD4,0xAD,0x61,0xA1,0xCE, +}; + +/* subject:/serialNumber=424761419/jurisdictionC=FR/businessCategory=Private Organization/C=FR/postalCode=59100/ST=Nord/L=Roubaix/street=2 rue Kellermann/O=OVH SAS/OU=IT/OU=COMODO EV SSL/CN=ovh.com */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Extended Validation Secure Server CA */ +static unsigned char ovh_certificate[1884]={ + 0x30,0x82,0x07,0x58,0x30,0x82,0x06,0x40,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x40, + 0x46,0x47,0xDC,0xC2,0x4B,0x04,0x42,0xD4,0x89,0x8D,0x08,0x4D,0x4B,0xC2,0x01,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, + 0x92,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B, + 0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72, + 0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06, + 0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30, + 0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43, + 0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x38,0x30,0x36,0x06,0x03,0x55, + 0x04,0x03,0x13,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x45, + 0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69, + 0x6F,0x6E,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72, + 0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,0x34,0x32,0x38,0x30,0x30,0x30, + 0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x34,0x32,0x38,0x32,0x33,0x35,0x39, + 0x35,0x39,0x5A,0x30,0x81,0xEA,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x05,0x13, + 0x09,0x34,0x32,0x34,0x37,0x36,0x31,0x34,0x31,0x39,0x31,0x13,0x30,0x11,0x06,0x0B, + 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x46,0x52,0x31, + 0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0F,0x13,0x14,0x50,0x72,0x69,0x76,0x61,0x74, + 0x65,0x20,0x4F,0x72,0x67,0x61,0x6E,0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,0x31,0x0B, + 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x52,0x31,0x0E,0x30,0x0C,0x06, + 0x03,0x55,0x04,0x11,0x13,0x05,0x35,0x39,0x31,0x30,0x30,0x31,0x0D,0x30,0x0B,0x06, + 0x03,0x55,0x04,0x08,0x13,0x04,0x4E,0x6F,0x72,0x64,0x31,0x10,0x30,0x0E,0x06,0x03, + 0x55,0x04,0x07,0x13,0x07,0x52,0x6F,0x75,0x62,0x61,0x69,0x78,0x31,0x19,0x30,0x17, + 0x06,0x03,0x55,0x04,0x09,0x13,0x10,0x32,0x20,0x72,0x75,0x65,0x20,0x4B,0x65,0x6C, + 0x6C,0x65,0x72,0x6D,0x61,0x6E,0x6E,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A, + 0x13,0x07,0x4F,0x56,0x48,0x20,0x53,0x41,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, + 0x04,0x0B,0x13,0x02,0x49,0x54,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0B,0x13, + 0x0D,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x31,0x10, + 0x30,0x0E,0x06,0x03,0x55,0x04,0x03,0x13,0x07,0x6F,0x76,0x68,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,0x93,0xA1,0x5D,0x05,0x5F,0x1A,0x26,0x56,0x3D,0xDC,0xC2,0x7C,0x1B,0xA1,0x7A, + 0x63,0x16,0x4F,0xBD,0xE0,0x77,0x85,0x04,0xB0,0x9B,0x49,0xE9,0x2B,0x5C,0xB1,0x51, + 0xFD,0x8A,0x14,0x51,0xC7,0xD9,0x50,0xDE,0x64,0x2F,0xFE,0x8C,0x27,0xC3,0x01,0x48, + 0x64,0x7C,0x85,0x3F,0x93,0xD4,0x09,0xE6,0x42,0xDF,0xC1,0xE4,0xEB,0x6A,0xC0,0x87, + 0x90,0xA5,0xF6,0x9C,0xD4,0x6B,0x08,0x77,0xFB,0x56,0x44,0x2B,0x8A,0xE0,0x05,0x73, + 0x14,0x6B,0x02,0x7D,0x76,0x44,0x7B,0x3E,0xA6,0xE5,0x23,0xA9,0xE1,0x8F,0x99,0xDD, + 0x15,0xCD,0xD9,0xD9,0x6D,0xB9,0x95,0x5B,0xE8,0xB6,0xE2,0x52,0xDD,0xF0,0xB0,0x80, + 0x1B,0xC1,0x95,0x4B,0x2C,0x9D,0x5E,0x8D,0x02,0x6B,0x59,0x6C,0x26,0x8B,0xC3,0x19, + 0x0D,0x3E,0xA8,0x34,0xD0,0x43,0x81,0xD7,0xBD,0xB3,0xA7,0x04,0xE1,0x05,0x82,0xA6, + 0x1F,0x4D,0x70,0x67,0x05,0x96,0x88,0xE8,0xE9,0x2E,0x95,0xD2,0x36,0x75,0xD6,0xC8, + 0x0C,0x59,0xBF,0x9F,0x1F,0x9F,0xB4,0xFF,0xF0,0x10,0x8C,0xC3,0xE6,0x8B,0x9F,0xE2, + 0x8E,0x00,0x60,0x58,0xCB,0x6F,0xAD,0x84,0x7B,0xA5,0x36,0xDB,0xB2,0xA4,0xEB,0xC6, + 0xC8,0xD8,0x61,0x6E,0x4A,0xDC,0x5C,0x3E,0x2C,0x33,0xCB,0x1E,0x16,0x8B,0x8C,0xA3, + 0x5F,0x0F,0x30,0x4E,0x0A,0x5D,0xA0,0x53,0x7C,0xCE,0xAB,0x29,0x9A,0xC6,0x64,0xC5, + 0x5A,0xD7,0x94,0x3D,0x81,0xB1,0x05,0x3F,0x2A,0x6D,0xD7,0xB8,0x9D,0xF1,0x6D,0x13, + 0xFD,0x82,0xB4,0xF9,0x88,0x77,0xAB,0xB8,0x2C,0x7A,0x81,0x6E,0x68,0xFF,0x6E,0x04, + 0xC1,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x03,0x4E,0x30,0x82,0x03,0x4A,0x30,0x1F, + 0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x39,0xDA,0xFF,0xCA,0x28, + 0x14,0x8A,0xA8,0x74,0x13,0x08,0xB9,0xE4,0x0E,0xA9,0xD2,0xFA,0x7E,0x9D,0x69,0x30, + 0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x0B,0x0F,0xAD,0xA6,0xC3,0xBF, + 0x98,0xA1,0xEC,0xCD,0x20,0xB3,0x2C,0x75,0x03,0x56,0x3A,0xA6,0xD3,0xE6,0x30,0x0E, + 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x0C, + 0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x1D,0x06,0x03, + 0x55,0x1D,0x25,0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03, + 0x01,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x46,0x06,0x03,0x55, + 0x1D,0x20,0x04,0x3F,0x30,0x3D,0x30,0x3B,0x06,0x0C,0x2B,0x06,0x01,0x04,0x01,0xB2, + 0x31,0x01,0x02,0x01,0x05,0x01,0x30,0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05, + 0x05,0x07,0x02,0x01,0x16,0x1D,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65, + 0x63,0x75,0x72,0x65,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x63,0x6F,0x6D,0x2F, + 0x43,0x50,0x53,0x30,0x56,0x06,0x03,0x55,0x1D,0x1F,0x04,0x4F,0x30,0x4D,0x30,0x4B, + 0xA0,0x49,0xA0,0x47,0x86,0x45,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C, + 0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F, + 0x4D,0x4F,0x44,0x4F,0x52,0x53,0x41,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x56, + 0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x53,0x65,0x63,0x75,0x72,0x65,0x53, + 0x65,0x72,0x76,0x65,0x72,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x81,0x87,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x7B,0x30,0x79,0x30,0x51,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x45,0x68,0x74,0x74,0x70,0x3A,0x2F, + 0x2F,0x63,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F, + 0x6D,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53,0x41,0x45,0x78,0x74,0x65,0x6E, + 0x64,0x65,0x64,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x53,0x65,0x63, + 0x75,0x72,0x65,0x53,0x65,0x72,0x76,0x65,0x72,0x43,0x41,0x2E,0x63,0x72,0x74,0x30, + 0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74, + 0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63, + 0x61,0x2E,0x63,0x6F,0x6D,0x30,0x1F,0x06,0x03,0x55,0x1D,0x11,0x04,0x18,0x30,0x16, + 0x82,0x07,0x6F,0x76,0x68,0x2E,0x63,0x6F,0x6D,0x82,0x0B,0x77,0x77,0x77,0x2E,0x6F, + 0x76,0x68,0x2E,0x63,0x6F,0x6D,0x30,0x82,0x01,0x7E,0x06,0x0A,0x2B,0x06,0x01,0x04, + 0x01,0xD6,0x79,0x02,0x04,0x02,0x04,0x82,0x01,0x6E,0x04,0x82,0x01,0x6A,0x01,0x68, + 0x00,0x76,0x00,0xA4,0xB9,0x09,0x90,0xB4,0x18,0x58,0x14,0x87,0xBB,0x13,0xA2,0xCC, + 0x67,0x70,0x0A,0x3C,0x35,0x98,0x04,0xF9,0x1B,0xDF,0xB8,0xE3,0x77,0xCD,0x0E,0xC8, + 0x0D,0xDC,0x10,0x00,0x00,0x01,0x5B,0xB5,0x7B,0xC8,0x2D,0x00,0x00,0x04,0x03,0x00, + 0x47,0x30,0x45,0x02,0x21,0x00,0xD5,0x1B,0x6C,0xAE,0x75,0x46,0x62,0x0C,0x8B,0x2E, + 0x14,0xB1,0xDE,0x7C,0xA5,0xFE,0x5C,0x4F,0x3E,0xB0,0xFF,0xFF,0x33,0xA2,0x84,0x58, + 0x51,0x57,0x97,0x09,0xAF,0x09,0x02,0x20,0x49,0xD7,0x12,0x12,0x6C,0x2A,0x00,0x21, + 0x5E,0x48,0xF8,0xD0,0xF2,0xA5,0x81,0x2A,0x4E,0xE9,0x22,0x0A,0x4E,0x46,0x8F,0xDB, + 0xA5,0x9C,0x4B,0x43,0x7E,0x51,0x24,0xE4,0x00,0x76,0x00,0x56,0x14,0x06,0x9A,0x2F, + 0xD7,0xC2,0xEC,0xD3,0xF5,0xE1,0xBD,0x44,0xB2,0x3E,0xC7,0x46,0x76,0xB9,0xBC,0x99, + 0x11,0x5C,0xC0,0xEF,0x94,0x98,0x55,0xD6,0x89,0xD0,0xDD,0x00,0x00,0x01,0x5B,0xB5, + 0x7B,0xC5,0xC8,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x20,0x36,0xA9,0x1D, + 0x52,0x63,0x04,0x11,0x1F,0x65,0xC6,0x97,0x7C,0x17,0xFC,0x17,0x8D,0xDB,0x9D,0xA7, + 0xB7,0x84,0x66,0x03,0x55,0x95,0x7D,0x42,0x39,0x98,0x60,0xDE,0x19,0x02,0x21,0x00, + 0x8B,0xB7,0x16,0xC0,0x20,0x17,0xBF,0x31,0x36,0xBD,0xBC,0x1C,0x12,0x61,0x42,0xC0, + 0x5C,0x19,0x97,0x0A,0xFA,0x85,0xDB,0x5D,0xC3,0x65,0xBE,0x18,0xBF,0x89,0x6F,0xB9, + 0x00,0x76,0x00,0xEE,0x4B,0xBD,0xB7,0x75,0xCE,0x60,0xBA,0xE1,0x42,0x69,0x1F,0xAB, + 0xE1,0x9E,0x66,0xA3,0x0F,0x7E,0x5F,0xB0,0x72,0xD8,0x83,0x00,0xC4,0x7B,0x89,0x7A, + 0xA8,0xFD,0xCB,0x00,0x00,0x01,0x5B,0xB5,0x7B,0xC7,0xFA,0x00,0x00,0x04,0x03,0x00, + 0x47,0x30,0x45,0x02,0x21,0x00,0xF8,0xFE,0x02,0xC9,0xAF,0x02,0x18,0xF4,0x12,0x00, + 0x39,0x3C,0x15,0xE0,0x9C,0x78,0x04,0x19,0x55,0xAE,0x8F,0xB4,0x22,0xB9,0x08,0x66, + 0x9E,0x21,0x3E,0xF0,0x7D,0xC6,0x02,0x20,0x47,0x45,0x31,0xC7,0x2C,0xC3,0xBE,0xC7, + 0x5B,0xD8,0x31,0x0A,0xD6,0xAF,0x9D,0xAF,0x04,0x45,0xAA,0x51,0x7D,0x43,0xEF,0x35, + 0x4D,0x81,0xB3,0x0A,0x2F,0x8D,0xD8,0x61,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6C,0x8E,0xB5,0x58, + 0x8A,0xC5,0x66,0xAC,0x99,0x68,0xF9,0x80,0x68,0x8E,0xC5,0x10,0xF7,0xD7,0x37,0x5E, + 0x09,0x8C,0x6B,0xCF,0x30,0x2B,0x98,0x3F,0x76,0x4D,0x69,0xBA,0xE8,0x61,0x1D,0xDE, + 0x1A,0x14,0x4F,0x5A,0x0B,0x54,0x0F,0x66,0xEF,0xB9,0xB3,0x51,0x6C,0x9B,0x86,0x1D, + 0xB9,0x13,0xC8,0x54,0x24,0x6C,0x82,0x6E,0x4B,0x3C,0x53,0xC7,0x7D,0x0B,0x40,0x4A, + 0x7E,0x23,0xF2,0x79,0x6B,0xC3,0xFF,0x9D,0xDF,0xC0,0x16,0x7B,0xFF,0x7B,0x04,0xC9, + 0xE0,0xEB,0x3F,0x28,0xC6,0xD2,0x79,0xEE,0xAE,0x7E,0x38,0x5F,0x0D,0xDF,0x71,0xE7, + 0xAA,0x38,0x7E,0xF3,0x28,0xE8,0xB2,0xAC,0x69,0xB9,0x69,0xD4,0x05,0x8E,0xF1,0x00, + 0x71,0x77,0x97,0x7F,0x94,0x36,0x45,0xE5,0x9C,0x15,0xA3,0xF1,0x40,0xD7,0xB5,0xEA, + 0x95,0x56,0x75,0x60,0x86,0xFB,0xCD,0xB7,0x81,0x5A,0x34,0x1A,0x83,0x1E,0xC2,0x50, + 0xA2,0x57,0x16,0x13,0x53,0x95,0xFA,0x95,0xD0,0x64,0x1E,0x09,0x45,0x50,0x05,0x63, + 0x3A,0x86,0xB2,0x1D,0x9B,0x19,0x0E,0x89,0x7E,0x75,0x17,0xDA,0xC5,0x4D,0x4F,0x71, + 0x55,0x82,0x3E,0x5F,0x41,0x25,0x2F,0x86,0x9E,0x3D,0xF1,0x32,0xFA,0x77,0x7C,0x30, + 0x6C,0x50,0x2F,0xE7,0x11,0x7B,0xE1,0x3F,0xA8,0x2E,0xEF,0xAC,0x36,0x94,0x8F,0xF0, + 0x92,0xB4,0xCA,0x1A,0x53,0x8E,0x12,0x26,0x48,0xC4,0xA8,0x25,0x19,0x96,0x19,0x11, + 0xA2,0xA2,0x48,0xEB,0x8C,0x12,0x59,0x7F,0xCE,0xFC,0x4B,0xC9,0x19,0x10,0x61,0x2B, + 0xB3,0xA6,0x6B,0xB4,0xBA,0x68,0xB9,0x22,0x58,0xE4,0x82,0x27, +}; + +/* This is the cert the ssl server returns to us. */ +/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Extended Validation Secure Server CA */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +static unsigned char comodo_ev_certificate[1554]={ + 0x30,0x82,0x06,0x0E,0x30,0x82,0x03,0xF6,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x06, + 0xA7,0x43,0x80,0xD4,0xEB,0xFE,0xD4,0x35,0xB5,0xA3,0xF7,0xE1,0x6A,0xBD,0xD8,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x30,0x81, + 0x85,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B, + 0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72, + 0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06, + 0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30, + 0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43, + 0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x2B,0x30,0x29,0x06,0x03,0x55, + 0x04,0x03,0x13,0x22,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x43, + 0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74, + 0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x31,0x32,0x30,0x32,0x31,0x32, + 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x37,0x30,0x32,0x31,0x31,0x32, + 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x92,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, + 0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13, + 0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73, + 0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61, + 0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11, + 0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65, + 0x64,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2F,0x43,0x4F,0x4D,0x4F, + 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20, + 0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x63,0x75,0x72, + 0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,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,0x95,0x56,0xDE,0x54, + 0xB4,0xDF,0xD5,0x02,0x49,0x7B,0xD1,0x5B,0x5C,0xA2,0xB2,0x1E,0x8F,0x9C,0x2B,0x62, + 0x4C,0x2B,0x8D,0x12,0x28,0xF3,0x1A,0x95,0xA3,0xC6,0x10,0xFD,0x29,0xDE,0xE1,0x9F, + 0x0B,0x38,0x40,0x93,0xD1,0xEF,0x6E,0x95,0x10,0xFC,0xE1,0x90,0x17,0x77,0x2C,0xEE, + 0x75,0x3E,0x7B,0x63,0xEC,0x61,0x92,0x6E,0x4F,0x3B,0xAB,0x80,0x49,0x6B,0xDF,0x00, + 0xEA,0x03,0x00,0x7F,0x2F,0x75,0xD5,0x28,0x2F,0xEC,0x56,0x67,0x8F,0x80,0x83,0xA3, + 0xBD,0xDC,0x03,0x99,0x93,0x8B,0x94,0x91,0x56,0x5B,0xA1,0xB8,0x6A,0x3A,0x3F,0x06, + 0xBD,0x0E,0x92,0xCC,0x60,0x9C,0xFD,0xB5,0xE0,0x9F,0x66,0x30,0x5F,0xDB,0xE6,0x94, + 0xF0,0x95,0x6A,0xAF,0xC8,0x8A,0xAF,0x80,0xD9,0xE6,0x88,0x39,0x01,0x7C,0x1C,0xC0, + 0xC5,0x2A,0xF7,0x7B,0x95,0xA0,0xF2,0x76,0xAB,0x6D,0x9B,0x72,0x39,0x30,0xEB,0xD1, + 0x57,0x55,0x01,0x9D,0x58,0x11,0x9D,0x7C,0x6D,0x84,0x8F,0x49,0xE8,0x9D,0x09,0xFC, + 0x3C,0xFD,0x0A,0x4A,0x76,0x14,0x21,0x5C,0x16,0x73,0x40,0x23,0x19,0x74,0xC3,0xBA, + 0x58,0x0A,0xA6,0x96,0x2E,0xDE,0x36,0xE5,0x9F,0xD0,0xC2,0xF0,0xE1,0xE0,0xC1,0x62, + 0xE3,0xC2,0x18,0x45,0x19,0x51,0xAA,0x17,0x1E,0xE8,0x23,0x75,0xD4,0xC8,0xD0,0x96, + 0x13,0xFF,0xC7,0x24,0xD1,0x8C,0x0B,0x27,0xAE,0x9E,0x7A,0xDC,0x3A,0x61,0x63,0x60, + 0x88,0x97,0x2D,0x5D,0x05,0x0B,0xE5,0x3B,0xEB,0xAE,0xCE,0x3A,0x47,0x73,0x76,0xA8, + 0xFA,0x2C,0xDD,0xC0,0x87,0x17,0xE9,0xAC,0x30,0x99,0xF8,0x1F,0x02,0x03,0x01,0x00, + 0x01,0xA3,0x82,0x01,0x69,0x30,0x82,0x01,0x65,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0xBB,0xAF,0x7E,0x02,0x3D,0xFA,0xA6,0xF1,0x3C,0x84, + 0x8E,0xAD,0xEE,0x38,0x98,0xEC,0xD9,0x32,0x32,0xD4,0x30,0x1D,0x06,0x03,0x55,0x1D, + 0x0E,0x04,0x16,0x04,0x14,0x39,0xDA,0xFF,0xCA,0x28,0x14,0x8A,0xA8,0x74,0x13,0x08, + 0xB9,0xE4,0x0E,0xA9,0xD2,0xFA,0x7E,0x9D,0x69,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F, + 0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13, + 0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x3E,0x06, + 0x03,0x55,0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00, + 0x30,0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D, + 0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63, + 0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x50,0x53,0x30,0x4C,0x06, + 0x03,0x55,0x1D,0x1F,0x04,0x45,0x30,0x43,0x30,0x41,0xA0,0x3F,0xA0,0x3D,0x86,0x3B, + 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64, + 0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53, + 0x41,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x41,0x75, + 0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x2E,0x63,0x72,0x6C,0x30,0x71,0x06,0x08,0x2B, + 0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x65,0x30,0x63,0x30,0x3B,0x06,0x08,0x2B, + 0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x2F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, + 0x63,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D, + 0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53,0x41,0x41,0x64,0x64,0x54,0x72,0x75, + 0x73,0x74,0x43,0x41,0x2E,0x63,0x72,0x74,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05, + 0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73, + 0x70,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x30,0x0D, + 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x03,0x82,0x02, + 0x01,0x00,0x44,0x42,0x9D,0x41,0x51,0x2B,0x48,0x88,0x5D,0x97,0x9B,0x79,0x5E,0x11, + 0x01,0x4A,0x52,0x19,0x7B,0x41,0x2C,0xC7,0x89,0x3C,0xD0,0x72,0xDC,0x85,0xFA,0x58, + 0xAF,0xD5,0x25,0xE4,0x13,0xF8,0x58,0x65,0x67,0x9F,0x0D,0xFF,0x57,0x8B,0xA9,0x85, + 0x5E,0xCA,0xA6,0x4B,0xB0,0xA7,0xB2,0x2D,0xE0,0x8C,0x22,0xCD,0xFB,0xFF,0x79,0xA4, + 0x8C,0x2B,0x8D,0xFE,0x02,0x3D,0x24,0xDE,0xA9,0x5D,0x5F,0xE4,0x0F,0x47,0xD0,0xDB, + 0x66,0x25,0x3E,0x87,0x47,0x0C,0xAE,0x22,0xC5,0x50,0x22,0x84,0xD7,0xED,0x4A,0x59, + 0x1A,0xF6,0x93,0xA5,0x93,0xB0,0xE0,0x1B,0x81,0xF2,0x56,0xC4,0xC8,0x10,0x53,0xE4, + 0xD4,0x76,0xB1,0xD1,0x5B,0x69,0x4B,0x77,0xB2,0xE0,0x4F,0xC4,0x84,0xE7,0xD4,0xA0, + 0x50,0xEE,0x3C,0xFA,0x44,0xFC,0xD0,0x57,0xB9,0xE1,0x28,0x53,0xFD,0x53,0xCD,0xDC, + 0xB9,0x1F,0x7A,0x40,0xBD,0x30,0x3F,0xD8,0x6C,0xD2,0xF3,0xE7,0x07,0x9F,0x1F,0x22, + 0xB5,0xEA,0x22,0x71,0xCB,0x2A,0xF0,0x56,0x7C,0xFE,0xAC,0xA8,0xD1,0x06,0x0F,0x14, + 0x14,0x52,0x4C,0xFE,0x64,0x2B,0x0C,0x69,0x2A,0xB8,0x0D,0x50,0x6E,0x3E,0x04,0x07, + 0xBF,0x7A,0x20,0x8B,0xF8,0xEE,0x65,0x09,0xE1,0xC7,0x49,0x08,0x32,0x3D,0x0D,0x28, + 0x7E,0x49,0x1D,0xB7,0x4A,0xEF,0x02,0xE7,0x0D,0x80,0x17,0xC8,0x5C,0xE0,0x61,0x62, + 0xCB,0xEC,0xB3,0x60,0x79,0x25,0xDA,0x1A,0x65,0x73,0x9C,0x38,0x10,0xA0,0x26,0x3A, + 0xB0,0xC8,0x16,0x7D,0x93,0x31,0x22,0xEE,0x74,0x0B,0x88,0xC0,0x5C,0x89,0x41,0x00, + 0x28,0xA9,0x47,0x31,0xDF,0x7D,0x49,0x45,0x9A,0xF5,0xE6,0xA7,0x45,0x1A,0xD2,0x8E, + 0x13,0x10,0xDF,0x83,0xAF,0x9B,0x0D,0xAD,0x7E,0x7E,0x9D,0x35,0x50,0x34,0x04,0xCE, + 0xE9,0x20,0xD6,0x9E,0xDB,0x9D,0xD4,0xA8,0xDA,0x64,0xB4,0xD1,0x2F,0x59,0x2E,0x5E, + 0xA2,0x36,0x61,0xD4,0x24,0xA0,0x82,0x33,0x33,0x8A,0xA1,0xD1,0x6C,0xEF,0x61,0x68, + 0xA3,0xE5,0xD2,0x56,0xAD,0xC5,0xFD,0x5E,0x62,0xEB,0x15,0xA8,0x74,0x12,0x4C,0x2F, + 0x31,0x8C,0xE9,0xC1,0xDF,0x10,0x4B,0x01,0xEA,0xF6,0x54,0x1B,0xCD,0x7F,0x3B,0xBD, + 0x5C,0x9F,0xC1,0xDB,0xCF,0x01,0xCA,0xF2,0xBA,0x60,0x12,0x21,0x31,0xED,0xA9,0x64, + 0xB8,0xB2,0x49,0x58,0x17,0x6D,0x5A,0xD7,0xCD,0x8C,0x6D,0xBE,0x9E,0x7F,0xE2,0x02, + 0x58,0xA7,0xDB,0xC3,0x2D,0x58,0xF6,0x74,0x06,0x6A,0x9A,0xF6,0x61,0xF9,0xF6,0x00, + 0xB6,0x69,0xD8,0x3A,0x8B,0x31,0x59,0xDD,0x91,0xE6,0x7C,0x27,0x23,0x87,0xDD,0x03, + 0x0F,0x8F,0x2A,0x8C,0x1E,0x83,0x01,0x4E,0x01,0x61,0x0C,0x52,0x73,0x6D,0xFC,0x08, + 0xA2,0xB9,0x2A,0x66,0xE4,0x76,0x4D,0x31,0xA0,0x56,0x9B,0xD9,0x53,0x8D,0xA2,0xB6, + 0x8F,0x02,0xC8,0xE6,0x3A,0xA6,0x04,0xD1,0x48,0xFB,0xC3,0x4A,0x02,0x76,0xFD,0x2F, + 0xD2,0xBC,0x13,0xB6,0xE8,0x6D,0x34,0x24,0xFA,0x9D,0x29,0x8A,0xC7,0xA1,0x2B,0x14, + 0xF1,0x96,0x00,0x73,0xB9,0x13,0xE9,0xC0,0xB9,0x3A,0x47,0x56,0x02,0x71,0x80,0x27, + 0xA4,0xBC,0x25,0xB6,0xE9,0xBD,0xE4,0xE9,0x98,0x74,0x16,0xF1,0x37,0x84,0x81,0x07, + 0xB4,0x82, +}; + +/* This is the cert we get when we get the url in the AIA extension of the ovh leaf. */ +/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Extended Validation Secure Server CA */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +static unsigned char comodo_aia_certificate[1554]={ + 0x30,0x82,0x06,0x0E,0x30,0x82,0x03,0xF6,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x06, + 0xA7,0x43,0x80,0xD4,0xEB,0xFE,0xD4,0x35,0xB5,0xA3,0xF7,0xE1,0x6A,0xBD,0xD8,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x30,0x81, + 0x85,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B, + 0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72, + 0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06, + 0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30, + 0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43, + 0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x2B,0x30,0x29,0x06,0x03,0x55, + 0x04,0x03,0x13,0x22,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x43, + 0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74, + 0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x31,0x32,0x30,0x32,0x31,0x32, + 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x37,0x30,0x32,0x31,0x31,0x32, + 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x92,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, + 0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13, + 0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73, + 0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61, + 0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11, + 0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65, + 0x64,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2F,0x43,0x4F,0x4D,0x4F, + 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20, + 0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x63,0x75,0x72, + 0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,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,0x95,0x56,0xDE,0x54, + 0xB4,0xDF,0xD5,0x02,0x49,0x7B,0xD1,0x5B,0x5C,0xA2,0xB2,0x1E,0x8F,0x9C,0x2B,0x62, + 0x4C,0x2B,0x8D,0x12,0x28,0xF3,0x1A,0x95,0xA3,0xC6,0x10,0xFD,0x29,0xDE,0xE1,0x9F, + 0x0B,0x38,0x40,0x93,0xD1,0xEF,0x6E,0x95,0x10,0xFC,0xE1,0x90,0x17,0x77,0x2C,0xEE, + 0x75,0x3E,0x7B,0x63,0xEC,0x61,0x92,0x6E,0x4F,0x3B,0xAB,0x80,0x49,0x6B,0xDF,0x00, + 0xEA,0x03,0x00,0x7F,0x2F,0x75,0xD5,0x28,0x2F,0xEC,0x56,0x67,0x8F,0x80,0x83,0xA3, + 0xBD,0xDC,0x03,0x99,0x93,0x8B,0x94,0x91,0x56,0x5B,0xA1,0xB8,0x6A,0x3A,0x3F,0x06, + 0xBD,0x0E,0x92,0xCC,0x60,0x9C,0xFD,0xB5,0xE0,0x9F,0x66,0x30,0x5F,0xDB,0xE6,0x94, + 0xF0,0x95,0x6A,0xAF,0xC8,0x8A,0xAF,0x80,0xD9,0xE6,0x88,0x39,0x01,0x7C,0x1C,0xC0, + 0xC5,0x2A,0xF7,0x7B,0x95,0xA0,0xF2,0x76,0xAB,0x6D,0x9B,0x72,0x39,0x30,0xEB,0xD1, + 0x57,0x55,0x01,0x9D,0x58,0x11,0x9D,0x7C,0x6D,0x84,0x8F,0x49,0xE8,0x9D,0x09,0xFC, + 0x3C,0xFD,0x0A,0x4A,0x76,0x14,0x21,0x5C,0x16,0x73,0x40,0x23,0x19,0x74,0xC3,0xBA, + 0x58,0x0A,0xA6,0x96,0x2E,0xDE,0x36,0xE5,0x9F,0xD0,0xC2,0xF0,0xE1,0xE0,0xC1,0x62, + 0xE3,0xC2,0x18,0x45,0x19,0x51,0xAA,0x17,0x1E,0xE8,0x23,0x75,0xD4,0xC8,0xD0,0x96, + 0x13,0xFF,0xC7,0x24,0xD1,0x8C,0x0B,0x27,0xAE,0x9E,0x7A,0xDC,0x3A,0x61,0x63,0x60, + 0x88,0x97,0x2D,0x5D,0x05,0x0B,0xE5,0x3B,0xEB,0xAE,0xCE,0x3A,0x47,0x73,0x76,0xA8, + 0xFA,0x2C,0xDD,0xC0,0x87,0x17,0xE9,0xAC,0x30,0x99,0xF8,0x1F,0x02,0x03,0x01,0x00, + 0x01,0xA3,0x82,0x01,0x69,0x30,0x82,0x01,0x65,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0xBB,0xAF,0x7E,0x02,0x3D,0xFA,0xA6,0xF1,0x3C,0x84, + 0x8E,0xAD,0xEE,0x38,0x98,0xEC,0xD9,0x32,0x32,0xD4,0x30,0x1D,0x06,0x03,0x55,0x1D, + 0x0E,0x04,0x16,0x04,0x14,0x39,0xDA,0xFF,0xCA,0x28,0x14,0x8A,0xA8,0x74,0x13,0x08, + 0xB9,0xE4,0x0E,0xA9,0xD2,0xFA,0x7E,0x9D,0x69,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F, + 0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13, + 0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x3E,0x06, + 0x03,0x55,0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00, + 0x30,0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D, + 0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63, + 0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x50,0x53,0x30,0x4C,0x06, + 0x03,0x55,0x1D,0x1F,0x04,0x45,0x30,0x43,0x30,0x41,0xA0,0x3F,0xA0,0x3D,0x86,0x3B, + 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64, + 0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53, + 0x41,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x41,0x75, + 0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x2E,0x63,0x72,0x6C,0x30,0x71,0x06,0x08,0x2B, + 0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x65,0x30,0x63,0x30,0x3B,0x06,0x08,0x2B, + 0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x2F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, + 0x63,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D, + 0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53,0x41,0x41,0x64,0x64,0x54,0x72,0x75, + 0x73,0x74,0x43,0x41,0x2E,0x63,0x72,0x74,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05, + 0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73, + 0x70,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x30,0x0D, + 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x03,0x82,0x02, + 0x01,0x00,0x44,0x42,0x9D,0x41,0x51,0x2B,0x48,0x88,0x5D,0x97,0x9B,0x79,0x5E,0x11, + 0x01,0x4A,0x52,0x19,0x7B,0x41,0x2C,0xC7,0x89,0x3C,0xD0,0x72,0xDC,0x85,0xFA,0x58, + 0xAF,0xD5,0x25,0xE4,0x13,0xF8,0x58,0x65,0x67,0x9F,0x0D,0xFF,0x57,0x8B,0xA9,0x85, + 0x5E,0xCA,0xA6,0x4B,0xB0,0xA7,0xB2,0x2D,0xE0,0x8C,0x22,0xCD,0xFB,0xFF,0x79,0xA4, + 0x8C,0x2B,0x8D,0xFE,0x02,0x3D,0x24,0xDE,0xA9,0x5D,0x5F,0xE4,0x0F,0x47,0xD0,0xDB, + 0x66,0x25,0x3E,0x87,0x47,0x0C,0xAE,0x22,0xC5,0x50,0x22,0x84,0xD7,0xED,0x4A,0x59, + 0x1A,0xF6,0x93,0xA5,0x93,0xB0,0xE0,0x1B,0x81,0xF2,0x56,0xC4,0xC8,0x10,0x53,0xE4, + 0xD4,0x76,0xB1,0xD1,0x5B,0x69,0x4B,0x77,0xB2,0xE0,0x4F,0xC4,0x84,0xE7,0xD4,0xA0, + 0x50,0xEE,0x3C,0xFA,0x44,0xFC,0xD0,0x57,0xB9,0xE1,0x28,0x53,0xFD,0x53,0xCD,0xDC, + 0xB9,0x1F,0x7A,0x40,0xBD,0x30,0x3F,0xD8,0x6C,0xD2,0xF3,0xE7,0x07,0x9F,0x1F,0x22, + 0xB5,0xEA,0x22,0x71,0xCB,0x2A,0xF0,0x56,0x7C,0xFE,0xAC,0xA8,0xD1,0x06,0x0F,0x14, + 0x14,0x52,0x4C,0xFE,0x64,0x2B,0x0C,0x69,0x2A,0xB8,0x0D,0x50,0x6E,0x3E,0x04,0x07, + 0xBF,0x7A,0x20,0x8B,0xF8,0xEE,0x65,0x09,0xE1,0xC7,0x49,0x08,0x32,0x3D,0x0D,0x28, + 0x7E,0x49,0x1D,0xB7,0x4A,0xEF,0x02,0xE7,0x0D,0x80,0x17,0xC8,0x5C,0xE0,0x61,0x62, + 0xCB,0xEC,0xB3,0x60,0x79,0x25,0xDA,0x1A,0x65,0x73,0x9C,0x38,0x10,0xA0,0x26,0x3A, + 0xB0,0xC8,0x16,0x7D,0x93,0x31,0x22,0xEE,0x74,0x0B,0x88,0xC0,0x5C,0x89,0x41,0x00, + 0x28,0xA9,0x47,0x31,0xDF,0x7D,0x49,0x45,0x9A,0xF5,0xE6,0xA7,0x45,0x1A,0xD2,0x8E, + 0x13,0x10,0xDF,0x83,0xAF,0x9B,0x0D,0xAD,0x7E,0x7E,0x9D,0x35,0x50,0x34,0x04,0xCE, + 0xE9,0x20,0xD6,0x9E,0xDB,0x9D,0xD4,0xA8,0xDA,0x64,0xB4,0xD1,0x2F,0x59,0x2E,0x5E, + 0xA2,0x36,0x61,0xD4,0x24,0xA0,0x82,0x33,0x33,0x8A,0xA1,0xD1,0x6C,0xEF,0x61,0x68, + 0xA3,0xE5,0xD2,0x56,0xAD,0xC5,0xFD,0x5E,0x62,0xEB,0x15,0xA8,0x74,0x12,0x4C,0x2F, + 0x31,0x8C,0xE9,0xC1,0xDF,0x10,0x4B,0x01,0xEA,0xF6,0x54,0x1B,0xCD,0x7F,0x3B,0xBD, + 0x5C,0x9F,0xC1,0xDB,0xCF,0x01,0xCA,0xF2,0xBA,0x60,0x12,0x21,0x31,0xED,0xA9,0x64, + 0xB8,0xB2,0x49,0x58,0x17,0x6D,0x5A,0xD7,0xCD,0x8C,0x6D,0xBE,0x9E,0x7F,0xE2,0x02, + 0x58,0xA7,0xDB,0xC3,0x2D,0x58,0xF6,0x74,0x06,0x6A,0x9A,0xF6,0x61,0xF9,0xF6,0x00, + 0xB6,0x69,0xD8,0x3A,0x8B,0x31,0x59,0xDD,0x91,0xE6,0x7C,0x27,0x23,0x87,0xDD,0x03, + 0x0F,0x8F,0x2A,0x8C,0x1E,0x83,0x01,0x4E,0x01,0x61,0x0C,0x52,0x73,0x6D,0xFC,0x08, + 0xA2,0xB9,0x2A,0x66,0xE4,0x76,0x4D,0x31,0xA0,0x56,0x9B,0xD9,0x53,0x8D,0xA2,0xB6, + 0x8F,0x02,0xC8,0xE6,0x3A,0xA6,0x04,0xD1,0x48,0xFB,0xC3,0x4A,0x02,0x76,0xFD,0x2F, + 0xD2,0xBC,0x13,0xB6,0xE8,0x6D,0x34,0x24,0xFA,0x9D,0x29,0x8A,0xC7,0xA1,0x2B,0x14, + 0xF1,0x96,0x00,0x73,0xB9,0x13,0xE9,0xC0,0xB9,0x3A,0x47,0x56,0x02,0x71,0x80,0x27, + 0xA4,0xBC,0x25,0xB6,0xE9,0xBD,0xE4,0xE9,0x98,0x74,0x16,0xF1,0x37,0x84,0x81,0x07, + 0xB4,0x82, +}; + +static unsigned char revoked_ist_certificate[1515]={ + 0x30,0x82,0x05,0xE7,0x30,0x82,0x04,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x7F, + 0x00,0xCE,0x8A,0xD6,0x3F,0x5B,0x34,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x62,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04, + 0x03,0x13,0x13,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x53,0x54,0x20,0x43,0x41,0x20, + 0x32,0x20,0x2D,0x20,0x47,0x31,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0B,0x13, + 0x17,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,0x13,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,0x34, + 0x31,0x31,0x32,0x38,0x31,0x35,0x30,0x36,0x31,0x34,0x5A,0x17,0x0D,0x31,0x36,0x31, + 0x32,0x32,0x37,0x31,0x35,0x30,0x36,0x31,0x34,0x5A,0x30,0x81,0xAB,0x31,0x4B,0x30, + 0x49,0x06,0x03,0x55,0x04,0x03,0x0C,0x42,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E, + 0x67,0x65,0x6F,0x74,0x72,0x75,0x73,0x74,0x2D,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2D, + 0x63,0x61,0x2E,0x74,0x65,0x73,0x74,0x2D,0x70,0x61,0x67,0x65,0x73,0x2E,0x63,0x65, + 0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x6D,0x61,0x6E,0x61,0x67,0x65,0x72, + 0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x31,0x25,0x30,0x23,0x06,0x03, + 0x55,0x04,0x0B,0x0C,0x1C,0x6D,0x61,0x6E,0x61,0x67,0x65,0x6D,0x65,0x6E,0x74,0x3A, + 0x69,0x64,0x6D,0x73,0x2E,0x67,0x72,0x6F,0x75,0x70,0x2E,0x31,0x37,0x36,0x33,0x39, + 0x39,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C, + 0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C, + 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x0B,0x30,0x09,0x06, + 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,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,0xA9,0xD7,0xE0,0x65,0x48,0x36,0x8A, + 0x4B,0x6C,0xBB,0x16,0xAF,0xFD,0x09,0xA5,0x9C,0x30,0xDA,0xC5,0x9B,0x3D,0xD6,0xB4, + 0x8E,0x6B,0xC2,0xF4,0xBF,0x30,0xA7,0xCC,0xF7,0xA1,0x23,0x58,0xA0,0x16,0xE8,0x31, + 0x5F,0xE7,0xD2,0x21,0x3D,0x24,0x3D,0xF4,0x1E,0x82,0x46,0x45,0xA0,0xB8,0x2E,0xD7, + 0xB6,0x86,0xD3,0x2A,0xBC,0x93,0x74,0x44,0xAB,0x1C,0x9F,0x86,0xBF,0x19,0xCE,0xA4, + 0xD0,0xC9,0xB9,0x65,0x84,0x89,0x87,0xDE,0x77,0xDC,0xAE,0x85,0xA9,0xDE,0x5A,0xCF, + 0xAF,0x46,0x80,0x45,0x72,0x68,0x87,0x55,0x5B,0x4D,0x49,0xE2,0x7B,0x25,0x31,0x22, + 0x00,0x87,0xAB,0x72,0xEB,0x9A,0x2D,0x81,0x35,0x0E,0x76,0x82,0x5C,0x99,0x10,0xFB, + 0xD6,0x3F,0x29,0xE8,0xFD,0x2E,0xAD,0xF6,0xF8,0xCF,0xC1,0x99,0x5F,0xDA,0xC1,0xB3, + 0x90,0x70,0xA5,0x4B,0x23,0x4D,0xD6,0x1D,0xC9,0x73,0x27,0xD1,0xAE,0x38,0xA3,0xD0, + 0x71,0x92,0xFF,0x89,0xA8,0xE5,0x51,0x3E,0x2F,0xB6,0xB4,0x02,0x20,0x54,0x62,0xA0, + 0x69,0x6D,0xB6,0x10,0x8D,0xB7,0x13,0x2A,0x94,0x4E,0xED,0x73,0x8C,0x78,0x39,0xF6, + 0x04,0xC0,0xF8,0x7A,0x75,0x2D,0x1E,0x82,0x7E,0x55,0x7B,0xE7,0xA7,0xFA,0x6E,0xB1, + 0x53,0x81,0x75,0xB6,0x19,0xD8,0xD2,0xD3,0x8E,0x30,0x95,0x0D,0xD8,0xC9,0xBA,0x3F, + 0x70,0x23,0xC3,0x7B,0xE2,0x6E,0xA9,0xA8,0x91,0x69,0x89,0x8D,0xEA,0x64,0x5D,0x8E, + 0x49,0x43,0x30,0x99,0xBC,0x54,0x97,0xAC,0xEB,0x98,0x09,0x8C,0xE9,0xA7,0xE8,0xDC, + 0xFC,0xE4,0xBE,0x20,0xDA,0xA1,0x88,0xB6,0x99,0x02,0x03,0x01,0x00,0x01,0xA3,0x82, + 0x02,0x55,0x30,0x82,0x02,0x51,0x30,0x48,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, + 0x01,0x01,0x04,0x3C,0x30,0x3A,0x30,0x38,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, + 0x30,0x01,0x86,0x2C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E, + 0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x6F,0x63,0x73,0x70,0x30,0x34, + 0x2D,0x61,0x70,0x70,0x6C,0x65,0x69,0x73,0x74,0x63,0x61,0x32,0x67,0x31,0x30,0x31, + 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x75,0x81,0x7F,0xDF,0xDE, + 0x90,0xE2,0xFB,0x67,0xA8,0x04,0xC9,0x82,0xE1,0x2A,0x13,0x08,0x3D,0xCE,0x8E,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,0xD8,0x7A,0x94,0x44,0x7C,0x90, + 0x70,0x90,0x16,0x9E,0xDD,0x17,0x9C,0x01,0x44,0x03,0x86,0xD6,0x2A,0x29,0x30,0x81, + 0xFF,0x06,0x03,0x55,0x1D,0x20,0x04,0x81,0xF7,0x30,0x81,0xF4,0x30,0x81,0xF1,0x06, + 0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x0B,0x04,0x30,0x81,0xE2,0x30,0x81, + 0xA4,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x81,0x97,0x0C,0x81, + 0x94,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,0x61,0x73,0x73,0x75,0x6D, + 0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,0x74,0x61,0x6E,0x63,0x65,0x20,0x6F,0x66, + 0x20,0x61,0x6E,0x79,0x20,0x61,0x70,0x70,0x6C,0x69,0x63,0x61,0x62,0x6C,0x65,0x20, + 0x74,0x65,0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,0x6E,0x64,0x69,0x74, + 0x69,0x6F,0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x6E,0x64,0x2F, + 0x6F,0x72,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E, + 0x20,0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x73,0x74,0x61,0x74,0x65,0x6D, + 0x65,0x6E,0x74,0x73,0x2E,0x30,0x39,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02, + 0x01,0x16,0x2D,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,0x72,0x70,0x61, + 0x30,0x37,0x06,0x03,0x55,0x1D,0x1F,0x04,0x30,0x30,0x2E,0x30,0x2C,0xA0,0x2A,0xA0, + 0x28,0x86,0x26,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x61,0x70, + 0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70,0x6C,0x65,0x69,0x73,0x74, + 0x63,0x61,0x32,0x67,0x31,0x2E,0x63,0x72,0x6C,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F, + 0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55,0x1D,0x25, + 0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x4D,0x06,0x03,0x55,0x1D,0x11,0x04, + 0x46,0x30,0x44,0x82,0x42,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,0x67,0x65,0x6F, + 0x74,0x72,0x75,0x73,0x74,0x2D,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2D,0x63,0x61,0x2E, + 0x74,0x65,0x73,0x74,0x2D,0x70,0x61,0x67,0x65,0x73,0x2E,0x63,0x65,0x72,0x74,0x69, + 0x66,0x69,0x63,0x61,0x74,0x65,0x6D,0x61,0x6E,0x61,0x67,0x65,0x72,0x2E,0x61,0x70, + 0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xC0,0x5B,0xA6,0xAF,0x2C, + 0x27,0xBA,0x49,0x8D,0x41,0xF6,0xC4,0x02,0xEE,0x9D,0xB1,0x48,0xC3,0x34,0x7B,0xF2, + 0xD2,0x82,0x49,0xA5,0x13,0x5A,0x66,0xAD,0xC9,0x73,0xBF,0x6B,0xC9,0x30,0x86,0xBA, + 0x7A,0xD2,0x9D,0x61,0xFE,0x04,0x07,0x15,0x66,0xC2,0x25,0xF7,0x6C,0x88,0xB1,0x0E, + 0x22,0x11,0xF9,0x26,0xA7,0x4E,0x88,0x96,0x20,0x99,0xA6,0x51,0xEE,0x02,0x96,0xC7, + 0xA4,0xCA,0xD4,0xAB,0xFC,0x5F,0x96,0x16,0x0D,0x8D,0xA0,0xA1,0x17,0x6E,0x77,0x92, + 0xC9,0x64,0xD9,0xA2,0x5A,0x00,0x08,0xA6,0x55,0x73,0x2C,0xDD,0xD3,0x0C,0xA5,0xCA, + 0x68,0x48,0xAE,0xCE,0x5F,0xF2,0x56,0x4A,0x66,0x57,0xB2,0x2D,0xB5,0xC6,0xFF,0x50, + 0xD8,0x36,0x9C,0x31,0x31,0xE8,0xB2,0x07,0xE2,0x7B,0xC0,0xCE,0x72,0xA4,0x60,0x91, + 0xBB,0x84,0xA7,0xA8,0xC0,0x1D,0x42,0xE8,0x1D,0xF5,0xD9,0x6B,0x85,0x67,0x23,0x20, + 0xA6,0xF8,0x0F,0xBA,0x83,0x63,0x49,0xE2,0x79,0x23,0x90,0xFF,0x6B,0xEF,0xFA,0xB4, + 0x04,0xA8,0x99,0x1E,0x5D,0x5A,0xCD,0x8C,0xBC,0x8E,0x30,0x41,0x7E,0xE7,0x4E,0xDB, + 0x6F,0x4E,0xB7,0xBA,0xE0,0x5B,0x31,0xC4,0xD2,0x2D,0xD3,0x5D,0x82,0x95,0x44,0x7D, + 0x11,0x60,0x75,0xCE,0x6D,0x12,0xDA,0x89,0x71,0x23,0x80,0x75,0xC0,0x13,0x67,0x27, + 0xE8,0xE8,0xCA,0xE0,0xE3,0xFC,0x72,0x23,0x98,0xFA,0xF0,0x96,0x05,0x23,0xC9,0x03, + 0xC8,0x29,0xA4,0xB1,0xE5,0x07,0xE6,0xE8,0x09,0x26,0xD1,0x8C,0xAF,0xE0,0x53,0xBB, + 0xB4,0x1E,0x4D,0x5E,0xEA,0x9A,0x1E,0xE9,0x42,0x87,0x9F, +}; + +static unsigned char ist_intermediate_certificate[1092]={ + 0x30,0x82,0x04,0x40,0x30,0x82,0x03,0x28,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x02, + 0x3A,0x74,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x42,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72, + 0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04, + 0x03,0x13,0x12,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62, + 0x61,0x6C,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x34,0x30,0x36,0x31,0x36,0x31, + 0x35,0x34,0x32,0x30,0x32,0x5A,0x17,0x0D,0x32,0x32,0x30,0x35,0x32,0x30,0x31,0x35, + 0x34,0x32,0x30,0x32,0x5A,0x30,0x62,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03, + 0x13,0x13,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x53,0x54,0x20,0x43,0x41,0x20,0x32, + 0x20,0x2D,0x20,0x47,0x31,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,0x17, + 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, + 0x13,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,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,0xD0,0x93,0xA1,0x1D,0x47,0x43, + 0x20,0x16,0xB2,0x0B,0x6B,0xEB,0xC3,0xD5,0xB4,0xE8,0xC7,0x98,0xCD,0xF3,0xDE,0xBF, + 0xE8,0x4D,0xE9,0xE3,0x36,0x80,0x07,0xFC,0x45,0x1B,0x6A,0x7C,0x45,0x86,0xAE,0x56, + 0xD3,0xA4,0x09,0x7F,0x61,0x0D,0x6B,0x5D,0x7E,0x52,0x6B,0x7D,0xB4,0xC8,0x39,0xC4, + 0xF4,0x67,0x3A,0xF7,0x83,0xCE,0x19,0x6F,0x86,0x2F,0x7E,0x45,0x7E,0x47,0x1C,0x67, + 0x52,0xCA,0x95,0x05,0x5D,0xE2,0x36,0x51,0x85,0xC0,0xD4,0x67,0x80,0x35,0x6F,0x15, + 0xDD,0x3E,0xFD,0x1D,0xD2,0xFD,0x8F,0x34,0x50,0xD8,0xEC,0x76,0x2A,0xBE,0xE3,0xD3, + 0xDA,0xE4,0xFD,0xC8,0xEB,0x28,0x02,0x96,0x11,0x97,0x17,0x61,0x1C,0xE9,0xC4,0x59, + 0x3B,0x42,0xDC,0x32,0xD1,0x09,0x1D,0xDA,0xA6,0xD1,0x43,0x86,0xFF,0x5E,0xB2,0xBC, + 0x8C,0xCF,0x66,0xDB,0x01,0x8B,0x02,0xAE,0x94,0x48,0xF3,0x38,0x8F,0xFD,0xEA,0x32, + 0xA8,0x08,0xEC,0x86,0x97,0x51,0x94,0x24,0x3E,0x49,0x49,0x96,0x53,0xE8,0x79,0xA1, + 0x40,0x81,0xE9,0x05,0xBB,0x93,0x95,0x51,0xFC,0xE3,0xFD,0x7C,0x11,0x4B,0xF7,0x9E, + 0x08,0xB3,0x15,0x49,0x15,0x07,0xF9,0xD1,0x37,0xA0,0x9B,0x4B,0x32,0xF6,0xB5,0xC4, + 0xDC,0x6A,0xD1,0xFC,0x0A,0xED,0xF6,0xE0,0xC5,0x29,0xA0,0xA8,0x8B,0x71,0xFE,0x0D, + 0x92,0xBC,0xFE,0x54,0x70,0x18,0x0A,0x6D,0xC7,0xED,0x0C,0xFB,0xC9,0x2D,0x06,0xC3, + 0x8C,0x85,0xFC,0xCB,0x86,0x5C,0xD6,0x36,0x8E,0x12,0x8B,0x09,0x7F,0xFB,0x19,0x1A, + 0x38,0xD5,0xF0,0x94,0x30,0x7A,0x0F,0xA6,0x8C,0xF3,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x82,0x01,0x1D,0x30,0x82,0x01,0x19,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, + 0x30,0x16,0x80,0x14,0xC0,0x7A,0x98,0x68,0x8D,0x89,0xFB,0xAB,0x05,0x64,0x0C,0x11, + 0x7D,0xAA,0x7D,0x65,0xB8,0xCA,0xCC,0x4E,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, + 0x16,0x04,0x14,0xD8,0x7A,0x94,0x44,0x7C,0x90,0x70,0x90,0x16,0x9E,0xDD,0x17,0x9C, + 0x01,0x44,0x03,0x86,0xD6,0x2A,0x29,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01, + 0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x0E,0x06,0x03,0x55, + 0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x35,0x06,0x03,0x55, + 0x1D,0x1F,0x04,0x2E,0x30,0x2C,0x30,0x2A,0xA0,0x28,0xA0,0x26,0x86,0x24,0x68,0x74, + 0x74,0x70,0x3A,0x2F,0x2F,0x67,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D, + 0x2F,0x63,0x72,0x6C,0x73,0x2F,0x67,0x74,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2E,0x63, + 0x72,0x6C,0x30,0x2E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x22, + 0x30,0x20,0x30,0x1E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x12, + 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x67,0x2E,0x73,0x79,0x6D,0x63,0x64,0x2E,0x63, + 0x6F,0x6D,0x30,0x4C,0x06,0x03,0x55,0x1D,0x20,0x04,0x45,0x30,0x43,0x30,0x41,0x06, + 0x0A,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x36,0x30,0x33,0x30,0x31,0x06, + 0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x25,0x68,0x74,0x74,0x70,0x3A, + 0x2F,0x2F,0x77,0x77,0x77,0x2E,0x67,0x65,0x6F,0x74,0x72,0x75,0x73,0x74,0x2E,0x63, + 0x6F,0x6D,0x2F,0x72,0x65,0x73,0x6F,0x75,0x72,0x63,0x65,0x73,0x2F,0x63,0x70,0x73, + 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03, + 0x82,0x01,0x01,0x00,0x16,0x47,0x73,0x6F,0x85,0xA2,0x62,0xE1,0xE7,0x2A,0x76,0xBB, + 0x89,0x95,0x42,0x26,0x97,0xBC,0x4A,0xAC,0xAC,0x70,0x53,0x3A,0x3F,0x31,0x83,0x3D, + 0x3C,0x1C,0xAB,0x9A,0xE2,0xB1,0x5D,0x1C,0x76,0x1A,0xA0,0x3C,0x0C,0x72,0x57,0xBE, + 0xD3,0x9E,0x50,0xE0,0xC8,0x99,0xD6,0x58,0xD7,0x02,0xEA,0xCE,0x0D,0x29,0x54,0x7C, + 0xCD,0xF5,0xC2,0xC6,0x90,0x29,0x55,0xA3,0x6F,0x14,0xA8,0x0B,0x42,0x0D,0x3A,0x98, + 0x6D,0x06,0x78,0x9E,0xF0,0x6A,0xA3,0x1D,0x02,0x0A,0xA2,0x28,0xA4,0x8D,0xC2,0x81, + 0x46,0x3E,0x6D,0x67,0xDA,0xDE,0x3F,0xFE,0x85,0x0E,0x42,0x2A,0x12,0xDE,0xB5,0xB7, + 0xFB,0xB8,0x1B,0xA7,0x96,0xEC,0x77,0x9F,0xEC,0xD4,0x53,0x95,0x7A,0xFF,0x07,0xF4, + 0xF2,0x0A,0x14,0xC0,0x51,0x52,0xB1,0xD6,0x8E,0x50,0x0B,0x1A,0x99,0x5C,0xBC,0x0B, + 0xC9,0xBD,0xED,0xED,0xF8,0x5E,0xC1,0x56,0xDB,0x4D,0x7E,0x23,0xA4,0x11,0xA1,0x2C, + 0xD4,0x1B,0x05,0x9A,0xE4,0x1B,0x52,0xF6,0x7C,0x38,0x99,0x05,0x4B,0xBA,0x72,0x8D, + 0x42,0x89,0x60,0x04,0x66,0x2A,0xF4,0xFD,0x68,0xD7,0x6B,0xF7,0x99,0x41,0x28,0xD6, + 0x6C,0x24,0xAB,0xE6,0x25,0x53,0x2E,0xC8,0x82,0x99,0xE2,0xA2,0x8F,0x23,0xBE,0x30, + 0x83,0xB1,0x27,0x8B,0xFA,0x68,0x7F,0x01,0x49,0xE8,0xC6,0x98,0x6B,0x10,0x2E,0x98, + 0x5E,0x8A,0xD7,0xCA,0x4B,0xB1,0xC7,0xC9,0x58,0x9A,0xD0,0x36,0xDB,0x96,0x95,0xEC, + 0xB6,0x81,0xE4,0xF2,0xCD,0x6F,0x1B,0x79,0x87,0x4C,0x10,0x3C,0x89,0xE4,0x4D,0xFA, + 0x54,0xDC,0xAA,0xA6, +}; + +unsigned char ocsp_smime_leaf_certificate[1338]={ + 0x30,0x82,0x05,0x36,0x30,0x82,0x04,0x1E,0xA0,0x03,0x02,0x01,0x02,0x02,0x0D,0x14, + 0x00,0x01,0x00,0x02,0x9C,0xE1,0xB9,0xE0,0x7C,0xD1,0x7B,0xEC,0x30,0x0D,0x06,0x09, + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x7C,0x31,0x0B,0x30, + 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03, + 0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E, + 0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04, + 0x0B,0x13,0x1C,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65, + 0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,0x43,0x41,0x31, + 0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75, + 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31, + 0x20,0x4C,0x31,0x20,0x43,0x41,0x20,0x49,0x58,0x30,0x1E,0x17,0x0D,0x31,0x30,0x31, + 0x31,0x31,0x32,0x30,0x36,0x33,0x36,0x34,0x35,0x5A,0x17,0x0D,0x31,0x31,0x31,0x31, + 0x31,0x33,0x30,0x36,0x33,0x36,0x34,0x35,0x5A,0x30,0x24,0x31,0x0B,0x30,0x09,0x06, + 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04, + 0x03,0x13,0x0C,0x51,0x75,0x69,0x6E,0x6E,0x20,0x54,0x61,0x79,0x6C,0x6F,0x72,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, + 0xC1,0x11,0xAA,0x04,0xCF,0x04,0xA0,0x07,0xF3,0x43,0x2A,0xB2,0x27,0x1A,0x13,0x35, + 0x97,0x9A,0xBA,0x34,0xE5,0x84,0xF3,0xD5,0xE5,0xD9,0xAB,0x23,0x8D,0xB4,0x7E,0x68, + 0x5C,0xF2,0x9A,0xF1,0x08,0x9B,0x04,0x34,0xC1,0x09,0x14,0x68,0xD8,0x9C,0xC1,0x6C, + 0x27,0xF5,0x92,0x54,0xAF,0x66,0x65,0xF1,0x50,0xAA,0x7E,0xE3,0xFC,0xC1,0xB0,0x3E, + 0xEF,0xAA,0x86,0x58,0x4F,0xE7,0x86,0x0A,0x74,0xA6,0x97,0xBD,0x7D,0xF6,0xCE,0xA6, + 0x8B,0xF7,0xC0,0x90,0x6E,0x50,0x69,0x36,0x65,0x82,0x0F,0x65,0xA7,0x2C,0x16,0xFA, + 0x6C,0xCA,0x54,0x45,0x7C,0x06,0x20,0x72,0xF0,0x00,0x7B,0xD7,0x17,0xCD,0x94,0x64, + 0x6A,0xB7,0x28,0xF3,0x62,0xB1,0x29,0xAE,0x0C,0x8A,0x2F,0x3C,0x06,0x89,0xE8,0x81, + 0x77,0xAD,0x1F,0x65,0xED,0x6F,0x51,0x64,0x65,0x68,0x76,0xD8,0xEE,0xEC,0xA6,0x28, + 0xA9,0x1C,0x4F,0x98,0x4A,0x6D,0xD0,0xC8,0x5C,0x59,0x17,0x9B,0xF8,0x6D,0xF5,0x93, + 0xD3,0x4C,0x2A,0x37,0x80,0x65,0xB4,0x34,0xBA,0x64,0x2F,0xA1,0x8E,0x1C,0x6A,0x88, + 0x7C,0xA3,0xDB,0xDD,0x00,0x9B,0x78,0x51,0x7B,0xA6,0x8D,0xDD,0x43,0x9B,0xB2,0x2E, + 0x4B,0x1E,0xB3,0x34,0x37,0x3F,0x63,0x08,0x8C,0xC8,0xCF,0xD0,0xB0,0x8C,0xBF,0x8F, + 0xA7,0x49,0xBD,0x48,0x1D,0xB5,0x1E,0x6A,0x42,0x48,0x16,0x9A,0x7C,0xD3,0x55,0x6B, + 0xFF,0xD6,0xBA,0x70,0xF3,0x5F,0x1F,0x57,0x16,0xE0,0x1C,0xF1,0x73,0x22,0xD9,0x33, + 0xA7,0x20,0xE8,0xED,0x52,0x2A,0xE9,0x6F,0xCF,0xFB,0x76,0xAC,0xB8,0x5D,0x9B,0xAB, + 0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0x0D,0x30,0x82,0x02,0x09,0x30,0x81,0xA5, + 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x81,0x98,0x30,0x81,0x95, + 0x30,0x51,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x45,0x68,0x74, + 0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65, + 0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x65,0x72,0x74,0x73,0x65,0x72,0x76, + 0x69,0x63,0x65,0x73,0x2F,0x63,0x61,0x63,0x65,0x72,0x74,0x73,0x2F,0x74,0x63,0x5F, + 0x63,0x6C,0x61,0x73,0x73,0x31,0x5F,0x4C,0x31,0x5F,0x43,0x41,0x5F,0x49,0x58,0x2E, + 0x63,0x72,0x74,0x30,0x40,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86, + 0x34,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x69,0x78,0x2E, + 0x74,0x63,0x63,0x6C,0x61,0x73,0x73,0x31,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65, + 0x72,0x73,0x61,0x6C,0x2D,0x69,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74, + 0x65,0x72,0x2E,0x64,0x65,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, + 0x80,0x14,0xE9,0xB8,0x28,0x1D,0x46,0xCF,0xFC,0xCD,0xF8,0x4E,0x9B,0xC5,0xEE,0x4B, + 0x60,0xEB,0xD8,0x3B,0x3F,0xD1,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF, + 0x04,0x02,0x30,0x00,0x30,0x4A,0x06,0x03,0x55,0x1D,0x20,0x04,0x43,0x30,0x41,0x30, + 0x3F,0x06,0x09,0x2A,0x82,0x14,0x00,0x2C,0x01,0x01,0x01,0x01,0x30,0x32,0x30,0x30, + 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x24,0x68,0x74,0x74,0x70, + 0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74, + 0x65,0x72,0x2E,0x64,0x65,0x2F,0x67,0x75,0x69,0x64,0x65,0x6C,0x69,0x6E,0x65,0x73, + 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x04,0xF0, + 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xF8,0x4D,0x7F,0xDE,0xFA, + 0x21,0x2E,0xAF,0x96,0xBB,0xAA,0x9B,0x22,0x56,0x80,0xF0,0x8E,0xD4,0x6A,0x52,0x30, + 0x62,0x06,0x03,0x55,0x1D,0x1F,0x04,0x5B,0x30,0x59,0x30,0x57,0xA0,0x55,0xA0,0x53, + 0x86,0x51,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x69,0x78,0x2E, + 0x74,0x63,0x63,0x6C,0x61,0x73,0x73,0x31,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65, + 0x72,0x73,0x61,0x6C,0x2D,0x69,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74, + 0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C,0x2F,0x76,0x32,0x2F,0x74,0x63,0x5F, + 0x43,0x6C,0x61,0x73,0x73,0x31,0x5F,0x4C,0x31,0x5F,0x43,0x41,0x5F,0x49,0x58,0x2E, + 0x63,0x72,0x6C,0x30,0x33,0x06,0x03,0x55,0x1D,0x25,0x04,0x2C,0x30,0x2A,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, + 0x03,0x04,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,0x06,0x0A,0x2B,0x06, + 0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,0x30,0x1C,0x06,0x03,0x55,0x1D,0x11,0x04, + 0x15,0x30,0x13,0x81,0x11,0x71,0x74,0x61,0x79,0x6C,0x6F,0x72,0x40,0x61,0x70,0x70, + 0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, + 0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x0D,0xCF,0x33,0xAB,0x3D,0xD3, + 0xD2,0x06,0x2C,0x20,0x3C,0xEC,0x0C,0xE4,0xA5,0x19,0x86,0xB3,0xA7,0xA9,0xA6,0xE9, + 0xDC,0xB4,0x35,0xBB,0x0D,0x67,0xD5,0xBD,0x5F,0x93,0xD9,0x2E,0xA0,0x05,0x2A,0xED, + 0xAE,0x41,0xD9,0xEE,0x30,0xA8,0x82,0x50,0xD0,0x4B,0x04,0x6B,0x37,0xAE,0xC0,0x10, + 0x89,0x05,0x68,0x82,0x91,0x2B,0x5B,0xE2,0x7D,0xA6,0x87,0xF7,0x26,0x96,0xBA,0x2A, + 0x52,0x03,0x97,0xF6,0x2E,0x0D,0x81,0x65,0x24,0x10,0xD5,0x8C,0xB3,0xCD,0x19,0x58, + 0xAF,0x3A,0x3D,0x2F,0x10,0x30,0x79,0x6A,0xD6,0x08,0x8F,0x8B,0x9D,0x1D,0xF8,0x19, + 0xE4,0x24,0x2B,0xE0,0x7F,0x73,0xE1,0x50,0x9C,0x53,0xE1,0x46,0xC7,0xA7,0xBD,0x71, + 0xCD,0xFF,0x39,0xA0,0x50,0xA5,0xA8,0xD9,0x50,0x39,0x6C,0x36,0x1C,0x13,0x89,0x8A, + 0x0D,0x9D,0x06,0x1B,0xAA,0x59,0x40,0xC1,0xAF,0xED,0x66,0x31,0xB8,0xA0,0x9F,0xCF, + 0xA6,0x8A,0x2E,0xC2,0x1A,0x4B,0xDB,0x62,0x15,0x6E,0x10,0x2F,0x82,0x3C,0xF8,0xA2, + 0x18,0x63,0xCC,0x67,0x13,0x42,0x07,0x43,0xDB,0x20,0x13,0xC7,0xAC,0xCE,0xCB,0xEA, + 0x7E,0x53,0xA6,0x01,0x81,0xB2,0x6E,0x92,0x2B,0x0C,0xF9,0x01,0x2C,0x11,0xC9,0x00, + 0x10,0x58,0x64,0x56,0x91,0xAC,0xAA,0xF6,0xE0,0x73,0xC7,0x59,0xEC,0xCE,0x51,0x7E, + 0xAD,0x9F,0x04,0xA4,0x38,0x74,0x65,0xD0,0x23,0xBD,0x6E,0xDF,0x64,0x79,0xE2,0xA3, + 0x37,0x19,0x2F,0x8C,0x41,0x8B,0x5F,0x6D,0x84,0x61,0x54,0xD1,0x26,0x18,0x70,0xAD, + 0xE5,0xF4,0xCD,0x59,0xED,0x9E,0xE0,0xC9,0x9F,0xD3, +}; + +unsigned char ocsp_smime_CA_certificate[1500]={ + 0x30,0x82,0x05,0xD8,0x30,0x82,0x04,0xC0,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x06, + 0xE8,0x00,0x01,0x00,0x02,0x4A,0x96,0x2D,0x24,0x0C,0xFE,0xC5,0xC9,0x30,0x0D,0x06, + 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x79,0x31,0x0B, + 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06, + 0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, + 0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55, + 0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74, + 0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31, + 0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75, + 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73, + 0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x30,0x1E,0x17,0x0D,0x30,0x39,0x31,0x31,0x30, + 0x33,0x31,0x34,0x30,0x38,0x31,0x39,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31, + 0x32,0x31,0x35,0x39,0x35,0x39,0x5A,0x30,0x7C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, + 0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13, + 0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20, + 0x47,0x6D,0x62,0x48,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,0x54, + 0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C, + 0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,0x43,0x41,0x31,0x28,0x30,0x26,0x06, + 0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, + 0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20, + 0x43,0x41,0x20,0x49,0x58,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,0xBB,0xE6,0x90,0x6E,0xCF,0x62,0xE9,0xE9,0x0B,0xAA, + 0xB6,0x10,0xD5,0x47,0xE5,0x7C,0x5D,0x2B,0x27,0x71,0x9A,0x68,0xCD,0x55,0x6D,0xE4, + 0xA2,0xEF,0xE4,0xFE,0xF2,0x7A,0x63,0x11,0xC2,0x57,0x8A,0xC8,0x7D,0xCF,0x8E,0x66, + 0x1F,0x65,0x45,0x4B,0xEB,0x80,0x62,0x69,0xBD,0x46,0x8E,0x8B,0xC5,0x6E,0x5A,0x95, + 0x18,0x2A,0xDE,0xA7,0xF1,0x1F,0x75,0x1A,0x27,0xAB,0x6D,0x32,0x53,0xE3,0xFB,0x4D, + 0x58,0x62,0x2C,0xFF,0x19,0xE5,0xC7,0xA0,0x0D,0x9A,0x2D,0x21,0x88,0x59,0x84,0xCD, + 0x1D,0xF1,0xC3,0xC8,0x8A,0x3E,0xB0,0xE5,0xDE,0x08,0x24,0xCF,0xFC,0x40,0x2C,0xBA, + 0x41,0x23,0x94,0xBB,0x80,0x12,0x89,0x35,0x48,0xB6,0x86,0x04,0xE0,0x01,0x4F,0x8C, + 0xBA,0xA9,0x98,0xFC,0x1C,0x89,0xED,0x1F,0x8A,0xA1,0xC7,0x86,0x98,0x26,0x1E,0x72, + 0x65,0x6B,0xFE,0xCF,0x65,0xD9,0x0C,0x64,0x4B,0x1A,0x09,0xF5,0x43,0x11,0x60,0x66, + 0x26,0xE3,0x33,0x56,0x9A,0xC9,0x3D,0x3E,0x34,0x6A,0x78,0xC6,0xE5,0x50,0x4B,0xC8, + 0xCD,0x88,0xE4,0x39,0x6C,0x50,0x26,0x9E,0x40,0x2C,0xB6,0x3B,0x7C,0x37,0xB2,0xA7, + 0xF5,0xDD,0xDC,0xB3,0x51,0xCB,0xF4,0xDC,0x82,0x02,0xB8,0xD7,0x3A,0xDE,0xDA,0x30, + 0x5C,0x0D,0xF5,0x42,0xDD,0x13,0x69,0x53,0x54,0xE9,0x80,0x26,0x42,0x33,0x1E,0xA5, + 0xD7,0xCC,0x6E,0xCA,0x66,0x09,0x9F,0x86,0xF0,0x3D,0xBE,0xC6,0x8A,0x61,0x10,0xF3, + 0xD1,0xFF,0x5B,0xE4,0xB2,0xDB,0x2D,0xB2,0x65,0x0C,0xA9,0x7D,0x17,0xAC,0xBA,0x27, + 0x4D,0x42,0x5C,0xCE,0x09,0x4F,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0x59,0x30, + 0x82,0x02,0x55,0x30,0x81,0x9A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, + 0x04,0x81,0x8D,0x30,0x81,0x8A,0x30,0x52,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, + 0x30,0x02,0x86,0x46,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74, + 0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x65, + 0x72,0x74,0x73,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2F,0x63,0x61,0x63,0x65,0x72, + 0x74,0x73,0x2F,0x74,0x63,0x5F,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x5F, + 0x72,0x6F,0x6F,0x74,0x5F,0x49,0x2E,0x63,0x72,0x74,0x30,0x34,0x06,0x08,0x2B,0x06, + 0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x28,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F, + 0x63,0x73,0x70,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x2D, + 0x49,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65, + 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x92,0xA4,0x75, + 0x2C,0xA4,0x9E,0xBE,0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75, + 0x73,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01, + 0x01,0xFF,0x02,0x01,0x00,0x30,0x52,0x06,0x03,0x55,0x1D,0x20,0x04,0x4B,0x30,0x49, + 0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x3F,0x06,0x09,0x2A,0x82,0x14,0x00, + 0x2C,0x01,0x01,0x01,0x01,0x30,0x32,0x30,0x30,0x06,0x08,0x2B,0x06,0x01,0x05,0x05, + 0x07,0x02,0x01,0x16,0x24,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E, + 0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x67, + 0x75,0x69,0x64,0x65,0x6C,0x69,0x6E,0x65,0x73,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F, + 0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E, + 0x04,0x16,0x04,0x14,0xE9,0xB8,0x28,0x1D,0x46,0xCF,0xFC,0xCD,0xF8,0x4E,0x9B,0xC5, + 0xEE,0x4B,0x60,0xEB,0xD8,0x3B,0x3F,0xD1,0x30,0x81,0xFD,0x06,0x03,0x55,0x1D,0x1F, + 0x04,0x81,0xF5,0x30,0x81,0xF2,0x30,0x81,0xEF,0xA0,0x81,0xEC,0xA0,0x81,0xE9,0x86, + 0x46,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x74,0x63,0x75,0x6E, + 0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x2D,0x49,0x2E,0x74,0x72,0x75,0x73,0x74,0x63, + 0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C,0x2F,0x76,0x32,0x2F, + 0x74,0x63,0x5F,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x5F,0x72,0x6F,0x6F, + 0x74,0x5F,0x49,0x2E,0x63,0x72,0x6C,0x86,0x81,0x9E,0x6C,0x64,0x61,0x70,0x3A,0x2F, + 0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72, + 0x2E,0x64,0x65,0x2F,0x43,0x4E,0x3D,0x54,0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73, + 0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25,0x32,0x30,0x55,0x6E,0x69,0x76,0x65,0x72, + 0x73,0x61,0x6C,0x25,0x32,0x30,0x43,0x41,0x25,0x32,0x30,0x49,0x2C,0x4F,0x3D,0x54, + 0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25, + 0x32,0x30,0x47,0x6D,0x62,0x48,0x2C,0x4F,0x55,0x3D,0x72,0x6F,0x6F,0x74,0x63,0x65, + 0x72,0x74,0x73,0x2C,0x44,0x43,0x3D,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74, + 0x65,0x72,0x2C,0x44,0x43,0x3D,0x64,0x65,0x3F,0x63,0x65,0x72,0x74,0x69,0x66,0x69, + 0x63,0x61,0x74,0x65,0x52,0x65,0x76,0x6F,0x63,0x61,0x74,0x69,0x6F,0x6E,0x4C,0x69, + 0x73,0x74,0x3F,0x62,0x61,0x73,0x65,0x3F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x39,0xC8,0xC4,0x9B, + 0xEE,0xBE,0x98,0xEE,0x48,0x72,0x6F,0x8D,0xE7,0x71,0xB6,0x0E,0x90,0x8C,0xD3,0xB2, + 0xC1,0x15,0x21,0xA8,0x46,0x90,0x68,0x5F,0x4A,0x04,0xF1,0x3A,0xC9,0x68,0x84,0x21, + 0xD8,0xA5,0xE6,0x04,0x75,0x5D,0x9F,0xD2,0xD4,0xF2,0x4B,0x77,0x43,0x32,0xDC,0x95, + 0xCB,0x60,0xBF,0x02,0x55,0xD0,0xAC,0x1C,0xB0,0xC5,0x14,0x97,0x9B,0x65,0x0A,0xC3, + 0x0F,0xA5,0x1D,0xEC,0xD8,0x49,0x39,0x95,0xB5,0xA9,0xBE,0xFA,0xF4,0x1E,0xAB,0x56, + 0xE7,0xA6,0xE5,0x01,0x08,0x88,0x35,0x5F,0x67,0x05,0xDD,0x44,0x24,0x50,0x12,0x22, + 0x44,0x63,0x79,0xF1,0x9B,0x57,0x69,0xCE,0xAB,0xD6,0x33,0x51,0x4F,0x8D,0xF0,0x70, + 0x3B,0x8E,0xAD,0x51,0x3A,0x17,0x7F,0x35,0x96,0x6B,0x68,0x68,0x63,0xB6,0x1C,0x0A, + 0xC9,0xF8,0xDF,0x1D,0x5E,0xCF,0x2B,0x11,0xA5,0x63,0xED,0xCC,0xD0,0xC6,0xD3,0x20, + 0x6F,0xAA,0xFC,0x68,0x48,0x7E,0x6D,0x1E,0xB8,0x3A,0x45,0xAA,0x12,0x86,0xF3,0xC7, + 0xBD,0x00,0xB5,0xEB,0xFE,0xEA,0x12,0x9F,0x73,0x33,0x78,0xE7,0x28,0x39,0x68,0xD3, + 0xA5,0x6D,0xDA,0x76,0xD1,0x4E,0xE1,0x55,0x95,0x80,0xA6,0xE0,0x1B,0xB8,0xCD,0xAC, + 0x56,0xEF,0x45,0x59,0x47,0x98,0x52,0xDB,0x3A,0x6E,0x26,0xB2,0x31,0x39,0x69,0x75, + 0xB1,0x2E,0x24,0xF0,0xA4,0x9D,0x97,0x88,0x5E,0x33,0x29,0xC6,0xB5,0xBC,0x07,0x40, + 0x3A,0x0C,0x3D,0xBA,0xCF,0x74,0x8C,0x4B,0x4E,0x7A,0x21,0xFA,0x1B,0x38,0xCD,0xC4, + 0x43,0x2F,0x6F,0xB4,0xDF,0x78,0xEE,0x99,0x92,0xE7,0x3A,0x1C, +}; + +unsigned char ocsp_smime_root_certificate[993]={ + 0x30,0x82,0x03,0xDD,0x30,0x82,0x02,0xC5,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x1D, + 0xA2,0x00,0x01,0x00,0x02,0xEC,0xB7,0x60,0x80,0x78,0x8D,0xB6,0x06,0x30,0x0D,0x06, + 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x79,0x31,0x0B, + 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06, + 0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65, + 0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55, + 0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74, + 0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31, + 0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75, + 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73, + 0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x33,0x32, + 0x32,0x31,0x35,0x35,0x34,0x32,0x38,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31, + 0x32,0x32,0x35,0x39,0x35,0x39,0x5A,0x30,0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, + 0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13, + 0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20, + 0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x0B,0x13,0x1B,0x54, + 0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E, + 0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,0x26,0x30,0x24,0x06,0x03, + 0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E, + 0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41, + 0x20,0x49,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,0xA4,0x77,0x23,0x96,0x44,0xAF,0x90,0xF4,0x31,0xA7,0x10,0xF4,0x26, + 0x87,0x9C,0xF3,0x38,0xD9,0x0F,0x5E,0xDE,0xCF,0x41,0xE8,0x31,0xAD,0xC6,0x74,0x91, + 0x24,0x96,0x78,0x1E,0x09,0xA0,0x9B,0x9A,0x95,0x4A,0x4A,0xF5,0x62,0x7C,0x02,0xA8, + 0xCA,0xAC,0xFB,0x5A,0x04,0x76,0x39,0xDE,0x5F,0xF1,0xF9,0xB3,0xBF,0xF3,0x03,0x58, + 0x55,0xD2,0xAA,0xB7,0xE3,0x04,0x22,0xD1,0xF8,0x94,0xDA,0x22,0x08,0x00,0x8D,0xD3, + 0x7C,0x26,0x5D,0xCC,0x77,0x79,0xE7,0x2C,0x78,0x39,0xA8,0x26,0x73,0x0E,0xA2,0x5D, + 0x25,0x69,0x85,0x4F,0x55,0x0E,0x9A,0xEF,0xC6,0xB9,0x44,0xE1,0x57,0x3D,0xDF,0x1F, + 0x54,0x22,0xE5,0x6F,0x65,0xAA,0x33,0x84,0x3A,0xF3,0xCE,0x7A,0xBE,0x55,0x97,0xAE, + 0x8D,0x12,0x0F,0x14,0x33,0xE2,0x50,0x70,0xC3,0x49,0x87,0x13,0xBC,0x51,0xDE,0xD7, + 0x98,0x12,0x5A,0xEF,0x3A,0x83,0x33,0x92,0x06,0x75,0x8B,0x92,0x7C,0x12,0x68,0x7B, + 0x70,0x6A,0x0F,0xB5,0x9B,0xB6,0x77,0x5B,0x48,0x59,0x9D,0xE4,0xEF,0x5A,0xAD,0xF3, + 0xC1,0x9E,0xD4,0xD7,0x45,0x4E,0xCA,0x56,0x34,0x21,0xBC,0x3E,0x17,0x5B,0x6F,0x77, + 0x0C,0x48,0x01,0x43,0x29,0xB0,0xDD,0x3F,0x96,0x6E,0xE6,0x95,0xAA,0x0C,0xC0,0x20, + 0xB6,0xFD,0x3E,0x36,0x27,0x9C,0xE3,0x5C,0xCF,0x4E,0x81,0xDC,0x19,0xBB,0x91,0x90, + 0x7D,0xEC,0xE6,0x97,0x04,0x1E,0x93,0xCC,0x22,0x49,0xD7,0x97,0x86,0xB6,0x13,0x0A, + 0x3C,0x43,0x23,0x77,0x7E,0xF0,0xDC,0xE6,0xCD,0x24,0x1F,0x3B,0x83,0x9B,0x34,0x3A, + 0x83,0x34,0xE3,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x1F,0x06,0x03, + 0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE, + 0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,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,0x86,0x30,0x1D, + 0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE, + 0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,0x30,0x0D,0x06, + 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01, + 0x00,0x28,0xD2,0xE0,0x86,0xD5,0xE6,0xF8,0x7B,0xF0,0x97,0xDC,0x22,0x6B,0x3B,0x95, + 0x14,0x56,0x0F,0x11,0x30,0xA5,0x9A,0x4F,0x3A,0xB0,0x3A,0xE0,0x06,0xCB,0x65,0xF5, + 0xED,0xC6,0x97,0x27,0xFE,0x25,0xF2,0x57,0xE6,0x5E,0x95,0x8C,0x3E,0x64,0x60,0x15, + 0x5A,0x7F,0x2F,0x0D,0x01,0xC5,0xB1,0x60,0xFD,0x45,0x35,0xCF,0xF0,0xB2,0xBF,0x06, + 0xD9,0xEF,0x5A,0xBE,0xB3,0x62,0x21,0xB4,0xD7,0xAB,0x35,0x7C,0x53,0x3E,0xA6,0x27, + 0xF1,0xA1,0x2D,0xDA,0x1A,0x23,0x9D,0xCC,0xDD,0xEC,0x3C,0x2D,0x9E,0x27,0x34,0x5D, + 0x0F,0xC2,0x36,0x79,0xBC,0xC9,0x4A,0x62,0x2D,0xED,0x6B,0xD9,0x7D,0x41,0x43,0x7C, + 0xB6,0xAA,0xCA,0xED,0x61,0xB1,0x37,0x82,0x15,0x09,0x1A,0x8A,0x16,0x30,0xD8,0xEC, + 0xC9,0xD6,0x47,0x72,0x78,0x4B,0x10,0x46,0x14,0x8E,0x5F,0x0E,0xAF,0xEC,0xC7,0x2F, + 0xAB,0x10,0xD7,0xB6,0xF1,0x6E,0xEC,0x86,0xB2,0xC2,0xE8,0x0D,0x92,0x73,0xDC,0xA2, + 0xF4,0x0F,0x3A,0xBF,0x61,0x23,0x10,0x89,0x9C,0x48,0x40,0x6E,0x70,0x00,0xB3,0xD3, + 0xBA,0x37,0x44,0x58,0x11,0x7A,0x02,0x6A,0x88,0xF0,0x37,0x34,0xF0,0x19,0xE9,0xAC, + 0xD4,0x65,0x73,0xF6,0x69,0x8C,0x64,0x94,0x3A,0x79,0x85,0x29,0xB0,0x16,0x2B,0x0C, + 0x82,0x3F,0x06,0x9C,0xC7,0xFD,0x10,0x2B,0x9E,0x0F,0x2C,0xB6,0x9E,0xE3,0x15,0xBF, + 0xD9,0x36,0x1C,0xBA,0x25,0x1A,0x52,0x3D,0x1A,0xEC,0x22,0x0C,0x1C,0xE0,0xA4,0xA2, + 0x3D,0xF0,0xE8,0x39,0xCF,0x81,0xC0,0x7B,0xED,0x5D,0x1F,0x6F,0xC5,0xD0,0x0B,0xD7, + 0x98, +}; + +/* subject:/C=US/ST=California/L=Walnut Creek/O=Lucas Garron/CN=revoked.badssl.com */ +/* issuer :/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA */ +uint8_t _probablyRevokedLeaf[]={ + 0x30,0x82,0x06,0xA1,0x30,0x82,0x05,0x89,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01, + 0xAF,0x1E,0xFB,0xDD,0x5E,0xAE,0x09,0x52,0x32,0x0B,0x24,0xFE,0x6B,0x55,0x68,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x4D, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, + 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x49,0x6E,0x63,0x31,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x03,0x13,0x1E,0x44, + 0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,0x53,0x65,0x63, + 0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17, + 0x0D,0x31,0x36,0x30,0x39,0x30,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D, + 0x31,0x39,0x30,0x39,0x31,0x31,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x30,0x6D,0x31, + 0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11, + 0x06,0x03,0x55,0x04,0x08,0x13,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69, + 0x61,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x07,0x13,0x0C,0x57,0x61,0x6C,0x6E, + 0x75,0x74,0x20,0x43,0x72,0x65,0x65,0x6B,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04, + 0x0A,0x13,0x0C,0x4C,0x75,0x63,0x61,0x73,0x20,0x47,0x61,0x72,0x72,0x6F,0x6E,0x31, + 0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12,0x72,0x65,0x76,0x6F,0x6B,0x65, + 0x64,0x2E,0x62,0x61,0x64,0x73,0x73,0x6C,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,0xC7,0x31,0x65, + 0xE4,0x55,0xCF,0x69,0x90,0x9F,0x6E,0x1F,0xD8,0x6A,0x13,0x7E,0x74,0xBF,0x13,0x3A, + 0x54,0x64,0x0F,0x74,0x24,0x3D,0xDC,0x60,0xB8,0xA7,0x45,0x01,0xB7,0xC8,0x6A,0x03, + 0xAC,0x64,0x4A,0x65,0xF0,0x7C,0x81,0x81,0x83,0x0A,0xD9,0xDD,0x31,0x20,0x82,0x48, + 0xA6,0x33,0x63,0xEE,0x2B,0x74,0xEA,0xB4,0xE6,0xC7,0x1C,0xB2,0x5E,0xE4,0x28,0x3A, + 0x7A,0x3D,0x20,0x19,0x03,0xB7,0x15,0x3F,0x4F,0xC9,0x26,0xEC,0xB7,0xCB,0xBF,0x48, + 0x6E,0x5F,0x34,0x70,0x56,0xC4,0x86,0xC7,0xE3,0x52,0x9A,0x21,0x33,0x2F,0x10,0x13, + 0xF3,0x25,0x0C,0x1E,0x94,0x35,0x2E,0xE8,0xD0,0xD1,0xB5,0xA0,0x77,0x40,0x91,0x2E, + 0xE9,0xBA,0xF8,0xFF,0x4E,0xF5,0xFB,0xF2,0x7A,0x04,0xA7,0xE6,0xC6,0xCE,0x3F,0x0F, + 0x10,0x18,0x32,0xC8,0x06,0xBC,0x15,0xB3,0xBE,0x69,0xAC,0x75,0x7D,0x42,0xA0,0x8C, + 0x2E,0xC3,0xAC,0xE1,0x20,0x4F,0x1E,0x36,0x9C,0x9A,0x2E,0xA2,0xFD,0x79,0x80,0xB6, + 0x62,0xF8,0xC0,0xB2,0x03,0xA9,0x29,0x50,0xCC,0xD5,0x25,0x8A,0x33,0x5E,0xE0,0x78, + 0x13,0x18,0xC0,0x80,0x17,0x09,0x95,0xBD,0xA2,0xFE,0x92,0x15,0x07,0x20,0x7A,0x81, + 0xCE,0xDB,0x0E,0x81,0x29,0x89,0xD4,0xC8,0xEC,0xB3,0xB3,0x79,0x0E,0xF2,0xCE,0x25, + 0xE7,0xEE,0xBE,0x21,0x7D,0xAF,0x0C,0x13,0x94,0x29,0xDE,0x35,0x9A,0x1E,0xD8,0x84, + 0x18,0x5A,0x5C,0x1A,0x94,0x82,0xCE,0x9A,0x61,0xD6,0x9D,0xEC,0xF8,0xEE,0xAD,0x3F, + 0x09,0x5B,0x73,0xEC,0xA2,0x9B,0xFA,0xDC,0x62,0xF1,0x58,0x1F,0x7D,0x02,0x03,0x01, + 0x00,0x01,0xA3,0x82,0x03,0x5B,0x30,0x82,0x03,0x57,0x30,0x1F,0x06,0x03,0x55,0x1D, + 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x0F,0x80,0x61,0x1C,0x82,0x31,0x61,0xD5,0x2F, + 0x28,0xE7,0x8D,0x46,0x38,0xB4,0x2C,0xE1,0xC6,0xD9,0xE2,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x0E,0x04,0x16,0x04,0x14,0xF4,0x48,0x7D,0x07,0x45,0x1A,0x32,0x07,0x90,0x91, + 0xAC,0x05,0xB8,0x9F,0xA9,0x11,0xF0,0x7E,0x11,0x36,0x30,0x1D,0x06,0x03,0x55,0x1D, + 0x11,0x04,0x16,0x30,0x14,0x82,0x12,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,0x62, + 0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F, + 0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55,0x1D,0x25, + 0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x6B,0x06,0x03,0x55,0x1D,0x1F,0x04, + 0x64,0x30,0x62,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,0x74,0x74,0x70,0x3A, + 0x2F,0x2F,0x63,0x72,0x6C,0x33,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E, + 0x63,0x6F,0x6D,0x2F,0x73,0x73,0x63,0x61,0x2D,0x73,0x68,0x61,0x32,0x2D,0x67,0x35, + 0x2E,0x63,0x72,0x6C,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,0x74,0x74,0x70, + 0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x34,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74, + 0x2E,0x63,0x6F,0x6D,0x2F,0x73,0x73,0x63,0x61,0x2D,0x73,0x68,0x61,0x32,0x2D,0x67, + 0x35,0x2E,0x63,0x72,0x6C,0x30,0x4C,0x06,0x03,0x55,0x1D,0x20,0x04,0x45,0x30,0x43, + 0x30,0x37,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xFD,0x6C,0x01,0x01,0x30,0x2A,0x30, + 0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,0x68,0x74,0x74, + 0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72, + 0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x50,0x53,0x30,0x08,0x06,0x06,0x67,0x81,0x0C, + 0x01,0x02,0x03,0x30,0x7C,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04, + 0x70,0x30,0x6E,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86, + 0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x64,0x69,0x67, + 0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x46,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x30,0x02,0x86,0x3A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x61, + 0x63,0x65,0x72,0x74,0x73,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63, + 0x6F,0x6D,0x2F,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x53,0x48,0x41,0x32,0x53, + 0x65,0x63,0x75,0x72,0x65,0x53,0x65,0x72,0x76,0x65,0x72,0x43,0x41,0x2E,0x63,0x72, + 0x74,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30, + 0x82,0x01,0x7E,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,0x04, + 0x82,0x01,0x6E,0x04,0x82,0x01,0x6A,0x01,0x68,0x00,0x75,0x00,0xA4,0xB9,0x09,0x90, + 0xB4,0x18,0x58,0x14,0x87,0xBB,0x13,0xA2,0xCC,0x67,0x70,0x0A,0x3C,0x35,0x98,0x04, + 0xF9,0x1B,0xDF,0xB8,0xE3,0x77,0xCD,0x0E,0xC8,0x0D,0xDC,0x10,0x00,0x00,0x01,0x56, + 0xEC,0xA1,0x37,0xDA,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02,0x20,0x3F,0x6C, + 0xA8,0xF5,0xC4,0x7C,0x01,0x4C,0xC3,0x5A,0x28,0x27,0x50,0x47,0x63,0xD9,0xAC,0xE1, + 0xBE,0x2D,0xBF,0x87,0x78,0xCB,0x3A,0x80,0x97,0x24,0x74,0xCD,0x16,0xF7,0x02,0x20, + 0x71,0xFF,0x93,0xA2,0xB5,0x54,0x7E,0x7F,0x53,0x45,0x7F,0x59,0x5A,0x60,0x18,0x21, + 0x5C,0xAB,0x7D,0x1F,0x08,0xB2,0x54,0xA0,0xB3,0xC4,0x88,0xA5,0x83,0xD2,0x63,0x55, + 0x00,0x77,0x00,0x68,0xF6,0x98,0xF8,0x1F,0x64,0x82,0xBE,0x3A,0x8C,0xEE,0xB9,0x28, + 0x1D,0x4C,0xFC,0x71,0x51,0x5D,0x67,0x93,0xD4,0x44,0xD1,0x0A,0x67,0xAC,0xBB,0x4F, + 0x4F,0xFB,0xC4,0x00,0x00,0x01,0x56,0xEC,0xA1,0x37,0xA1,0x00,0x00,0x04,0x03,0x00, + 0x48,0x30,0x46,0x02,0x21,0x00,0xFE,0x59,0x97,0x22,0x4C,0x6C,0x0F,0x39,0x05,0xD9, + 0xE4,0xCA,0x7E,0x3B,0xD3,0xB3,0x47,0x1B,0x61,0x72,0xB6,0x3A,0x4F,0xD6,0xF2,0xA3, + 0x57,0x49,0x48,0x4F,0x6A,0x6D,0x02,0x21,0x00,0x8F,0x14,0x1B,0x3C,0x1B,0x89,0xA3, + 0x1D,0x70,0xEC,0xD4,0xD7,0x11,0xBC,0xF9,0x0B,0x3C,0x60,0xAC,0x8C,0x84,0x73,0x24, + 0x6B,0x0E,0x37,0x6E,0x53,0x7F,0x9D,0x7F,0x34,0x00,0x76,0x00,0x56,0x14,0x06,0x9A, + 0x2F,0xD7,0xC2,0xEC,0xD3,0xF5,0xE1,0xBD,0x44,0xB2,0x3E,0xC7,0x46,0x76,0xB9,0xBC, + 0x99,0x11,0x5C,0xC0,0xEF,0x94,0x98,0x55,0xD6,0x89,0xD0,0xDD,0x00,0x00,0x01,0x56, + 0xEC,0xA1,0x38,0x7F,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x20,0x0E,0xBF, + 0x53,0x59,0x17,0x0C,0xEC,0x66,0x0C,0x5E,0x87,0xBB,0x8F,0x5F,0xB6,0x76,0x86,0xF2, + 0x5C,0xFC,0xBC,0xA8,0xB9,0xC0,0xDF,0xBC,0x1A,0x3B,0xEE,0x11,0xF2,0xD0,0x02,0x21, + 0x00,0x87,0x25,0x39,0xE4,0x32,0x99,0x48,0xCA,0x20,0x1B,0x13,0x96,0x1D,0xC3,0x2C, + 0x98,0x6B,0x1B,0xC0,0xCC,0xE5,0x67,0x22,0xBD,0x92,0x14,0xE9,0x68,0xCD,0x95,0x82, + 0x32,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00, + 0x03,0x82,0x01,0x01,0x00,0x5A,0xA0,0x49,0x88,0xAD,0x60,0x1F,0x08,0x53,0x4C,0xD9, + 0xB8,0xDC,0xF5,0x40,0x41,0xAD,0xEF,0xC8,0x7B,0x01,0x3B,0x13,0x70,0x44,0x99,0xF6, + 0x5C,0x23,0x46,0xF7,0x3A,0xC8,0x7D,0xC9,0x21,0xAD,0x3A,0x49,0x45,0x82,0x1E,0x5D, + 0x3B,0x1E,0x9B,0x6A,0x0A,0x3E,0x61,0x2D,0xF6,0xB1,0x99,0x74,0x2F,0x91,0xF9,0xD5, + 0xF1,0x9F,0xAE,0x74,0x26,0x8B,0x3C,0xA7,0x8C,0xBE,0x28,0xFE,0xAC,0x3B,0x70,0xAE, + 0x08,0x56,0x71,0xAC,0x55,0x7C,0x40,0x89,0x02,0x2D,0x61,0x2A,0xFD,0x54,0x72,0xBF, + 0x1A,0x5C,0x70,0x19,0x90,0x15,0xA4,0x76,0xA0,0x7F,0x56,0x1C,0xC1,0xF0,0x8D,0x5E, + 0x99,0x3D,0x83,0x41,0x54,0x68,0xE5,0x62,0xC1,0x5A,0xA2,0x64,0x8C,0x01,0x64,0x7A, + 0x23,0xB9,0x3F,0xBF,0x22,0xCF,0x1F,0xC0,0x47,0x80,0x1F,0x94,0xD5,0xF2,0x30,0x84, + 0xFB,0x07,0x02,0xFA,0x5B,0xA0,0xBA,0x09,0x04,0x98,0x4E,0xF3,0x25,0x56,0x4C,0xC4, + 0x7E,0xE0,0x27,0xD8,0xE8,0x32,0x8F,0xB3,0x3C,0x5A,0x92,0x4B,0xC0,0x77,0x2D,0xB0, + 0xE5,0xAE,0x1F,0xAF,0x1D,0x7F,0x21,0x9C,0x65,0x26,0xBE,0x0C,0xBA,0xE8,0x0D,0xC1, + 0xD2,0x67,0xB4,0xB9,0x33,0xD1,0x4A,0xEE,0xFC,0xB8,0xAF,0x03,0x5B,0xC8,0x3E,0xBC, + 0xFA,0x09,0x9D,0x04,0xCE,0x3E,0xA6,0xB5,0xC4,0x74,0x3B,0x31,0x7A,0xF3,0x2C,0x42, + 0xB3,0xC7,0x73,0xDB,0xAA,0x75,0x2E,0x8D,0x8A,0x9E,0x79,0x33,0xBE,0xD7,0xB6,0x14, + 0x9B,0x26,0xAB,0x7B,0x9E,0x14,0xB3,0x55,0xE6,0x4B,0xBB,0x86,0x94,0x11,0x74,0x02, + 0x35,0xB4,0x52,0x70,0x9B, +}; + +/* subject:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA */ +/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ +uint8_t _digiCertSha2SubCA[] ={ + 0x30,0x82,0x04,0x94,0x30,0x82,0x03,0x7C,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01, + 0xFD,0xA3,0xEB,0x6E,0xCA,0x75,0xC8,0x88,0x43,0x8B,0x72,0x4B,0xCF,0xBC,0x91,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x61, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, + 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77, + 0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31, + 0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, + 0x41,0x30,0x1E,0x17,0x0D,0x31,0x33,0x30,0x33,0x30,0x38,0x31,0x32,0x30,0x30,0x30, + 0x30,0x5A,0x17,0x0D,0x32,0x33,0x30,0x33,0x30,0x38,0x31,0x32,0x30,0x30,0x30,0x30, + 0x5A,0x30,0x4D,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43, + 0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x03, + 0x13,0x1E,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20, + 0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41, + 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,0xDC,0xAE,0x58,0x90,0x4D,0xC1,0xC4,0x30,0x15,0x90,0x35,0x5B,0x6E,0x3C,0x82, + 0x15,0xF5,0x2C,0x5C,0xBD,0xE3,0xDB,0xFF,0x71,0x43,0xFA,0x64,0x25,0x80,0xD4,0xEE, + 0x18,0xA2,0x4D,0xF0,0x66,0xD0,0x0A,0x73,0x6E,0x11,0x98,0x36,0x17,0x64,0xAF,0x37, + 0x9D,0xFD,0xFA,0x41,0x84,0xAF,0xC7,0xAF,0x8C,0xFE,0x1A,0x73,0x4D,0xCF,0x33,0x97, + 0x90,0xA2,0x96,0x87,0x53,0x83,0x2B,0xB9,0xA6,0x75,0x48,0x2D,0x1D,0x56,0x37,0x7B, + 0xDA,0x31,0x32,0x1A,0xD7,0xAC,0xAB,0x06,0xF4,0xAA,0x5D,0x4B,0xB7,0x47,0x46,0xDD, + 0x2A,0x93,0xC3,0x90,0x2E,0x79,0x80,0x80,0xEF,0x13,0x04,0x6A,0x14,0x3B,0xB5,0x9B, + 0x92,0xBE,0xC2,0x07,0x65,0x4E,0xFC,0xDA,0xFC,0xFF,0x7A,0xAE,0xDC,0x5C,0x7E,0x55, + 0x31,0x0C,0xE8,0x39,0x07,0xA4,0xD7,0xBE,0x2F,0xD3,0x0B,0x6A,0xD2,0xB1,0xDF,0x5F, + 0xFE,0x57,0x74,0x53,0x3B,0x35,0x80,0xDD,0xAE,0x8E,0x44,0x98,0xB3,0x9F,0x0E,0xD3, + 0xDA,0xE0,0xD7,0xF4,0x6B,0x29,0xAB,0x44,0xA7,0x4B,0x58,0x84,0x6D,0x92,0x4B,0x81, + 0xC3,0xDA,0x73,0x8B,0x12,0x97,0x48,0x90,0x04,0x45,0x75,0x1A,0xDD,0x37,0x31,0x97, + 0x92,0xE8,0xCD,0x54,0x0D,0x3B,0xE4,0xC1,0x3F,0x39,0x5E,0x2E,0xB8,0xF3,0x5C,0x7E, + 0x10,0x8E,0x86,0x41,0x00,0x8D,0x45,0x66,0x47,0xB0,0xA1,0x65,0xCE,0xA0,0xAA,0x29, + 0x09,0x4E,0xF3,0x97,0xEB,0xE8,0x2E,0xAB,0x0F,0x72,0xA7,0x30,0x0E,0xFA,0xC7,0xF4, + 0xFD,0x14,0x77,0xC3,0xA4,0x5B,0x28,0x57,0xC2,0xB3,0xF9,0x82,0xFD,0xB7,0x45,0x58, + 0x9B,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x5A,0x30,0x82,0x01,0x56,0x30,0x12, + 0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02, + 0x01,0x00,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02, + 0x01,0x86,0x30,0x34,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28, + 0x30,0x26,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18, + 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x64,0x69,0x67,0x69, + 0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x7B,0x06,0x03,0x55,0x1D,0x1F,0x04, + 0x74,0x30,0x72,0x30,0x37,0xA0,0x35,0xA0,0x33,0x86,0x31,0x68,0x74,0x74,0x70,0x3A, + 0x2F,0x2F,0x63,0x72,0x6C,0x33,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E, + 0x63,0x6F,0x6D,0x2F,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x47,0x6C,0x6F,0x62, + 0x61,0x6C,0x52,0x6F,0x6F,0x74,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x37,0xA0,0x35, + 0xA0,0x33,0x86,0x31,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x34,0x2E, + 0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x44,0x69,0x67, + 0x69,0x43,0x65,0x72,0x74,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x52,0x6F,0x6F,0x74,0x43, + 0x41,0x2E,0x63,0x72,0x6C,0x30,0x3D,0x06,0x03,0x55,0x1D,0x20,0x04,0x36,0x30,0x34, + 0x30,0x32,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06, + 0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F, + 0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D, + 0x2F,0x43,0x50,0x53,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x0F, + 0x80,0x61,0x1C,0x82,0x31,0x61,0xD5,0x2F,0x28,0xE7,0x8D,0x46,0x38,0xB4,0x2C,0xE1, + 0xC6,0xD9,0xE2,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, + 0x03,0xDE,0x50,0x35,0x56,0xD1,0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97, + 0xB2,0x3D,0xD1,0x55,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, + 0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x23,0x3E,0xDF,0x4B,0xD2,0x31,0x42,0xA5, + 0xB6,0x7E,0x42,0x5C,0x1A,0x44,0xCC,0x69,0xD1,0x68,0xB4,0x5D,0x4B,0xE0,0x04,0x21, + 0x6C,0x4B,0xE2,0x6D,0xCC,0xB1,0xE0,0x97,0x8F,0xA6,0x53,0x09,0xCD,0xAA,0x2A,0x65, + 0xE5,0x39,0x4F,0x1E,0x83,0xA5,0x6E,0x5C,0x98,0xA2,0x24,0x26,0xE6,0xFB,0xA1,0xED, + 0x93,0xC7,0x2E,0x02,0xC6,0x4D,0x4A,0xBF,0xB0,0x42,0xDF,0x78,0xDA,0xB3,0xA8,0xF9, + 0x6D,0xFF,0x21,0x85,0x53,0x36,0x60,0x4C,0x76,0xCE,0xEC,0x38,0xDC,0xD6,0x51,0x80, + 0xF0,0xC5,0xD6,0xE5,0xD4,0x4D,0x27,0x64,0xAB,0x9B,0xC7,0x3E,0x71,0xFB,0x48,0x97, + 0xB8,0x33,0x6D,0xC9,0x13,0x07,0xEE,0x96,0xA2,0x1B,0x18,0x15,0xF6,0x5C,0x4C,0x40, + 0xED,0xB3,0xC2,0xEC,0xFF,0x71,0xC1,0xE3,0x47,0xFF,0xD4,0xB9,0x00,0xB4,0x37,0x42, + 0xDA,0x20,0xC9,0xEA,0x6E,0x8A,0xEE,0x14,0x06,0xAE,0x7D,0xA2,0x59,0x98,0x88,0xA8, + 0x1B,0x6F,0x2D,0xF4,0xF2,0xC9,0x14,0x5F,0x26,0xCF,0x2C,0x8D,0x7E,0xED,0x37,0xC0, + 0xA9,0xD5,0x39,0xB9,0x82,0xBF,0x19,0x0C,0xEA,0x34,0xAF,0x00,0x21,0x68,0xF8,0xAD, + 0x73,0xE2,0xC9,0x32,0xDA,0x38,0x25,0x0B,0x55,0xD3,0x9A,0x1D,0xF0,0x68,0x86,0xED, + 0x2E,0x41,0x34,0xEF,0x7C,0xA5,0x50,0x1D,0xBF,0x3A,0xF9,0xD3,0xC1,0x08,0x0C,0xE6, + 0xED,0x1E,0x8A,0x58,0x25,0xE4,0xB8,0x77,0xAD,0x2D,0x6E,0xF5,0x52,0xDD,0xB4,0x74, + 0x8F,0xAB,0x49,0x2E,0x9D,0x3B,0x93,0x34,0x28,0x1F,0x78,0xCE,0x94,0xEA,0xC7,0xBD, + 0xD3,0xC9,0x6D,0x1C,0xDE,0x5C,0x32,0xF3, +}; + +/* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ +/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ +uint8_t _digiCertGlobalRoot[] ={ + 0x30,0x82,0x03,0xAF,0x30,0x82,0x02,0x97,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x08, + 0x3B,0xE0,0x56,0x90,0x42,0x46,0xB1,0xA1,0x75,0x6A,0xC9,0x59,0x91,0xC7,0x4A,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x61, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, + 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77, + 0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31, + 0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, + 0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30, + 0x30,0x5A,0x17,0x0D,0x33,0x31,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30, + 0x5A,0x30,0x61,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43, + 0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B, + 0x13,0x10,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63, + 0x6F,0x6D,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67, + 0x69,0x43,0x65,0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F, + 0x74,0x20,0x43,0x41,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,0x3B,0xE1,0x11,0x72,0xDE,0xA8,0xA4,0xD3,0xA3,0x57, + 0xAA,0x50,0xA2,0x8F,0x0B,0x77,0x90,0xC9,0xA2,0xA5,0xEE,0x12,0xCE,0x96,0x5B,0x01, + 0x09,0x20,0xCC,0x01,0x93,0xA7,0x4E,0x30,0xB7,0x53,0xF7,0x43,0xC4,0x69,0x00,0x57, + 0x9D,0xE2,0x8D,0x22,0xDD,0x87,0x06,0x40,0x00,0x81,0x09,0xCE,0xCE,0x1B,0x83,0xBF, + 0xDF,0xCD,0x3B,0x71,0x46,0xE2,0xD6,0x66,0xC7,0x05,0xB3,0x76,0x27,0x16,0x8F,0x7B, + 0x9E,0x1E,0x95,0x7D,0xEE,0xB7,0x48,0xA3,0x08,0xDA,0xD6,0xAF,0x7A,0x0C,0x39,0x06, + 0x65,0x7F,0x4A,0x5D,0x1F,0xBC,0x17,0xF8,0xAB,0xBE,0xEE,0x28,0xD7,0x74,0x7F,0x7A, + 0x78,0x99,0x59,0x85,0x68,0x6E,0x5C,0x23,0x32,0x4B,0xBF,0x4E,0xC0,0xE8,0x5A,0x6D, + 0xE3,0x70,0xBF,0x77,0x10,0xBF,0xFC,0x01,0xF6,0x85,0xD9,0xA8,0x44,0x10,0x58,0x32, + 0xA9,0x75,0x18,0xD5,0xD1,0xA2,0xBE,0x47,0xE2,0x27,0x6A,0xF4,0x9A,0x33,0xF8,0x49, + 0x08,0x60,0x8B,0xD4,0x5F,0xB4,0x3A,0x84,0xBF,0xA1,0xAA,0x4A,0x4C,0x7D,0x3E,0xCF, + 0x4F,0x5F,0x6C,0x76,0x5E,0xA0,0x4B,0x37,0x91,0x9E,0xDC,0x22,0xE6,0x6D,0xCE,0x14, + 0x1A,0x8E,0x6A,0xCB,0xFE,0xCD,0xB3,0x14,0x64,0x17,0xC7,0x5B,0x29,0x9E,0x32,0xBF, + 0xF2,0xEE,0xFA,0xD3,0x0B,0x42,0xD4,0xAB,0xB7,0x41,0x32,0xDA,0x0C,0xD4,0xEF,0xF8, + 0x81,0xD5,0xBB,0x8D,0x58,0x3F,0xB5,0x1B,0xE8,0x49,0x28,0xA2,0x70,0xDA,0x31,0x04, + 0xDD,0xF7,0xB2,0x16,0xF2,0x4C,0x0A,0x4E,0x07,0xA8,0xED,0x4A,0x3D,0x5E,0xB5,0x7F, + 0xA3,0x90,0xC3,0xAF,0x27,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0E, + 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0F, + 0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30, + 0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x03,0xDE,0x50,0x35,0x56,0xD1, + 0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30,0x1F, + 0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x03,0xDE,0x50,0x35,0x56, + 0xD1,0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82, + 0x01,0x01,0x00,0xCB,0x9C,0x37,0xAA,0x48,0x13,0x12,0x0A,0xFA,0xDD,0x44,0x9C,0x4F, + 0x52,0xB0,0xF4,0xDF,0xAE,0x04,0xF5,0x79,0x79,0x08,0xA3,0x24,0x18,0xFC,0x4B,0x2B, + 0x84,0xC0,0x2D,0xB9,0xD5,0xC7,0xFE,0xF4,0xC1,0x1F,0x58,0xCB,0xB8,0x6D,0x9C,0x7A, + 0x74,0xE7,0x98,0x29,0xAB,0x11,0xB5,0xE3,0x70,0xA0,0xA1,0xCD,0x4C,0x88,0x99,0x93, + 0x8C,0x91,0x70,0xE2,0xAB,0x0F,0x1C,0xBE,0x93,0xA9,0xFF,0x63,0xD5,0xE4,0x07,0x60, + 0xD3,0xA3,0xBF,0x9D,0x5B,0x09,0xF1,0xD5,0x8E,0xE3,0x53,0xF4,0x8E,0x63,0xFA,0x3F, + 0xA7,0xDB,0xB4,0x66,0xDF,0x62,0x66,0xD6,0xD1,0x6E,0x41,0x8D,0xF2,0x2D,0xB5,0xEA, + 0x77,0x4A,0x9F,0x9D,0x58,0xE2,0x2B,0x59,0xC0,0x40,0x23,0xED,0x2D,0x28,0x82,0x45, + 0x3E,0x79,0x54,0x92,0x26,0x98,0xE0,0x80,0x48,0xA8,0x37,0xEF,0xF0,0xD6,0x79,0x60, + 0x16,0xDE,0xAC,0xE8,0x0E,0xCD,0x6E,0xAC,0x44,0x17,0x38,0x2F,0x49,0xDA,0xE1,0x45, + 0x3E,0x2A,0xB9,0x36,0x53,0xCF,0x3A,0x50,0x06,0xF7,0x2E,0xE8,0xC4,0x57,0x49,0x6C, + 0x61,0x21,0x18,0xD5,0x04,0xAD,0x78,0x3C,0x2C,0x3A,0x80,0x6B,0xA7,0xEB,0xAF,0x15, + 0x14,0xE9,0xD8,0x89,0xC1,0xB9,0x38,0x6C,0xE2,0x91,0x6C,0x8A,0xFF,0x64,0xB9,0x77, + 0x25,0x57,0x30,0xC0,0x1B,0x24,0xA3,0xE1,0xDC,0xE9,0xDF,0x47,0x7C,0xB5,0xB4,0x24, + 0x08,0x05,0x30,0xEC,0x2D,0xBD,0x0B,0xBF,0x45,0xBF,0x50,0xB9,0xA9,0xF3,0xEB,0x98, + 0x01,0x12,0xAD,0xC8,0x88,0xC6,0x98,0x34,0x5F,0x8D,0x0A,0x3C,0xC6,0xE9,0xD5,0x95, + 0x95,0x6D,0xDE, +}; + +uint8_t _digicertOCSPResponse[] = { + 0x30,0x82,0x01,0xe6,0x0a,0x01,0x00,0xa0,0x82,0x01,0xdf,0x30,0x82,0x01,0xdb,0x06,0x09,0x2b,0x06,0x01, + 0x05,0x05,0x07,0x30,0x01,0x01,0x04,0x82,0x01,0xcc,0x30,0x82,0x01,0xc8,0x30,0x81,0xb1,0xa2,0x16,0x04, + 0x14,0x0f,0x80,0x61,0x1c,0x82,0x31,0x61,0xd5,0x2f,0x28,0xe7,0x8d,0x46,0x38,0xb4,0x2c,0xe1,0xc6,0xd9, + 0xe2,0x18,0x0f,0x32,0x30,0x31,0x38,0x30,0x34,0x32,0x35,0x31,0x37,0x34,0x37,0x34,0x33,0x5a,0x30,0x81, + 0x85,0x30,0x81,0x82,0x30,0x49,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14,0x10, + 0x5f,0xa6,0x7a,0x80,0x08,0x9d,0xb5,0x27,0x9f,0x35,0xce,0x83,0x0b,0x43,0x88,0x9e,0xa3,0xc7,0x0d,0x04, + 0x14,0x0f,0x80,0x61,0x1c,0x82,0x31,0x61,0xd5,0x2f,0x28,0xe7,0x8d,0x46,0x38,0xb4,0x2c,0xe1,0xc6,0xd9, + 0xe2,0x02,0x10,0x01,0xaf,0x1e,0xfb,0xdd,0x5e,0xae,0x09,0x52,0x32,0x0b,0x24,0xfe,0x6b,0x55,0x68,0xa1, + 0x11,0x18,0x0f,0x32,0x30,0x31,0x36,0x30,0x39,0x30,0x32,0x32,0x31,0x32,0x38,0x34,0x38,0x5a,0x18,0x0f, + 0x32,0x30,0x31,0x38,0x30,0x34,0x32,0x35,0x31,0x37,0x34,0x37,0x34,0x33,0x5a,0xa0,0x11,0x18,0x0f,0x32, + 0x30,0x31,0x38,0x30,0x35,0x30,0x32,0x31,0x37,0x30,0x32,0x34,0x33,0x5a,0x30,0x0d,0x06,0x09,0x2a,0x86, + 0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x9c,0x3d,0xb9,0xc6,0xfd,0x97, + 0x21,0xb0,0x04,0xc1,0x62,0x4b,0xc7,0x74,0x7a,0x37,0x01,0xa6,0x22,0xb2,0xd2,0xce,0xbb,0xd4,0x67,0xcd, + 0xda,0x66,0xb6,0x53,0xbc,0x81,0xd4,0x09,0x9c,0xa0,0x3e,0x95,0x6d,0x90,0x0a,0xe6,0x39,0x24,0xb0,0x42, + 0x17,0xc1,0x02,0x62,0x57,0xc8,0x04,0x07,0x66,0x1f,0xc4,0x75,0x75,0xe6,0x82,0x7e,0xd3,0x28,0x46,0xde, + 0xaa,0xb8,0xd7,0x2d,0xd5,0x17,0x70,0xb7,0xbf,0xd6,0xcc,0xa3,0x14,0xe9,0x5f,0x9d,0x40,0xf2,0x5f,0x29, + 0xb2,0xde,0x8a,0x9f,0x02,0x79,0x2a,0xe9,0xa0,0xc0,0x0f,0xb1,0xc3,0xf8,0xaa,0xb1,0x9d,0xaf,0x15,0x78, + 0xf1,0x98,0x6c,0xd2,0xf2,0x1f,0x8d,0x75,0xd4,0xb6,0x91,0xc4,0xb8,0x13,0x18,0xd2,0x30,0xa1,0xb1,0x1e, + 0x81,0x1a,0xef,0x2a,0x42,0x52,0x2a,0xd4,0xec,0xc5,0x8a,0x87,0x9c,0x7b,0x38,0x81,0xf9,0x6e,0xfe,0x60, + 0x3d,0xc7,0xfe,0x77,0x64,0x99,0x3d,0x1c,0xf5,0x92,0xe9,0xe5,0x45,0xf3,0x7e,0x98,0x74,0xfa,0x5a,0xd9, + 0xf4,0x79,0xf3,0xf7,0x6c,0x99,0xce,0x52,0x47,0xc0,0x4a,0x87,0x20,0xed,0x3b,0x76,0x2a,0x58,0x3f,0x8b, + 0xb3,0xcb,0x9f,0xd4,0x11,0x26,0xc4,0x43,0xce,0xd1,0x6f,0x48,0xe4,0xd0,0x2f,0xa1,0x95,0x5a,0xb9,0x93, + 0x25,0xf9,0xd4,0x1a,0xe9,0x75,0x7d,0xcf,0xfb,0xc5,0xa5,0x78,0x98,0x68,0xfb,0x12,0xbd,0x53,0xdc,0x98, + 0x1d,0xd6,0xc7,0xa1,0x28,0x3f,0x5b,0x82,0x39,0x18,0x85,0xfd,0x91,0x8f,0x80,0xa2,0x30,0xd9,0xee,0xc4, + 0x23,0x48,0x3c,0x50,0x18,0x7e,0xc7,0x1d,0xc1,0x5a +}; + +uint8_t _caissuer_https[] = { + 0x30,0x82,0x04,0x68,0x30,0x82,0x03,0x50,0xA0,0x03,0x02,0x01,0x02,0x02,0x13,0x7A, + 0x22,0xA1,0x88,0x18,0x9E,0x75,0x77,0xE6,0xEF,0x7E,0xC0,0x33,0x8E,0xE8,0x90,0xE8, + 0x7B,0xC4,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x81,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, + 0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69, + 0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C, + 0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x13,0x30,0x11,0x06,0x03, + 0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31, + 0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x0C,0x14,0x53,0x65,0x63,0x75,0x72,0x69, + 0x74,0x79,0x20,0x45,0x6E,0x67,0x69,0x6E,0x65,0x65,0x72,0x69,0x6E,0x67,0x31,0x15, + 0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C,0x54,0x65,0x73,0x74,0x20,0x52,0x6F, + 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x34,0x32,0x38,0x32, + 0x30,0x32,0x31,0x34,0x31,0x5A,0x17,0x0D,0x31,0x39,0x30,0x34,0x32,0x38,0x32,0x30, + 0x32,0x31,0x34,0x31,0x5A,0x30,0x81,0x8D,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, + 0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A, + 0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,0x10,0x06,0x03, + 0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x13, + 0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49, + 0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x0C,0x14,0x53,0x65, + 0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x45,0x6E,0x67,0x69,0x6E,0x65,0x65,0x72,0x69, + 0x6E,0x67,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x0C,0x18,0x48,0x54,0x54, + 0x50,0x53,0x20,0x43,0x41,0x49,0x73,0x73,0x75,0x65,0x72,0x20,0x54,0x65,0x73,0x74, + 0x20,0x43,0x65,0x72,0x74,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,0xC1,0x68,0xC2,0x47,0x1E,0x07,0x82,0x66,0x47,0xC9, + 0x5C,0x22,0xDD,0x8B,0x93,0x6A,0xA7,0x22,0x00,0xB8,0xDA,0x8C,0x3C,0x52,0xA7,0x47, + 0x73,0xBB,0x7A,0xD7,0x8C,0x1E,0xAE,0xDA,0x34,0x25,0x4E,0xEB,0x1F,0x33,0x0B,0x8A, + 0xC7,0x6D,0x2A,0x93,0xDB,0x0D,0xD0,0x47,0x85,0x9C,0x14,0xD5,0x23,0xE3,0xE4,0x94, + 0xE0,0x17,0x9F,0x56,0x64,0x8E,0xE0,0x08,0xE9,0x1B,0x4C,0x7C,0x77,0xF9,0x35,0x74, + 0x52,0x43,0x90,0x13,0xFA,0x51,0x9A,0xA2,0x93,0x47,0x94,0xE7,0xBD,0x07,0xE5,0xFB, + 0x67,0x8B,0xF0,0xE2,0x0C,0x97,0xFD,0x29,0x51,0xBD,0x85,0x6C,0xBE,0x36,0xFD,0xDD, + 0xCC,0x99,0x4D,0x68,0x37,0x96,0xB2,0x20,0x85,0x55,0xA5,0x99,0xA4,0x7E,0xD7,0x19, + 0x06,0x15,0x20,0x10,0x50,0x51,0x2E,0x74,0x5C,0x43,0x49,0x94,0x6B,0x0E,0x9E,0xFB, + 0xDF,0xB2,0xEB,0xD9,0x28,0xA8,0xF1,0x25,0x49,0xC8,0xFE,0x3B,0xE1,0x45,0x95,0x47, + 0xD1,0x53,0xCD,0x34,0x9A,0x6F,0xC4,0x3F,0x63,0xC2,0x60,0xC6,0x40,0xBB,0xF7,0x20, + 0x8A,0xB8,0xB7,0xD7,0xC2,0xBB,0x48,0x24,0x64,0xA2,0x4A,0xE4,0x2A,0x17,0x68,0xE2, + 0xAC,0x47,0x2D,0xCC,0xBD,0xB7,0xCE,0x73,0xDF,0x96,0x8C,0x12,0x56,0xE3,0x29,0xE3, + 0x4D,0xB4,0x55,0x28,0xAB,0x28,0x24,0x45,0x7F,0x55,0x66,0xCD,0x46,0x29,0x89,0x58, + 0xFF,0xA6,0xD1,0x67,0xAC,0x50,0xEE,0x55,0x6D,0x6A,0x2A,0xCF,0xD6,0x09,0xE9,0xDA, + 0x22,0xB0,0xAF,0x90,0xD7,0x02,0xB2,0xCE,0x5F,0x09,0x96,0x5E,0x88,0xAE,0xB5,0xB6, + 0xA1,0xC3,0x9D,0x1A,0x2F,0x2D,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xCA,0x30,0x81, + 0xC7,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30, + 0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30, + 0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05, + 0x05,0x07,0x03,0x01,0x30,0x16,0x06,0x03,0x55,0x1D,0x11,0x04,0x0F,0x30,0x0D,0x82, + 0x0B,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1D,0x06,0x03, + 0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xDF,0xC7,0x68,0x26,0x64,0x95,0x5D,0x73,0x36, + 0x84,0xE8,0xE3,0x1D,0xC8,0x28,0x5E,0xA8,0x27,0x73,0x8C,0x30,0x1F,0x06,0x03,0x55, + 0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xB5,0xA9,0x53,0x08,0x10,0x38,0x1A,0xA5, + 0xB3,0x84,0xC9,0xEE,0xC4,0xAB,0x0F,0xB8,0x5F,0x68,0x10,0xA2,0x30,0x3A,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x2E,0x30,0x2C,0x30,0x2A,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x1E,0x68,0x74,0x74,0x70,0x73,0x3A, + 0x2F,0x2F,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x74,0x65, + 0x73,0x74,0x43,0x41,0x2E,0x64,0x65,0x72,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xC4,0x48,0xDF,0x5E, + 0x73,0xD1,0x43,0x28,0x7D,0x69,0x71,0x32,0x1F,0xCC,0x1A,0xEB,0x5B,0x98,0x9D,0xCE, + 0xFF,0xCA,0x16,0xA9,0x96,0xE7,0x4D,0xC4,0xAE,0x53,0xE2,0x5D,0xDB,0xDA,0x40,0x80, + 0xE5,0xFB,0xF3,0xD7,0x21,0x9A,0x77,0x1D,0x67,0xFC,0x04,0x62,0x18,0xFF,0x10,0x59, + 0xF4,0xDD,0xF4,0xC6,0x8F,0xB4,0xEF,0x9F,0x05,0xA6,0xF1,0xCB,0x44,0x24,0x02,0x19, + 0x75,0xF9,0x3C,0x28,0x8A,0xAA,0x57,0x6B,0xFF,0x64,0xFF,0xD7,0xE2,0x62,0x67,0x70, + 0x20,0x4D,0xAE,0xD2,0x67,0xED,0x92,0xA4,0xFA,0x8A,0xC3,0x24,0x9C,0x2F,0x4D,0x2C, + 0xA9,0xA5,0x92,0x5E,0x5C,0x6F,0xDB,0xAB,0x96,0xA6,0xB1,0x5B,0xF1,0x8D,0x97,0x08, + 0xBC,0x5B,0x27,0xD5,0x9E,0x2D,0xF0,0x49,0x68,0xA6,0x92,0x00,0x13,0xAD,0x60,0x9E, + 0x78,0x72,0xC2,0x18,0xB8,0xE5,0x9D,0x72,0xA5,0x87,0x61,0xA8,0x95,0x8A,0x2B,0xB2, + 0xCC,0xCA,0x7F,0x1E,0x1E,0xC5,0xFB,0x5A,0x0C,0x77,0x17,0xB0,0xBE,0x7B,0x5A,0x50, + 0x05,0x32,0x40,0x98,0x3A,0x8B,0x22,0x3F,0x3B,0xA5,0xA8,0xA9,0x59,0x3B,0x55,0x92, + 0xD1,0x8A,0x34,0x73,0xA6,0xD6,0x5D,0x5E,0x85,0x59,0x00,0xD5,0x55,0x94,0x80,0xC1, + 0xB9,0xF1,0xCA,0x2B,0xC5,0x96,0xEE,0x49,0x6A,0x2C,0xDD,0x62,0x98,0xB3,0x74,0x09, + 0x09,0xDE,0x3D,0x59,0x5B,0x21,0x76,0x6E,0x27,0x66,0xED,0x7B,0x74,0x7F,0xE7,0xA9, + 0xAE,0xEB,0x40,0x83,0xB9,0xBC,0xE6,0x0C,0x1E,0x53,0xB2,0xEA,0x79,0xC4,0xA9,0x30, + 0x2B,0x1F,0xC4,0x34,0x82,0x3E,0xFC,0x1E,0x2D,0x66,0x75,0xD0, +}; + +#endif /* _SECURITY_SI_23_SECTRUST_OCSP_H_ */ diff --git a/OSX/sec/Security/Regressions/secitem/si-27-sectrust-exceptions.c b/OSX/sec/Security/Regressions/secitem/si-27-sectrust-exceptions.c index 34d3d92f..81a2af1e 100644 --- a/OSX/sec/Security/Regressions/secitem/si-27-sectrust-exceptions.c +++ b/OSX/sec/Security/Regressions/secitem/si-27-sectrust-exceptions.c @@ -302,7 +302,7 @@ static void tests(void) cert0, cert1 }; - SecPolicyRef policy = SecPolicyCreateSSL(false, CFSTR("store.apple.com")); + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("store.apple.com")); CFArrayRef certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), NULL); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust"); @@ -322,7 +322,7 @@ static void tests(void) CFReleaseNull(trust); CFReleaseNull(policy); - policy = SecPolicyCreateSSL(false, CFSTR("badstore.apple.com")); + policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust with hostname mismatch"); ok_status(SecTrustSetVerifyDate(trust, date), "set date"); ok(SecTrustSetExceptions(trust, exceptions), "set old exceptions"); @@ -368,7 +368,7 @@ static void tests(void) CFReleaseNull(trust); CFReleaseNull(policy); - policy = SecPolicyCreateSSL(false, CFSTR("self-signed.ssltest.apple.com")); + policy = SecPolicyCreateSSL(true, CFSTR("self-signed.ssltest.apple.com")); ok_status(SecTrustCreateWithCertificates(sscert0, policy, &trust), "create trust"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); diff --git a/OSX/sec/Security/Regressions/secitem/si-28-sectrustsettings.m b/OSX/sec/Security/Regressions/secitem/si-28-sectrustsettings.m index 522b3fd4..66aa2eb7 100644 --- a/OSX/sec/Security/Regressions/secitem/si-28-sectrustsettings.m +++ b/OSX/sec/Security/Regressions/secitem/si-28-sectrustsettings.m @@ -29,6 +29,7 @@ /* Of course, the interface is different for OS X and iOS. */ /* each call is 1 test */ +#define kNumberSetTSTests 1 #if TARGET_OS_IPHONE #define setTS(cert, settings) \ { \ @@ -61,6 +62,7 @@ #endif /* each call is 1 test */ +#define kNumberRemoveTSTests 1 #if TARGET_OS_IPHONE #define removeTS(cert) \ { \ @@ -76,6 +78,7 @@ #endif /* each call is 4 tests */ +#define kNumberCheckTrustTests 4 #define check_trust(certs, policy, valid_date, expected) \ { \ SecTrustRef trust = NULL; \ @@ -533,7 +536,28 @@ static void test_multiple_constraints(void) { } -#define kNumberPolicyNamePinnningConstraintsTests (1 + 1 + 5) +#define kNumberChangeConstraintsTests (2*kNumberSetTSTests + kNumberRemoveTSTests + 4*kNumberCheckTrustTests) +static void test_change_constraints(void) { + /* allow all but */ + NSArray *allowAllBut = @[ + @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy , + (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)}, + @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) } + ]; + setTS(cert0, (__bridge CFArrayRef)allowAllBut); + check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed); + check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure); + + /* Don't clear trust settings. Just change them. */ + + /* root with the default TrustRoot result succeeds */ + setTS(cert0, NULL); + check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed); + check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultProceed); + removeTS(cert0); +} + +#define kNumberPolicyNamePinnningConstraintsTests (kNumberSetTSTests + kNumberRemoveTSTests + 5) static void test_policy_name_pinning_constraints(void) { /* allow all but */ NSArray *allowAllBut = @[ @@ -564,6 +588,7 @@ int si_28_sectrustsettings(int argc, char *const *argv) + kNumberKeyUsageConstraintsTests + kNumberAllowedErrorsTests + kNumberMultipleConstraintsTests + + kNumberChangeConstraintsTests + kNumberPolicyNamePinnningConstraintsTests ); @@ -583,6 +608,7 @@ int si_28_sectrustsettings(int argc, char *const *argv) test_key_usage_constraints(); test_allowed_errors(); test_multiple_constraints(); + test_change_constraints(); test_policy_name_pinning_constraints(); cleanup_globals(); } diff --git a/OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.m b/OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.m index 3a7bffdf..8ad5a799 100644 --- a/OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.m +++ b/OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.m @@ -150,7 +150,7 @@ static void tests(void) is(trustResult, kSecTrustResultUnspecified, "accept test: app-trusted SHA-1 SSL server"); /* SHA1 cert from system root passes SSL client */ - clientPolicy = SecPolicyCreateSSL(false, CFSTR("www.badssl.com")); + clientPolicy = SecPolicyCreateSSL(false, NULL); setTrust(&trust, sha1_certs, clientPolicy); require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust"); is(trustResult, kSecTrustResultUnspecified, "accept test: system-trusted SHA-1 SSL client"); diff --git a/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.h b/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.h new file mode 100644 index 00000000..b48920b6 --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.h @@ -0,0 +1,916 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + */ + +#ifndef si_34_cms_timestamp_h +#define si_34_cms_timestamp_h + +/* MARK: Mismatched timestamp + * The MessageImprint in the timestamp of this CMS blob does not match the countersigned SignerInfo + * that contains the timestamp. + */ +uint8_t _mismatched_content[] = { + 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x0a +}; + +uint8_t _mismatched_timestamp[] = { + 0x30, 0x82, 0x21, 0x6c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x21, 0x5d, 0x30, + 0x82, 0x21, 0x59, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x01, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x0e, 0xc1, 0x30, 0x82, + 0x05, 0x69, 0x30, 0x82, 0x04, 0x51, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x00, 0xe3, 0xd3, 0xe8, 0xe4, 0xcc, 0xd6, + 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x71, 0x31, 0x2b, + 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x22, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, + 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x20, 0x2d, + 0x20, 0x47, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 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, 0x31, 0x32, + 0x39, 0x32, 0x32, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x31, 0x32, 0x37, 0x32, 0x32, 0x33, 0x35, + 0x35, 0x32, 0x5a, 0x30, 0x3c, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x63, 0x73, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x30, 0x30, 0x33, 0x74, 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, 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, 0xe9, 0xad, + 0x73, 0xbc, 0xa2, 0x60, 0x1a, 0x44, 0x1d, 0x16, 0x2b, 0x21, 0x23, 0xdf, 0xe8, 0x1e, 0x74, 0xc2, 0xe8, 0x14, 0xb3, 0x60, + 0x17, 0x02, 0x8a, 0x54, 0xbf, 0xfd, 0x3e, 0x77, 0x7b, 0xdc, 0x55, 0x49, 0xd7, 0x05, 0x33, 0x6a, 0xd8, 0x4d, 0xa8, 0x2b, + 0xa1, 0xfd, 0xeb, 0xdf, 0xb6, 0xd5, 0x7b, 0x1a, 0x15, 0x02, 0xa3, 0x41, 0xc0, 0x71, 0x12, 0x13, 0x72, 0xe1, 0x8f, 0x23, + 0x65, 0x18, 0xde, 0x7f, 0x66, 0x7c, 0x49, 0x5d, 0x78, 0x75, 0xd7, 0xf6, 0xe2, 0x7c, 0x8c, 0x8d, 0xf6, 0xc7, 0x6d, 0x83, + 0x9e, 0xd9, 0x8b, 0xef, 0xd3, 0xb2, 0xab, 0x31, 0x19, 0x7f, 0xd1, 0x95, 0x0e, 0xaf, 0xe6, 0x16, 0xb8, 0x43, 0x23, 0xa5, + 0x93, 0xc4, 0x0f, 0x8f, 0xde, 0xf3, 0x38, 0xf6, 0x53, 0xbc, 0xdd, 0x5c, 0x3a, 0x5b, 0x06, 0x5e, 0xf1, 0x68, 0x82, 0x2e, + 0xee, 0x29, 0x5d, 0xfa, 0x3f, 0x0f, 0x06, 0xfa, 0xef, 0x8b, 0x54, 0x26, 0xc9, 0xd7, 0xff, 0x92, 0x4f, 0x13, 0x19, 0x6e, + 0x5b, 0x6f, 0x73, 0x58, 0x8e, 0x5d, 0xc1, 0xdf, 0x23, 0xe1, 0x27, 0xb9, 0x16, 0xd2, 0xe5, 0x67, 0x07, 0xc5, 0xcc, 0xe4, + 0xbe, 0xa6, 0xda, 0xfa, 0x37, 0xe6, 0xe1, 0xe1, 0xba, 0x05, 0x68, 0x84, 0xe3, 0xa2, 0xd9, 0xa9, 0x43, 0x93, 0x8b, 0xaa, + 0xd7, 0xc6, 0x98, 0x75, 0xde, 0xb2, 0xfe, 0x2c, 0x28, 0xbf, 0x58, 0x92, 0x60, 0xe5, 0xbc, 0xda, 0x0b, 0xc4, 0x5b, 0x8c, + 0x87, 0x45, 0xad, 0x62, 0x8c, 0x10, 0x6a, 0x31, 0x77, 0x4e, 0x48, 0xc0, 0x76, 0x79, 0x29, 0x91, 0xb3, 0x66, 0x82, 0xeb, + 0xb2, 0x35, 0xd1, 0xc3, 0x5a, 0x2b, 0x13, 0xda, 0x24, 0xf7, 0xa8, 0xad, 0xb7, 0xd2, 0xaf, 0x98, 0xa1, 0x93, 0x43, 0x9a, + 0x07, 0xf8, 0xb5, 0xce, 0xe5, 0x1c, 0xc9, 0x46, 0x63, 0x50, 0x79, 0xa5, 0x1e, 0x1f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x02, 0x38, 0x30, 0x82, 0x02, 0x34, 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, 0xbe, 0x46, 0x64, 0xc6, 0xc9, 0x6d, + 0x92, 0x89, 0x11, 0x41, 0x60, 0x91, 0x87, 0xf1, 0x64, 0x7c, 0x78, 0xd2, 0x7c, 0x94, 0x30, 0x56, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x4a, 0x30, 0x48, 0x30, 0x46, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x01, 0x86, 0x3a, 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, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x63, 0x61, 0x67, 0x32, + 0x30, 0x31, 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, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0d, 0x30, 0x0b, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x04, 0x01, 0x30, 0x49, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x42, 0x30, + 0x40, 0x30, 0x3e, 0xa0, 0x3c, 0xa0, 0x3a, 0x86, 0x38, 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, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x63, 0x61, 0x67, + 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x4e, 0xe9, 0xa9, 0xc3, + 0x2e, 0x25, 0xd2, 0xa2, 0x7a, 0x8b, 0x52, 0x3d, 0x16, 0x3c, 0xaf, 0xee, 0x41, 0xef, 0x79, 0x01, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x11, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x63, 0x64, 0x06, 0x01, 0x1d, 0x02, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0xbe, 0xc8, 0x17, 0x96, 0xe9, 0x50, 0x1e, 0xfa, + 0xfb, 0xa8, 0x99, 0x83, 0xc4, 0x68, 0x3a, 0xc5, 0xb7, 0x80, 0x7a, 0xb0, 0x59, 0x6c, 0xb6, 0x0c, 0xb1, 0xee, 0x40, 0x9a, + 0x18, 0x11, 0x45, 0x16, 0x97, 0xad, 0xd7, 0xe5, 0x10, 0xa2, 0x1f, 0x3c, 0xdd, 0x63, 0xcb, 0xc9, 0x72, 0xd3, 0x6e, 0x72, + 0x4d, 0x90, 0xc4, 0xb2, 0x16, 0x95, 0x16, 0x1c, 0x12, 0x2a, 0xd0, 0xb6, 0x65, 0x4c, 0x54, 0x7e, 0xe0, 0xa6, 0xb7, 0x06, + 0x85, 0x07, 0xac, 0x3f, 0x05, 0x51, 0xcb, 0xd5, 0x20, 0x6a, 0x47, 0x16, 0xb9, 0x6e, 0xd3, 0x93, 0xa1, 0xd6, 0xbc, 0xe2, + 0x15, 0x25, 0x0b, 0x7c, 0xc1, 0x72, 0xcd, 0xee, 0x64, 0xbe, 0x5f, 0x4e, 0xb4, 0xf5, 0x1d, 0x6d, 0x6c, 0xc5, 0x37, 0xf6, + 0xb8, 0xb3, 0xfc, 0xc2, 0x41, 0x01, 0x79, 0x0c, 0x68, 0x2b, 0x24, 0x86, 0xe8, 0x6f, 0x55, 0x19, 0x59, 0x69, 0xa2, 0x36, + 0x01, 0x80, 0x22, 0x78, 0xad, 0xe6, 0xd8, 0xe9, 0xa8, 0x98, 0x75, 0xc7, 0xe8, 0x10, 0x37, 0x7c, 0x8a, 0x80, 0x06, 0xbf, + 0x24, 0xfb, 0xd6, 0xc0, 0x9f, 0xa3, 0x26, 0x7a, 0xee, 0x92, 0xbe, 0xea, 0x7a, 0x18, 0x88, 0x2a, 0xdf, 0xc5, 0x85, 0x1d, + 0x8a, 0x18, 0x66, 0xa9, 0xd5, 0xe5, 0x76, 0x23, 0xc0, 0x47, 0x4f, 0xc2, 0xb9, 0x6a, 0x46, 0x21, 0x8c, 0x6a, 0xd6, 0x95, + 0x04, 0x7d, 0x06, 0xa1, 0x91, 0xf5, 0x0c, 0x77, 0x9b, 0xb4, 0xbb, 0x21, 0xc6, 0xc0, 0x63, 0x5b, 0xe3, 0x47, 0x65, 0x71, + 0xe5, 0x55, 0x89, 0x17, 0xa9, 0x73, 0x70, 0xd0, 0xdf, 0x43, 0x9d, 0xfc, 0x1d, 0xb1, 0x6f, 0x73, 0x83, 0xd5, 0x89, 0x34, + 0xf6, 0x00, 0xa7, 0x87, 0x7d, 0x7b, 0x91, 0xc2, 0x15, 0x18, 0x38, 0x97, 0x7f, 0x81, 0x63, 0x34, 0x64, 0xaa, 0xa4, 0x00, + 0x40, 0x29, 0xbe, 0xfd, 0x96, 0x14, 0xfa, 0x30, 0x82, 0x04, 0x80, 0x30, 0x82, 0x03, 0x68, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x08, 0x30, 0x0c, 0x95, 0xe4, 0x78, 0x4f, 0xf3, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 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, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x35, 0x30, 0x39, + 0x32, 0x32, 0x30, 0x36, 0x31, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x30, 0x71, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x22, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, + 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, 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, 0xd9, 0xdc, 0x8b, 0xf5, 0x7a, 0x4e, 0xb8, 0xcb, 0xee, 0x25, + 0xb2, 0xd6, 0x6a, 0x36, 0x16, 0xd6, 0xf6, 0xdf, 0x9d, 0xd6, 0xcc, 0x65, 0xf3, 0xf4, 0x89, 0xb2, 0x06, 0x3e, 0x41, 0xfd, + 0xc2, 0xf8, 0x5a, 0x7b, 0x16, 0x90, 0x03, 0x9a, 0x60, 0x7c, 0xb0, 0x93, 0x1e, 0x20, 0xc0, 0x8a, 0xce, 0x13, 0x08, 0xd5, + 0x2e, 0x4d, 0x88, 0xd1, 0x10, 0xdc, 0xef, 0xc1, 0x62, 0x50, 0x5a, 0x8b, 0x77, 0x2e, 0x4f, 0x53, 0xa1, 0x0a, 0x0f, 0xb3, + 0xb1, 0xd2, 0x00, 0xd6, 0x6b, 0x6f, 0xa0, 0x20, 0x52, 0xe7, 0x91, 0x4e, 0x9e, 0xd0, 0x85, 0xa6, 0xcd, 0x76, 0x1a, 0xd0, + 0x58, 0x2a, 0x1d, 0xa2, 0x9b, 0xd4, 0xf7, 0xae, 0x05, 0xe7, 0x0a, 0xab, 0xd6, 0x0f, 0x74, 0x29, 0x5b, 0x88, 0x46, 0xc4, + 0x6b, 0x73, 0x4d, 0x56, 0x9d, 0x91, 0xb6, 0x11, 0xc5, 0xab, 0xc0, 0xc7, 0x19, 0x1d, 0x78, 0xe4, 0xa9, 0x2f, 0x8e, 0x0b, + 0x7f, 0x97, 0x85, 0x3a, 0x61, 0x32, 0x1d, 0x94, 0x59, 0x59, 0x30, 0xe6, 0xf7, 0xbc, 0x33, 0x74, 0x74, 0x54, 0x6e, 0xe8, + 0x90, 0xc9, 0xb4, 0xc6, 0x9a, 0xb7, 0x44, 0x02, 0xd7, 0x95, 0x60, 0x72, 0x4c, 0xe2, 0x8f, 0xe9, 0xf8, 0x53, 0x44, 0xd2, + 0x1a, 0x15, 0xac, 0x14, 0xe8, 0x93, 0x9c, 0xe6, 0xd8, 0xf1, 0xa3, 0xc1, 0x59, 0x29, 0x6f, 0x92, 0xb4, 0x53, 0xf4, 0x68, + 0x47, 0x9b, 0x81, 0xcf, 0xfc, 0x7c, 0xe8, 0x65, 0x6c, 0xcd, 0x54, 0x44, 0x80, 0x87, 0xef, 0x45, 0x07, 0x98, 0x82, 0x1d, + 0x07, 0x9b, 0xf2, 0x1f, 0xcc, 0x22, 0x81, 0x98, 0x18, 0xbf, 0x4c, 0x14, 0xb3, 0x2c, 0xa7, 0xae, 0x00, 0x9a, 0x7a, 0x3c, + 0x1e, 0xd1, 0x0d, 0xef, 0xeb, 0x95, 0xba, 0xd4, 0xd4, 0x8d, 0x75, 0x0f, 0xa0, 0x00, 0x01, 0x64, 0x98, 0x49, 0x17, 0x2b, + 0xe3, 0xfb, 0xeb, 0x3e, 0x4d, 0xbd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x24, 0x30, 0x82, 0x01, 0x20, 0x30, + 0x51, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x35, 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, 0x65, 0x73, 0x74, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x72, 0x6f, 0x6f, 0x74, + 0x63, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xbe, 0x46, 0x64, 0xc6, 0xc9, 0x6d, 0x92, + 0x89, 0x11, 0x41, 0x60, 0x91, 0x87, 0xf1, 0x64, 0x7c, 0x78, 0xd2, 0x7c, 0x94, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, + 0x16, 0x80, 0x14, 0x59, 0xb8, 0x2b, 0x94, 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, 0x33, 0xc9, 0x59, + 0xc3, 0x54, 0x98, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, + 0x86, 0x31, 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, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0d, 0x30, 0x0b, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x04, 0x01, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, + 0x06, 0x02, 0x13, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0x1b, 0x61, 0x6c, 0x35, 0xb9, 0x13, 0xb9, 0xb9, 0xac, 0xdc, 0x31, 0x8a, + 0x9c, 0x09, 0xb0, 0x5a, 0xe4, 0x63, 0x07, 0x0e, 0x74, 0xeb, 0xe8, 0x37, 0x28, 0x62, 0x39, 0xdb, 0x25, 0xbe, 0x6c, 0xff, + 0xea, 0x1b, 0xd4, 0x3f, 0x50, 0x23, 0xbd, 0xa6, 0x91, 0x1c, 0xfe, 0x9c, 0x2f, 0x52, 0xb6, 0x67, 0x2b, 0xf1, 0x7a, 0x9c, + 0xd8, 0x66, 0x6c, 0x07, 0xeb, 0x11, 0x88, 0x68, 0x66, 0x2b, 0xb6, 0xd0, 0x72, 0xdb, 0xcc, 0x3a, 0xa8, 0xb8, 0xb8, 0x1f, + 0xd0, 0x05, 0xaa, 0xb3, 0xb2, 0x7b, 0xc1, 0xa9, 0xfe, 0x5e, 0xd3, 0x1b, 0xfb, 0x88, 0xba, 0x60, 0xbe, 0x1e, 0xb1, 0x63, + 0x8a, 0xae, 0x21, 0x35, 0xc6, 0xc0, 0x42, 0xe0, 0xa3, 0x1a, 0xc3, 0x37, 0x25, 0x5c, 0xc5, 0xca, 0x35, 0x65, 0x4d, 0x6d, + 0x9c, 0x13, 0x69, 0xb5, 0xde, 0x07, 0x4c, 0xf8, 0x54, 0x96, 0x9a, 0x60, 0x94, 0xca, 0x1d, 0xa3, 0xb7, 0xf6, 0x49, 0x86, + 0x26, 0x06, 0xa8, 0x6a, 0x70, 0x22, 0x54, 0x4a, 0xd4, 0xfd, 0xd8, 0x2d, 0xae, 0xc1, 0x35, 0x42, 0xac, 0x50, 0x03, 0xe3, + 0x34, 0xd7, 0x52, 0xb5, 0x9e, 0xeb, 0xb6, 0x41, 0x98, 0x0b, 0xdd, 0xec, 0xf9, 0x7e, 0x5a, 0x55, 0xd2, 0xf5, 0x4c, 0xb5, + 0x78, 0x1a, 0xd8, 0x23, 0x31, 0xff, 0x67, 0x7e, 0x7f, 0x05, 0xd6, 0x20, 0x7f, 0xe4, 0x34, 0xd4, 0xd3, 0x8e, 0x8d, 0x75, + 0xe1, 0x8c, 0xf1, 0x60, 0x26, 0x4b, 0x88, 0x87, 0x6b, 0xbd, 0x88, 0x1d, 0xe2, 0xa6, 0x9b, 0xbf, 0x4d, 0xed, 0xd7, 0x31, + 0x13, 0x8f, 0xa0, 0x64, 0x63, 0x27, 0xbc, 0x06, 0xce, 0x9d, 0x91, 0xa4, 0x8d, 0xd3, 0x10, 0x25, 0x0c, 0xe7, 0xac, 0xef, + 0x7f, 0x21, 0xf1, 0xfb, 0xca, 0x80, 0x28, 0x0c, 0x4a, 0xd4, 0x52, 0x61, 0xbc, 0x7c, 0x3b, 0x88, 0x54, 0x16, 0x0e, 0x5f, + 0x14, 0x99, 0x4f, 0x30, 0x82, 0x04, 0xcc, 0x30, 0x82, 0x03, 0xb4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x3d, 0x00, + 0x4b, 0x90, 0x3e, 0xde, 0xe0, 0xd0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, + 0x00, 0x30, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 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, 0x1b, 0x30, + 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, + 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x34, 0x32, 0x32, 0x30, 0x32, 0x31, 0x35, + 0x34, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x67, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 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, 0x1b, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, + 0x20, 0x43, 0x41, 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, 0xc7, 0xd1, 0x43, 0x53, + 0x7f, 0x0d, 0x88, 0x6b, 0xe6, 0xb1, 0x67, 0x9d, 0xee, 0x67, 0xb6, 0xe7, 0x77, 0x12, 0x81, 0xc4, 0xdf, 0x24, 0x6b, 0x7a, + 0x75, 0x24, 0xf7, 0x01, 0x09, 0xce, 0x34, 0x92, 0xf5, 0x38, 0x08, 0x42, 0x7e, 0xec, 0x9d, 0xf2, 0x5d, 0x38, 0x91, 0xb4, + 0x93, 0x98, 0x35, 0x11, 0x3c, 0x98, 0x00, 0x77, 0xd9, 0xd7, 0xf3, 0x4a, 0xf8, 0xf0, 0xbc, 0xeb, 0x97, 0x5d, 0x4b, 0x61, + 0x2e, 0xfb, 0xc5, 0xcc, 0x68, 0xb7, 0x6d, 0x69, 0x10, 0xcc, 0xa5, 0x61, 0x78, 0xa8, 0x81, 0x02, 0x9e, 0xe7, 0x63, 0xc5, + 0xff, 0x29, 0x22, 0x82, 0x68, 0xaa, 0xaa, 0x0e, 0xfb, 0xa9, 0xd8, 0x16, 0x73, 0x25, 0xbf, 0x9d, 0x08, 0x62, 0x2f, 0x78, + 0x04, 0xf6, 0xf6, 0x44, 0x07, 0x37, 0x6e, 0x99, 0x1b, 0x93, 0xd8, 0x7f, 0xee, 0x72, 0xde, 0xe8, 0x32, 0xf6, 0x6d, 0x78, + 0x04, 0xa0, 0xa8, 0x21, 0x26, 0x8a, 0x32, 0xe3, 0xb1, 0x65, 0x85, 0xa1, 0x7b, 0x1a, 0xa9, 0x02, 0xb2, 0xbb, 0xee, 0xdd, + 0xdd, 0x8f, 0x41, 0x49, 0xc8, 0x3f, 0xdc, 0x1e, 0xdf, 0x21, 0xa3, 0x95, 0x99, 0xbb, 0xfc, 0x29, 0xba, 0x40, 0x43, 0xb9, + 0x1c, 0xcd, 0xc9, 0x21, 0x45, 0x73, 0xad, 0xff, 0xfd, 0xa2, 0x6c, 0x5c, 0x3b, 0x1c, 0x37, 0x91, 0x34, 0x8e, 0x5c, 0xd3, + 0xd5, 0x03, 0x58, 0x28, 0xc7, 0xf2, 0x76, 0x6f, 0x11, 0xc0, 0xb5, 0xbd, 0x7e, 0xef, 0x23, 0xb3, 0x3d, 0xb8, 0xbd, 0x38, + 0x66, 0x8c, 0xf2, 0x78, 0x95, 0xc1, 0x8b, 0x32, 0x65, 0x3a, 0x9b, 0x49, 0x1a, 0x5c, 0x41, 0x3c, 0xc6, 0x85, 0x50, 0xec, + 0x85, 0xf0, 0x59, 0x17, 0x81, 0xe8, 0x96, 0xe8, 0x6a, 0xcc, 0xb3, 0xc7, 0x46, 0xbf, 0x81, 0x48, 0xd1, 0x09, 0x1b, 0xbc, + 0x73, 0x1e, 0xd7, 0xe8, 0x27, 0xa8, 0x49, 0x48, 0xa2, 0x1c, 0x41, 0x1d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, + 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x59, 0xb8, 0x2b, 0x94, + 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, 0x33, 0xc9, 0x59, 0xc3, 0x54, 0x98, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x59, 0xb8, 0x2b, 0x94, 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, + 0x33, 0xc9, 0x59, 0xc3, 0x54, 0x98, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x08, 0x30, + 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, + 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, + 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, + 0xb6, 0x0c, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, + 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x10, + 0x5e, 0x6c, 0x69, 0xfc, 0xa6, 0x0f, 0xe2, 0x09, 0xd5, 0x94, 0x90, 0xa6, 0x7c, 0x22, 0xdc, 0xee, 0xb0, 0x8f, 0x24, 0x22, + 0x4f, 0xb3, 0x67, 0xdb, 0x32, 0xb0, 0xd6, 0x24, 0x87, 0xe6, 0xf3, 0xea, 0x9e, 0xd0, 0x95, 0x75, 0xaa, 0xa7, 0x08, 0xff, + 0xb0, 0x35, 0xd7, 0x1f, 0xa3, 0xbf, 0x89, 0x55, 0x0c, 0x1c, 0xa4, 0xd0, 0xf8, 0x00, 0x17, 0x44, 0x94, 0x36, 0x63, 0x3b, + 0x83, 0xfe, 0x4e, 0xe5, 0xb3, 0xec, 0x7b, 0x7d, 0xce, 0xfe, 0xa9, 0x54, 0xed, 0xbb, 0x12, 0xa6, 0x72, 0x2b, 0xb3, 0x48, + 0x00, 0xc7, 0x8e, 0xf5, 0x5b, 0x68, 0xc9, 0x24, 0x22, 0x7f, 0xa1, 0x4d, 0xfc, 0x54, 0xd9, 0xd0, 0x5d, 0x82, 0x53, 0x71, + 0x29, 0x66, 0xcf, 0x0f, 0x6d, 0x32, 0xa6, 0x3f, 0xae, 0x54, 0x27, 0xc2, 0x8c, 0x12, 0x4c, 0xf0, 0xd6, 0xc1, 0x80, 0x75, + 0xc3, 0x33, 0x19, 0xd1, 0x8b, 0x58, 0xe6, 0x00, 0x69, 0x76, 0xe7, 0xe5, 0x3d, 0x47, 0xf9, 0xc0, 0x9c, 0xe7, 0x19, 0x1e, + 0x95, 0xbc, 0x52, 0x15, 0xce, 0x94, 0xf8, 0x30, 0x14, 0x0b, 0x39, 0x0e, 0x8b, 0xaf, 0x29, 0x30, 0x56, 0xaf, 0x5a, 0x28, + 0xac, 0xe1, 0x0f, 0x51, 0x76, 0x76, 0x9a, 0xe7, 0xb9, 0x7d, 0xa3, 0x30, 0xe8, 0xe3, 0x71, 0x15, 0xe8, 0xbf, 0x0d, 0x4f, + 0x12, 0x9b, 0x65, 0xab, 0xef, 0xa4, 0xe9, 0x42, 0xf0, 0xd2, 0x4d, 0x20, 0x55, 0x29, 0x88, 0x58, 0x5c, 0x82, 0x67, 0x63, + 0x20, 0x50, 0xc6, 0xca, 0x04, 0xe8, 0xbc, 0x3d, 0x93, 0x06, 0x21, 0xb2, 0xc0, 0xbf, 0x53, 0x1e, 0xe1, 0x8b, 0x48, 0xa9, + 0xb9, 0xd7, 0xe6, 0x5f, 0x4e, 0x5a, 0x2f, 0x43, 0xac, 0x35, 0xbd, 0x26, 0x60, 0x2f, 0x01, 0xd5, 0x86, 0x6b, 0x64, 0xfa, + 0x67, 0x05, 0x44, 0x55, 0x83, 0x5b, 0x93, 0x9c, 0x7c, 0xa7, 0x26, 0x4e, 0x02, 0x2b, 0x48, 0x31, 0x82, 0x12, 0x71, 0x30, + 0x82, 0x12, 0x6d, 0x02, 0x01, 0x03, 0xa0, 0x16, 0x04, 0x14, 0x4e, 0xe9, 0xa9, 0xc3, 0x2e, 0x25, 0xd2, 0xa2, 0x7a, 0x8b, + 0x52, 0x3d, 0x16, 0x3c, 0xaf, 0xee, 0x41, 0xef, 0x79, 0x01, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0xa0, 0x69, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x51, 0xc4, 0xbf, 0xb0, 0x32, 0xf1, 0x05, 0x0d, 0xd1, 0x16, 0x4f, 0x18, + 0x9f, 0x54, 0x93, 0x36, 0x1c, 0x86, 0xad, 0x78, 0xcc, 0x14, 0x3f, 0xc1, 0xa5, 0x90, 0x1e, 0x78, 0x47, 0x05, 0xb4, 0x4d, + 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x03, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x39, 0x31, + 0x32, 0x33, 0x31, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x6d, 0xb7, 0x63, 0x59, 0x7a, 0xbb, 0x28, 0xdf, 0xd2, 0x41, 0x3c, + 0x6c, 0x39, 0xbb, 0x42, 0x49, 0x82, 0xa9, 0x21, 0x09, 0xb1, 0x83, 0x54, 0x17, 0xf4, 0x7d, 0x91, 0x92, 0x36, 0xce, 0x2d, + 0x86, 0xf2, 0xbb, 0x1d, 0x7a, 0xb7, 0x90, 0x13, 0x95, 0xd3, 0x42, 0x94, 0x92, 0x12, 0xd3, 0xec, 0xd2, 0xdb, 0x6a, 0xcb, + 0x3f, 0x63, 0x5a, 0x02, 0x8f, 0xe8, 0x8e, 0x34, 0x67, 0xfa, 0xa0, 0x6d, 0x49, 0xa0, 0xfe, 0xd9, 0xd2, 0x1f, 0x38, 0xdd, + 0x54, 0x45, 0xa3, 0xd1, 0x15, 0xc0, 0xdb, 0x3e, 0xb8, 0x0a, 0xa9, 0xce, 0x5c, 0x46, 0x7b, 0x76, 0xa5, 0x34, 0x4f, 0xe6, + 0x33, 0x27, 0x41, 0x3c, 0xff, 0x8d, 0x8d, 0x7b, 0xec, 0x5c, 0xa8, 0xa9, 0x6b, 0x79, 0x30, 0xde, 0xe2, 0x50, 0x80, 0x92, + 0xb2, 0x0d, 0x69, 0xca, 0x60, 0x72, 0x04, 0xd7, 0x40, 0x80, 0xb6, 0xc9, 0xcb, 0x97, 0x89, 0x0b, 0x9a, 0xa6, 0x20, 0x7e, + 0xc2, 0xef, 0xc6, 0xc3, 0x72, 0x6e, 0x08, 0x7b, 0x38, 0x2d, 0x08, 0xc4, 0x97, 0xdd, 0x61, 0x76, 0x0e, 0xe7, 0xae, 0x28, + 0x61, 0xbf, 0x41, 0xa6, 0x06, 0x9f, 0x7a, 0x00, 0xd9, 0x38, 0x42, 0xdc, 0x7e, 0xba, 0xfd, 0xa9, 0x11, 0xa5, 0x81, 0x80, + 0xa8, 0x9c, 0x18, 0xba, 0xda, 0xef, 0x16, 0x29, 0x70, 0xbf, 0x76, 0xe5, 0x95, 0x85, 0x2f, 0xf6, 0xa2, 0xa5, 0x7b, 0x82, + 0x84, 0x37, 0xd2, 0xf5, 0xc4, 0x9b, 0x45, 0xd0, 0x64, 0x22, 0xf1, 0xdd, 0xd0, 0x60, 0x57, 0xb2, 0xfb, 0xb2, 0x5f, 0xa1, + 0x40, 0xf9, 0x3b, 0xf5, 0x06, 0x36, 0x49, 0x8f, 0x58, 0x1e, 0x48, 0x96, 0xff, 0xec, 0x57, 0xbd, 0x17, 0xf8, 0x4b, 0xf3, + 0xb4, 0x5d, 0x06, 0x9f, 0xe8, 0x94, 0x6d, 0x27, 0xe4, 0x78, 0x3a, 0x73, 0x47, 0xc3, 0x52, 0xd1, 0x74, 0x41, 0x74, 0x32, + 0xa6, 0x98, 0x3c, 0xc4, 0x65, 0xa1, 0x82, 0x10, 0xc3, 0x30, 0x82, 0x10, 0xbf, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0e, 0x31, 0x82, 0x10, 0xae, 0x30, 0x82, 0x10, 0xaa, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x10, 0x9b, 0x30, 0x82, 0x10, 0x97, 0x02, 0x01, 0x03, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x6d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x10, 0x01, 0x04, 0xa0, 0x5e, 0x04, 0x5c, 0x30, 0x5a, 0x02, 0x01, 0x01, 0x06, 0x02, 0x2a, 0x03, 0x30, 0x31, 0x30, + 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0x51, 0xc4, 0xbf, 0xb0, + 0x32, 0xf1, 0x05, 0x0d, 0xd1, 0x16, 0x4f, 0x18, 0x9f, 0x54, 0x93, 0x36, 0x1c, 0x86, 0xad, 0x78, 0xcc, 0x14, 0x3f, 0xc1, + 0xa5, 0x90, 0x1e, 0x78, 0x47, 0x05, 0xb4, 0x4d, 0x02, 0x08, 0x3b, 0x16, 0xc3, 0xcb, 0x4d, 0x17, 0xe8, 0xc1, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x38, 0x30, 0x33, 0x32, 0x31, 0x31, 0x39, 0x31, 0x34, 0x35, 0x30, 0x5a, 0x30, 0x03, 0x02, 0x01, 0x01, + 0xa0, 0x82, 0x0d, 0xd1, 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x55, + 0xbd, 0xb7, 0x92, 0xdb, 0x54, 0x05, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, + 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 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, 0x33, 0x30, 0x36, 0x30, 0x31, + 0x33, 0x30, 0x30, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x34, 0x31, 0x37, 0x30, 0x31, 0x33, 0x30, 0x30, 0x33, 0x5a, + 0x30, 0x42, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x4e, 0x57, 0x4b, 0x32, 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, 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, 0xbc, 0x9b, 0x45, 0x28, 0x53, 0xe1, 0x51, 0xbf, 0xef, 0x09, 0x31, 0x1d, 0x75, 0x65, 0x97, 0x05, 0x46, 0x6e, 0x59, + 0x18, 0xc2, 0x6d, 0x3a, 0x85, 0x1d, 0x0d, 0x2e, 0x78, 0x7c, 0x50, 0xdf, 0x57, 0x02, 0x32, 0x4f, 0x6b, 0x13, 0xb6, 0x33, + 0xdd, 0xff, 0x44, 0x4a, 0xed, 0xdf, 0x6b, 0xcb, 0xd5, 0x21, 0xd2, 0x96, 0x40, 0x43, 0xde, 0x0f, 0x90, 0x8f, 0x29, 0x6a, + 0x09, 0xf4, 0xac, 0x43, 0xd6, 0xbc, 0x61, 0xbb, 0x47, 0xd7, 0xde, 0xba, 0x4e, 0x68, 0x3a, 0x42, 0x4b, 0x45, 0xcc, 0x76, + 0x15, 0xdb, 0x17, 0x3b, 0x51, 0xbf, 0x73, 0x85, 0x7e, 0x00, 0x2c, 0xa4, 0x0a, 0x94, 0x1e, 0x5c, 0x1b, 0x3b, 0x26, 0xe4, + 0x56, 0x52, 0xb5, 0xc2, 0x78, 0x56, 0xbf, 0x43, 0xb9, 0xab, 0xa2, 0x7a, 0x52, 0xbd, 0x3b, 0x3f, 0x7c, 0x11, 0x88, 0x5f, + 0x8c, 0xf3, 0x36, 0x00, 0xb1, 0xe6, 0x43, 0xdb, 0x84, 0xa4, 0x3e, 0x9e, 0x87, 0xcb, 0x09, 0x25, 0x71, 0x8a, 0x45, 0x9e, + 0xbb, 0x0a, 0x62, 0x4c, 0xfa, 0xcc, 0xaa, 0x97, 0xba, 0x6d, 0x90, 0x9e, 0x0d, 0x0c, 0xac, 0x60, 0xe7, 0x5e, 0x61, 0xa2, + 0xc5, 0x29, 0x5c, 0x64, 0x5f, 0xc3, 0xd8, 0x2c, 0xe7, 0x1b, 0x57, 0x32, 0x79, 0x97, 0xae, 0x97, 0x3f, 0x19, 0x1b, 0xe9, + 0xb9, 0x2a, 0x53, 0x23, 0xfc, 0x9b, 0x3c, 0x88, 0x90, 0xaa, 0x58, 0xde, 0x0b, 0x91, 0x45, 0xb1, 0x26, 0xb9, 0xc0, 0x6d, + 0x9e, 0x3b, 0x1e, 0x56, 0x19, 0x7a, 0xf2, 0x5f, 0xa9, 0x82, 0x9d, 0x88, 0xbe, 0x53, 0x10, 0x02, 0x7f, 0x80, 0x79, 0x15, + 0xc1, 0x60, 0xc7, 0xe0, 0xbf, 0xe9, 0x0c, 0x5c, 0x16, 0xb3, 0x6d, 0xda, 0x61, 0xb2, 0xe8, 0x6d, 0x26, 0xf1, 0xe2, 0xb1, + 0xea, 0x1d, 0x66, 0x42, 0xe7, 0x6c, 0x4a, 0xf2, 0xa4, 0xaa, 0x49, 0xfe, 0xfb, 0x7e, 0xbf, 0x5f, 0xbb, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0xc1, 0x30, 0x82, 0x01, 0xbd, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x60, 0xd9, 0x78, 0x59, 0xea, 0xb0, 0x24, 0x26, 0x69, 0xac, 0xd9, 0xc1, 0xa3, 0xac, 0xb0, 0x50, 0xaa, 0x37, 0xcb, + 0x97, 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, 0x34, 0xcd, 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, + 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 0x30, 0x82, 0x01, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, + 0x05, 0x30, 0x82, 0x01, 0x01, 0x30, 0x81, 0xfe, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, + 0x81, 0xf0, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, + 0x6c, 0x65, 0x63, 0x61, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0xb6, + 0x0c, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, + 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, + 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, + 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x34, 0xf6, 0x34, 0x61, 0x30, + 0x1c, 0x0a, 0xa4, 0xf1, 0x2a, 0x4e, 0x47, 0xf2, 0xb3, 0x5a, 0x6b, 0xfe, 0x9e, 0x33, 0x8f, 0xa6, 0x44, 0x8b, 0xd0, 0x37, + 0x2c, 0xff, 0x00, 0xb3, 0x83, 0xaf, 0x42, 0x2e, 0xa5, 0x98, 0x77, 0x5d, 0x1c, 0x75, 0xbd, 0xaa, 0x68, 0x62, 0x5b, 0xbe, + 0x59, 0x91, 0x9e, 0x58, 0xfd, 0xe4, 0x74, 0xe2, 0x7c, 0x5c, 0xb8, 0xb3, 0xb5, 0x66, 0xda, 0x78, 0xda, 0xf7, 0x58, 0x6f, + 0xcd, 0x50, 0x77, 0x01, 0xe3, 0x99, 0x84, 0xf2, 0x77, 0x66, 0xba, 0x7c, 0xbe, 0x97, 0xe9, 0x2d, 0x2e, 0x83, 0x2d, 0xcc, + 0x73, 0x3a, 0x6a, 0x42, 0xed, 0x58, 0xb0, 0x34, 0x7d, 0xe0, 0xa7, 0x48, 0x6b, 0xe9, 0x39, 0x92, 0xdf, 0x67, 0x05, 0xe5, + 0x01, 0x5e, 0xeb, 0x63, 0xc1, 0x35, 0x3a, 0x58, 0xdc, 0x44, 0x35, 0x39, 0x5c, 0xe5, 0xe0, 0x4d, 0x9b, 0x72, 0xb7, 0x0b, + 0x59, 0x5a, 0x4a, 0x0d, 0x07, 0x61, 0x5d, 0x0f, 0xf8, 0x19, 0x42, 0x10, 0xd9, 0x77, 0xaf, 0xdf, 0x3d, 0xac, 0x86, 0xf0, + 0x5f, 0x66, 0x11, 0x4d, 0x94, 0x38, 0x3f, 0xca, 0xb9, 0x0c, 0xbf, 0xbf, 0x7d, 0x00, 0x51, 0x74, 0x61, 0xd2, 0xc7, 0x75, + 0xab, 0xe4, 0x99, 0x0f, 0x18, 0xd2, 0x5e, 0x6d, 0xa0, 0x2a, 0x96, 0x52, 0x36, 0xa9, 0xa3, 0xbb, 0x20, 0xde, 0x0c, 0x6e, + 0xfa, 0x86, 0x25, 0xee, 0x05, 0x80, 0x7f, 0x56, 0x6a, 0xd7, 0xc8, 0xaa, 0xbc, 0x4b, 0x85, 0x94, 0xe8, 0x38, 0xc5, 0x45, + 0xd8, 0x15, 0x97, 0xde, 0x69, 0x1a, 0x14, 0x04, 0xa4, 0xfc, 0x84, 0x8c, 0xef, 0xe3, 0x23, 0x0d, 0xe1, 0x6b, 0x23, 0x5f, + 0xdf, 0x47, 0x93, 0x22, 0x24, 0xe8, 0x12, 0x2b, 0xbd, 0xd1, 0x6f, 0xcb, 0xb5, 0x65, 0x89, 0xa0, 0x9f, 0x78, 0xb3, 0xdb, + 0x55, 0xf5, 0x34, 0x41, 0x99, 0x00, 0xd8, 0x31, 0x49, 0x00, 0xb9, 0x30, 0x82, 0x04, 0x07, 0x30, 0x82, 0x02, 0xef, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x7d, 0x4c, 0x57, 0x63, 0x9f, 0xf3, 0xf0, 0xb7, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, + 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x35, 0x31, + 0x32, 0x30, 0x32, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x34, 0x30, 0x35, 0x31, 0x32, 0x30, 0x32, 0x34, 0x34, + 0x5a, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 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, 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, + 0xd3, 0x77, 0x18, 0xa1, 0xf7, 0x99, 0x10, 0x67, 0x5c, 0xd2, 0x2e, 0x9e, 0xb8, 0x8f, 0x23, 0x67, 0x3e, 0xfc, 0x42, 0xe2, + 0x09, 0x7d, 0x0a, 0x8a, 0xb8, 0x18, 0xfc, 0x73, 0x40, 0x2f, 0xbd, 0xc4, 0xd8, 0x50, 0xc5, 0x27, 0xc8, 0xfe, 0xb8, 0x34, + 0x70, 0xa0, 0x0d, 0x13, 0x3c, 0xbd, 0x08, 0x4e, 0x9a, 0x93, 0x6f, 0x39, 0x37, 0xda, 0x9e, 0x65, 0xf5, 0xb4, 0x63, 0xf4, + 0x90, 0xc8, 0x49, 0x6d, 0x5d, 0x20, 0xd3, 0x39, 0xfd, 0x09, 0xba, 0xf4, 0x3a, 0xf3, 0xce, 0x4a, 0x69, 0x64, 0x05, 0x99, + 0x46, 0xe0, 0xda, 0x35, 0xc4, 0x65, 0x18, 0x1e, 0xc6, 0x16, 0xa3, 0x12, 0x61, 0xb4, 0x2e, 0xf5, 0xf0, 0x89, 0x0d, 0x8c, + 0xdc, 0x3d, 0xf6, 0x06, 0xcf, 0x6f, 0x86, 0x25, 0x4c, 0x09, 0xc2, 0x1b, 0xc8, 0x0e, 0x78, 0x88, 0x8d, 0xc1, 0x22, 0xb8, + 0xba, 0x21, 0x13, 0x9b, 0xca, 0xee, 0x8a, 0x9e, 0xdd, 0x7b, 0x5b, 0xff, 0xa3, 0xe9, 0xd1, 0xa3, 0x81, 0x7e, 0xfe, 0xff, + 0xe6, 0x8c, 0x49, 0xe4, 0x3b, 0x0a, 0xf9, 0x10, 0xa6, 0x72, 0x33, 0xbb, 0x2c, 0xc4, 0x4a, 0x5a, 0x72, 0x0a, 0x39, 0x50, + 0x74, 0xdd, 0x28, 0x6e, 0x79, 0x5f, 0x7e, 0xa7, 0xa8, 0x14, 0xcf, 0x56, 0xb3, 0x56, 0x6c, 0xa5, 0xe9, 0xf0, 0xc4, 0xae, + 0xf9, 0xea, 0x20, 0x8e, 0x18, 0xc7, 0x28, 0x74, 0xe2, 0x08, 0x4d, 0x89, 0x26, 0x42, 0x79, 0x5e, 0xf6, 0x60, 0xe3, 0x45, + 0x58, 0xa1, 0xfb, 0x51, 0x49, 0x5e, 0x92, 0x4a, 0x4d, 0xb9, 0xef, 0xd4, 0x73, 0xb5, 0xda, 0x04, 0x7b, 0xe3, 0x52, 0x9f, + 0xcb, 0xa3, 0x19, 0x5d, 0xac, 0x6b, 0x98, 0x6c, 0x9e, 0xe2, 0xec, 0x74, 0x2d, 0x44, 0x3e, 0xe0, 0x61, 0x3e, 0x07, 0x45, + 0x7e, 0x34, 0x75, 0x26, 0x98, 0x40, 0x9b, 0x75, 0x9e, 0xc8, 0x30, 0xed, 0x4b, 0xbf, 0x77, 0x8f, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x34, 0xcd, + 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, + 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x27, 0x30, 0x25, 0x30, + 0x23, 0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, + 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x63, 0x64, 0x06, 0x02, 0x09, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x36, 0xd2, 0xf5, 0xde, 0x71, 0x53, 0x07, 0xc9, 0x23, 0xd8, + 0x78, 0x9b, 0x65, 0xbc, 0xf3, 0xd5, 0x5b, 0xe9, 0xb8, 0x7f, 0x1b, 0x23, 0xc7, 0xa2, 0xcf, 0xb4, 0xa9, 0x28, 0xe9, 0xf8, + 0xdd, 0x70, 0x88, 0x21, 0x39, 0xf3, 0xdb, 0x33, 0x9c, 0xc3, 0x72, 0x43, 0xd6, 0x3d, 0x42, 0x51, 0x97, 0xba, 0xad, 0x1d, + 0x8e, 0x92, 0xd2, 0x75, 0x8b, 0xc3, 0x5d, 0x9c, 0xf5, 0xcb, 0x8c, 0xdc, 0x6a, 0x6a, 0x3a, 0xdd, 0xeb, 0x54, 0x7d, 0xed, + 0x14, 0x6b, 0xf3, 0xd6, 0x3e, 0x93, 0xc8, 0x6d, 0x7a, 0x54, 0x5f, 0xf2, 0x43, 0x8e, 0x10, 0xd0, 0x76, 0x5c, 0x9b, 0x00, + 0x0c, 0x1d, 0x4e, 0xca, 0x3c, 0xcd, 0xfa, 0xe6, 0xf7, 0xc2, 0x3e, 0x72, 0xb7, 0xb8, 0xde, 0xe8, 0x34, 0xaa, 0x15, 0xa0, + 0xae, 0x5c, 0x67, 0xa8, 0x0c, 0xac, 0x9b, 0x1e, 0x65, 0xb3, 0xe3, 0x0f, 0x30, 0x42, 0x34, 0xe9, 0xae, 0xd3, 0x01, 0xd3, + 0xa7, 0xdd, 0x42, 0x73, 0x75, 0x7c, 0x51, 0x43, 0x85, 0x9a, 0x60, 0x10, 0xdc, 0xae, 0x27, 0xd2, 0x6b, 0x67, 0xc9, 0x33, + 0x45, 0x6f, 0xc9, 0x98, 0x1e, 0xa0, 0x9a, 0x7f, 0x4d, 0x11, 0x93, 0xe1, 0x69, 0xff, 0xec, 0x4b, 0x45, 0xf3, 0x4e, 0xca, + 0x22, 0x0e, 0x57, 0xd7, 0x22, 0x07, 0xe5, 0x22, 0xb4, 0x87, 0xe9, 0x9c, 0xd3, 0x45, 0xcb, 0x6e, 0x3f, 0xe5, 0x8e, 0xb8, + 0xfc, 0x46, 0xd5, 0x5c, 0xc9, 0xb0, 0xab, 0x05, 0x3a, 0x6d, 0x37, 0x28, 0xa3, 0xa8, 0x46, 0x65, 0x6f, 0x55, 0xa1, 0x68, + 0x88, 0xea, 0x52, 0x3e, 0xc9, 0xf4, 0xd4, 0xe6, 0xfa, 0x3f, 0xa4, 0xe4, 0x26, 0x80, 0xb5, 0x3a, 0x6b, 0xd6, 0xc3, 0xe5, + 0xf9, 0x32, 0x81, 0xc8, 0x32, 0xa2, 0x48, 0xe1, 0x8e, 0x06, 0xa3, 0x19, 0xe4, 0xb3, 0xcb, 0x3b, 0x4b, 0xdf, 0xe0, 0xcc, + 0x0e, 0xb2, 0xaf, 0x98, 0xd1, 0x83, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x62, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, + 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, + 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, + 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 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, 0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84, 0x2d, 0xeb, + 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30, 0x02, 0xe8, + 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3, + 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b, 0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4, + 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25, 0x03, 0xba, + 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d, 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, + 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f, 0x70, 0xb6, 0x3f, + 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e, + 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74, + 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, 0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb, + 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62, 0x0b, 0x10, + 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c, 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, + 0x73, 0xff, 0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, + 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, + 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, + 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, + 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, + 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, + 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, + 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, 0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2, + 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b, 0x40, 0x8e, + 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f, 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, + 0x3e, 0xf9, 0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1, 0xbf, 0x9a, + 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b, + 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d, + 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5, 0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2, + 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8, 0x44, 0x48, + 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7, 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, + 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda, 0x0f, 0x21, 0x0e, + 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8, + 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c, + 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, 0x09, 0x07, 0x37, 0xb0, 0x75, 0x75, + 0x21, 0x31, 0x82, 0x02, 0x3f, 0x30, 0x82, 0x02, 0x3b, 0x02, 0x01, 0x01, 0x30, 0x81, 0x88, 0x30, 0x7c, 0x31, 0x30, 0x30, + 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 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, 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, 0x02, 0x08, 0x55, 0xbd, 0xb7, 0x92, 0xdb, 0x54, 0x05, 0xfd, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0x00, 0xa0, 0x81, 0x8c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0d, + 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32, 0x31, 0x31, 0x39, 0x31, 0x34, + 0x35, 0x30, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14, + 0x0e, 0xf0, 0xad, 0x61, 0xed, 0x39, 0xbe, 0xbc, 0x79, 0xf7, 0xad, 0x2b, 0x19, 0x8d, 0xb1, 0xb1, 0xc3, 0x9d, 0x27, 0xa1, + 0x30, 0x2b, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0c, 0x31, 0x1c, 0x30, 0x1a, 0x30, + 0x18, 0x30, 0x16, 0x04, 0x14, 0xc5, 0xe5, 0x93, 0x54, 0xe1, 0x09, 0x59, 0x31, 0x49, 0x9b, 0x0e, 0xde, 0xbb, 0xda, 0x5c, + 0xc9, 0x20, 0x94, 0x1c, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x04, 0x82, 0x01, 0x00, 0x73, 0x96, 0x28, 0x77, 0xa2, 0x30, 0x0a, 0x61, 0xee, 0x07, 0x0c, 0x85, 0x7c, 0xaa, 0x37, 0xa4, + 0xda, 0x0f, 0xd2, 0xca, 0x0d, 0xa3, 0xf7, 0xc8, 0x1c, 0x20, 0x8d, 0xd1, 0x82, 0xda, 0xa0, 0x7d, 0xf5, 0x72, 0x49, 0x2d, + 0x11, 0x28, 0xe4, 0xb4, 0x71, 0x3e, 0xf7, 0x7b, 0x50, 0x74, 0x28, 0x0d, 0xee, 0x05, 0x5d, 0xc2, 0x5b, 0xe9, 0xfc, 0xee, + 0x48, 0x40, 0x1d, 0x84, 0x31, 0x8e, 0x78, 0x08, 0xb5, 0xa0, 0xaf, 0xf0, 0x29, 0xe9, 0xd4, 0x39, 0xd2, 0xff, 0xfb, 0x62, + 0xda, 0x5e, 0x4f, 0xa5, 0xe4, 0x32, 0x1e, 0xdd, 0xce, 0xf7, 0x1f, 0xf3, 0x79, 0x0c, 0xf2, 0x67, 0x8d, 0xc9, 0x5d, 0x68, + 0xe6, 0xe5, 0x8d, 0x15, 0x1a, 0x94, 0x98, 0x28, 0x38, 0xa6, 0x34, 0xe4, 0x90, 0x18, 0x4b, 0xea, 0x78, 0xa0, 0xc3, 0x04, + 0x2e, 0x2d, 0x54, 0x41, 0xd5, 0x9c, 0x6d, 0xbf, 0xc9, 0xa5, 0x65, 0xe1, 0xd5, 0xe3, 0xf2, 0xcd, 0xc0, 0x52, 0x40, 0x35, + 0xa1, 0xdd, 0x56, 0xff, 0x96, 0x6c, 0xa8, 0x81, 0x8a, 0x40, 0x61, 0x05, 0x8c, 0xa1, 0xd0, 0xf7, 0xce, 0x9b, 0xe1, 0x05, + 0x83, 0xc1, 0xf5, 0x6e, 0x5e, 0x33, 0xd2, 0x7d, 0xd1, 0x96, 0x31, 0x68, 0xd3, 0xdb, 0x63, 0x4c, 0xa5, 0xf7, 0xac, 0x9d, + 0xe5, 0x1c, 0x93, 0x23, 0x5a, 0x1e, 0x7c, 0x13, 0x58, 0xf7, 0x3a, 0xff, 0x92, 0x46, 0xee, 0xec, 0xf5, 0x9b, 0x54, 0x27, + 0x3e, 0xa7, 0x22, 0x26, 0xe4, 0x24, 0xd1, 0x07, 0x51, 0xfc, 0xa1, 0x50, 0x7d, 0xa7, 0xf9, 0x44, 0x82, 0x84, 0x23, 0x13, + 0x40, 0x19, 0xfd, 0x1d, 0x9f, 0x1f, 0x65, 0x24, 0x17, 0x96, 0x56, 0xa8, 0xcf, 0x85, 0xc3, 0xe5, 0x2a, 0x68, 0x56, 0xd1, + 0x6f, 0x6d, 0x15, 0x87, 0xaa, 0x64, 0x9e, 0xf1, 0xaf, 0x74, 0x95, 0x71, 0xd0, 0x4a, 0x8f, 0x73, 0x9a, 0x7f, 0x31, 0xdd +}; + +/* MARK: Developer ID Signature + * This timestamp has a matching MessageImprint */ +uint8_t _developer_id_data[] = { + 0xfa, 0xde, 0x0c, 0x02, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x7e, 0x00, 0x14, 0x01, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6b, 0x37, 0x32, + 0x2e, 0x43, 0x68, 0x61, 0x72, 0x6c, 0x65, 0x73, 0x00, 0x39, 0x41, 0x35, 0x50, 0x43, 0x55, 0x34, 0x46, 0x53, 0x44, 0x00, + 0x0a, 0x91, 0x11, 0xba, 0x5e, 0xbb, 0xcb, 0x30, 0xbc, 0xf0, 0x20, 0x12, 0xc4, 0x12, 0x87, 0xa6, 0x38, 0x7f, 0x94, 0x85, + 0x19, 0xa0, 0x1f, 0x76, 0x50, 0xfb, 0xd9, 0x8e, 0x42, 0xe8, 0x5c, 0x37, 0xd8, 0x91, 0xb2, 0xdd, 0xee, 0x43, 0xb4, 0xc7, + 0x65, 0x23, 0x39, 0xb8, 0x34, 0xec, 0x43, 0x13, 0xe2, 0xf4, 0x87, 0xf8, 0x53, 0x8b, 0x9a, 0x45, 0x1a, 0x3b, 0x3c, 0x6b, + 0x45, 0xe3, 0xec, 0x96, 0xcb, 0x55, 0x5a, 0xbe, 0x6d, 0x39, 0x63, 0x11, 0x74, 0x28, 0x6b, 0x74, 0x9f, 0xb2, 0x39, 0x04, + 0x60, 0xd4, 0x71, 0x64, 0xe5, 0xf2, 0xe1, 0xae, 0x3f, 0xb0, 0x20, 0xa1, 0xee, 0x3a, 0x54, 0x0b, 0x2d, 0x50, 0x47, 0x6c, + 0x10, 0x94, 0x66, 0x5a, 0x03, 0xaa, 0x49, 0xe4, 0x9c, 0xf4, 0xbd, 0x0b, 0xeb, 0xe1, 0xaf, 0xf8, 0x7e, 0x8a, 0x53, 0x05, + 0xf5, 0x0e, 0xa4, 0x2a, 0x45, 0x4a, 0x8e, 0xd1, 0x1e, 0xed, 0x98, 0x10, 0x0b, 0x66, 0x4b, 0xc4, 0x31, 0x4b, 0xed, 0x80, + 0x6c, 0x80, 0x34, 0xf5, 0xe3, 0x91, 0x9d, 0x46, 0xea, 0x6f, 0x94, 0x59, 0x84, 0x38, 0x8f, 0x1e, 0x3d, 0xcc, 0x4a, 0x29, + 0xaf, 0xe2, 0x52, 0x65, 0x92, 0xa9, 0x9e, 0xc0, 0xfd, 0x26, 0xb7, 0xed, 0xb6, 0x65, 0x9e, 0xcf, 0xe9, 0x6c, 0xf7, 0x4b, + 0x5f, 0x24, 0x87, 0x95, 0xc4, 0x8f, 0xd8, 0x6c, 0x6c, 0x06, 0x5d, 0x96, 0x06, 0xa7, 0x9d, 0xf4, 0x97, 0xf5, 0xc3, 0x0c, + 0xea, 0x8f, 0x54, 0xf4, 0xe3, 0x3e, 0x08, 0xe5, 0x9a, 0x64, 0xbd, 0xe3, 0x79, 0xc0, 0xc0, 0xe0, 0xf8, 0x7f, 0xfc, 0xe3 +}; + +uint8_t _developer_id_sig[] = { + 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, + 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x00, 0x00, 0xa0, 0x82, 0x0e, 0x3d, 0x30, 0x82, 0x04, 0x04, + 0x30, 0x82, 0x02, 0xec, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x18, 0x7a, 0xa9, 0xa8, 0xc2, 0x96, 0x21, 0x0c, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, + 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, + 0x30, 0x32, 0x30, 0x31, 0x32, 0x32, 0x31, 0x32, 0x31, 0x35, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x32, 0x30, 0x31, 0x32, + 0x32, 0x31, 0x32, 0x31, 0x35, 0x5a, 0x30, 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x44, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x49, 0x44, 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, 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, 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, 0x89, 0x76, 0x4f, 0x06, 0x5b, 0x9a, 0x41, 0xee, 0xa5, 0x23, 0x2b, 0x02, 0xa3, 0x5f, 0xd7, 0x73, 0x3f, 0xc0, + 0x35, 0xb0, 0x8b, 0x84, 0x0a, 0x3f, 0x06, 0x24, 0x7f, 0xa7, 0x95, 0x3f, 0xeb, 0x4f, 0x0e, 0x93, 0xaf, 0xb4, 0x0e, 0xd0, + 0xc8, 0x3e, 0xe5, 0x6d, 0x18, 0xb3, 0x1f, 0xe8, 0x89, 0x47, 0xbf, 0xd7, 0x09, 0x08, 0xe4, 0xff, 0x56, 0x98, 0x29, 0x15, + 0xe7, 0x94, 0x9d, 0xb9, 0x35, 0xa3, 0x0a, 0xcd, 0xb4, 0xc0, 0xe1, 0xe2, 0x60, 0xf4, 0xca, 0xec, 0x29, 0x78, 0x45, 0x69, + 0x69, 0x60, 0x6b, 0x5f, 0x8a, 0x92, 0xfc, 0x9e, 0x23, 0xe6, 0x3a, 0xc2, 0x22, 0xb3, 0x31, 0x4f, 0x1c, 0xba, 0xf2, 0xb6, + 0x34, 0x59, 0x42, 0xee, 0xb0, 0xa9, 0x02, 0x03, 0x18, 0x91, 0x04, 0xb6, 0xb3, 0x78, 0x2e, 0x33, 0x1f, 0x80, 0x45, 0x0d, + 0x45, 0x6f, 0xbb, 0x0e, 0x5a, 0x5b, 0x7f, 0x3a, 0xe7, 0xd8, 0x08, 0xd7, 0x0b, 0x0e, 0x32, 0x6d, 0xfb, 0x86, 0x36, 0xe4, + 0x6c, 0xab, 0xc4, 0x11, 0x8a, 0x70, 0x84, 0x26, 0xaa, 0x9f, 0x44, 0xd1, 0xf1, 0xb8, 0xc6, 0x7b, 0x94, 0x17, 0x9b, 0x48, + 0xf7, 0x0b, 0x58, 0x16, 0xba, 0x23, 0xc5, 0x9f, 0x15, 0x39, 0x7e, 0xca, 0x5d, 0xc3, 0x32, 0x5f, 0x0f, 0xe0, 0x52, 0x7f, + 0x40, 0xea, 0xbe, 0xac, 0x08, 0x64, 0x95, 0x5b, 0xc9, 0x1a, 0x9c, 0xe5, 0x80, 0xca, 0x1f, 0x6a, 0x44, 0x1c, 0x6c, 0x3e, + 0xc4, 0xb0, 0x26, 0x1f, 0x1d, 0xec, 0x7b, 0xaf, 0x5e, 0xa0, 0x6a, 0x3d, 0x47, 0xa9, 0x58, 0x12, 0x31, 0x3f, 0x20, 0x76, + 0x28, 0x6d, 0x1d, 0x1c, 0xb0, 0xc2, 0x4e, 0x11, 0x69, 0x26, 0x8b, 0xcb, 0xd6, 0xd0, 0x11, 0x82, 0xc9, 0x4e, 0x0f, 0xf1, + 0x56, 0x74, 0xd0, 0xd9, 0x08, 0x4b, 0x66, 0x78, 0xa2, 0xab, 0xac, 0xa7, 0xe2, 0xd2, 0x4c, 0x87, 0x59, 0xc9, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x57, 0x17, 0xed, 0xa2, 0xcf, 0xdc, 0x7c, 0x98, 0xa1, 0x10, 0xe0, 0xfc, 0xbe, 0x87, 0x2d, 0x2c, 0xf2, 0xe3, 0x17, 0x54, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, + 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x27, 0x30, + 0x25, 0x30, 0x23, 0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, + 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x06, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x42, 0x39, 0x74, 0x6b, 0xa1, 0xdc, 0xc6, 0xa4, + 0x8f, 0x37, 0x2a, 0x8c, 0xb3, 0x1d, 0x0a, 0x44, 0xbc, 0x95, 0x2c, 0x7f, 0xbc, 0x59, 0xb8, 0xac, 0x61, 0xfb, 0x07, 0x90, + 0x92, 0x32, 0xb9, 0xd4, 0xbf, 0x3b, 0xc1, 0x50, 0x39, 0x6a, 0x44, 0x74, 0xa2, 0xec, 0x5b, 0x1f, 0x70, 0xe5, 0xaa, 0xdd, + 0x4b, 0x6c, 0x1c, 0x23, 0x71, 0x2d, 0x5f, 0xd1, 0xc5, 0x93, 0xbe, 0xee, 0x9b, 0x8a, 0x70, 0x65, 0x82, 0x9d, 0x16, 0xe3, + 0x1a, 0x10, 0x17, 0x89, 0x2d, 0xa8, 0xcd, 0xfd, 0x0c, 0x78, 0x58, 0x49, 0x0c, 0x28, 0x7f, 0x33, 0xee, 0x00, 0x7a, 0x1b, + 0xb4, 0x76, 0xac, 0xb6, 0xb5, 0xbb, 0x4f, 0xdf, 0xa8, 0x1b, 0x9d, 0xc8, 0x19, 0x97, 0x4a, 0x0b, 0x56, 0x67, 0x2f, 0xc2, + 0x3e, 0xb6, 0xb3, 0xc4, 0x83, 0x3a, 0xf0, 0x77, 0x6d, 0x74, 0xc4, 0x2e, 0x23, 0x51, 0xee, 0x9a, 0xa5, 0x03, 0x6f, 0x60, + 0xf4, 0xa5, 0x48, 0xa7, 0x06, 0xc2, 0xbb, 0x5a, 0xe2, 0x1f, 0x1f, 0x46, 0x45, 0x7e, 0xe4, 0x97, 0xf5, 0x27, 0x10, 0xb7, + 0x20, 0x22, 0x72, 0x6f, 0x72, 0xda, 0xc6, 0x50, 0x75, 0xc5, 0x3d, 0x25, 0x8f, 0x5d, 0xa3, 0x00, 0xe9, 0x9f, 0x36, 0x8c, + 0x48, 0x39, 0x8f, 0xb3, 0x3b, 0xea, 0x90, 0x80, 0x2e, 0x95, 0x9a, 0x60, 0xf4, 0x78, 0xce, 0xf4, 0x0e, 0x0a, 0x53, 0x3e, + 0xa2, 0xfa, 0x4f, 0xd8, 0x1e, 0xae, 0x84, 0x95, 0x8d, 0x32, 0xbc, 0x56, 0x4d, 0x89, 0xe9, 0x78, 0x18, 0xe0, 0xac, 0x9a, + 0x42, 0xba, 0x7a, 0x46, 0x1b, 0x84, 0xa2, 0x89, 0xce, 0x14, 0xe8, 0x88, 0xd1, 0x58, 0x8b, 0xf6, 0xae, 0x56, 0xc4, 0x2c, + 0x05, 0x2a, 0x45, 0xaf, 0x0b, 0xd9, 0x4b, 0xa9, 0x02, 0x0f, 0x34, 0xac, 0x88, 0xc7, 0x61, 0x55, 0x89, 0x44, 0xc9, 0x27, + 0x73, 0x07, 0xee, 0x82, 0xe5, 0x4e, 0xf5, 0x70, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, + 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, + 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35, + 0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, + 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 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, 0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84, + 0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30, + 0x02, 0xe8, 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11, + 0xd0, 0xa3, 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b, 0xd4, 0x16, 0x37, 0x33, + 0xcb, 0xc4, 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25, + 0x03, 0xba, 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d, 0xb3, 0x94, 0xf7, 0xf6, + 0x9c, 0x9e, 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f, 0x70, + 0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5, + 0xb9, 0x0e, 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16, + 0x2e, 0x74, 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, 0xaf, 0x2f, 0x41, 0xb3, + 0xf8, 0xfb, 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62, + 0x0b, 0x10, 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c, 0x68, 0xb3, 0x8f, 0x1d, + 0xde, 0x65, 0x73, 0xff, 0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0xd0, 0x69, + 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, + 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, + 0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, + 0x05, 0x01, 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, + 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x02, 0x02, 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, + 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, 0x9b, 0xdc, 0xf3, 0x77, + 0x9b, 0xf2, 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b, + 0x40, 0x8e, 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f, 0xcb, 0x79, 0x4f, 0x34, + 0xd8, 0xa2, 0x3e, 0xf9, 0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1, + 0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3, + 0xb7, 0x8b, 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca, + 0xf1, 0x6d, 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5, 0xd9, 0x0f, 0xd6, 0x6b, + 0xd4, 0xa2, 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8, + 0x44, 0x48, 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7, 0x0d, 0x82, 0xcf, 0xde, + 0xeb, 0xa3, 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda, 0x0f, + 0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42, + 0xfb, 0xd8, 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6, + 0x4d, 0x9c, 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, 0x09, 0x07, 0x37, 0xb0, + 0x75, 0x75, 0x21, 0x30, 0x82, 0x05, 0x72, 0x30, 0x82, 0x04, 0x5a, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x60, 0x97, + 0xa2, 0xe8, 0x89, 0x7f, 0x15, 0xbc, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, + 0x70, 0x65, 0x72, 0x20, 0x49, 0x44, 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, 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, 0x36, 0x32, 0x38, 0x30, 0x34, 0x31, 0x38, 0x33, 0x31, + 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x36, 0x32, 0x39, 0x30, 0x34, 0x31, 0x38, 0x33, 0x31, 0x5a, 0x30, 0x81, 0x93, 0x31, + 0x1a, 0x30, 0x18, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x01, 0x0c, 0x0a, 0x39, 0x41, 0x35, + 0x50, 0x43, 0x55, 0x34, 0x46, 0x53, 0x44, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x33, 0x44, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x49, 0x44, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x58, 0x4b, 0x37, 0x32, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x20, 0x28, 0x39, 0x41, + 0x35, 0x50, 0x43, 0x55, 0x34, 0x46, 0x53, 0x44, 0x29, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0a, + 0x39, 0x41, 0x35, 0x50, 0x43, 0x55, 0x34, 0x46, 0x53, 0x44, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x0c, 0x58, 0x4b, 0x37, 0x32, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 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, 0xc9, + 0x97, 0x5a, 0x0c, 0x4c, 0x30, 0x37, 0xb1, 0xf0, 0x25, 0x28, 0xba, 0x16, 0x41, 0x3b, 0x44, 0xdc, 0x50, 0xc6, 0xf0, 0x20, + 0xf5, 0xe1, 0x17, 0x79, 0x8a, 0xdf, 0xd8, 0x87, 0x12, 0x04, 0x08, 0x6a, 0xb1, 0x2e, 0xa0, 0x7f, 0x1c, 0x8b, 0x61, 0x51, + 0x7d, 0x30, 0xef, 0x30, 0xbe, 0x8d, 0x91, 0x33, 0x9f, 0x2f, 0x42, 0xce, 0x85, 0x03, 0xaf, 0x05, 0x59, 0x72, 0xf3, 0xf1, + 0x5b, 0x77, 0xb0, 0x94, 0x31, 0xc9, 0xd5, 0x99, 0x0a, 0x0c, 0x6f, 0x56, 0x0e, 0xf9, 0x0a, 0x54, 0x40, 0x22, 0x1e, 0x96, + 0x9e, 0xcb, 0xf1, 0x43, 0xa1, 0x6c, 0x61, 0x28, 0x92, 0x6f, 0x1b, 0x2b, 0x29, 0x19, 0x1f, 0xe0, 0xa1, 0x18, 0xcd, 0x80, + 0xcc, 0xd5, 0x66, 0xc9, 0xe4, 0x0c, 0x12, 0x95, 0x4f, 0x21, 0x64, 0x81, 0x33, 0x19, 0x2c, 0x1e, 0xa6, 0x78, 0x3f, 0x56, + 0x6a, 0x4b, 0xc7, 0xb7, 0x38, 0xec, 0x38, 0xce, 0x60, 0x75, 0x8e, 0x67, 0xc5, 0x93, 0x00, 0xb3, 0x2c, 0x98, 0xb0, 0x56, + 0xef, 0x16, 0xbe, 0x4c, 0xe0, 0x2c, 0x4c, 0xa4, 0x67, 0x27, 0xcb, 0xa9, 0xbf, 0x67, 0xf4, 0x60, 0xe1, 0x9f, 0x56, 0x4a, + 0x38, 0xeb, 0xd7, 0x86, 0x21, 0xd6, 0xa5, 0xd3, 0x20, 0x41, 0x55, 0xcb, 0x8c, 0xbd, 0xaa, 0x80, 0x90, 0x17, 0xde, 0xbb, + 0x0d, 0x55, 0xac, 0x4e, 0x93, 0xa1, 0x7f, 0x75, 0xcc, 0xc6, 0xe7, 0x22, 0x3d, 0xed, 0xff, 0x34, 0x96, 0xd0, 0x41, 0x63, + 0x2a, 0x00, 0x1b, 0x72, 0xe3, 0x37, 0xb6, 0xf1, 0xfc, 0x28, 0x12, 0x8c, 0x13, 0xd3, 0xe5, 0x3e, 0xad, 0xc0, 0xb7, 0x59, + 0x9e, 0x79, 0x9a, 0x26, 0x13, 0xa2, 0x36, 0x19, 0xd8, 0xdb, 0x82, 0x78, 0x4d, 0x61, 0xc0, 0xc8, 0x56, 0x04, 0x29, 0xc8, + 0xc7, 0x95, 0x93, 0x69, 0xfb, 0x19, 0xe9, 0xe4, 0x2d, 0xd8, 0xc3, 0x95, 0xb3, 0x43, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x82, 0x01, 0xe1, 0x30, 0x82, 0x01, 0xdd, 0x30, 0x3e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, + 0x04, 0x32, 0x30, 0x30, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x69, 0x64, 0x30, 0x31, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x64, 0xca, 0x4d, 0xf4, 0x2c, 0x19, 0xf5, 0x2a, 0x21, 0xd1, 0xf9, 0x9e, 0x38, 0xeb, 0xbd, 0x79, 0x12, + 0x86, 0xc1, 0x0e, 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, 0x57, 0x17, 0xed, 0xa2, 0xcf, 0xdc, 0x7c, 0x98, 0xa1, 0x10, + 0xe0, 0xfc, 0xbe, 0x87, 0x2d, 0x2c, 0xf2, 0xe3, 0x17, 0x54, 0x30, 0x82, 0x01, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, + 0x82, 0x01, 0x05, 0x30, 0x82, 0x01, 0x01, 0x30, 0x81, 0xfe, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, + 0x01, 0x30, 0x81, 0xf0, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, + 0x81, 0xb6, 0x0c, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, + 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x03, 0x03, 0x30, 0x13, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x01, 0x0d, 0x01, 0x01, + 0xff, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x7a, 0x4b, 0xa3, 0x42, 0x22, 0x42, 0xa3, 0x8f, 0xc1, 0xbb, 0x60, 0x8a, 0xb6, 0x3e, 0xf5, + 0x2e, 0x76, 0x68, 0x59, 0x97, 0x2e, 0x91, 0xc9, 0xb0, 0x7f, 0x3d, 0xba, 0xf1, 0x7b, 0x19, 0x84, 0x68, 0xad, 0x69, 0x8c, + 0xe2, 0x08, 0x35, 0x4f, 0x8a, 0xf2, 0xf8, 0x04, 0xe8, 0xe9, 0x46, 0x3e, 0x64, 0xf9, 0x2d, 0xef, 0x5f, 0x34, 0x77, 0x43, + 0xd1, 0x1d, 0x6f, 0xeb, 0x7d, 0x58, 0xb0, 0x85, 0xf5, 0x34, 0x4c, 0x20, 0x84, 0x27, 0xc5, 0x02, 0x77, 0x93, 0x01, 0x18, + 0x5a, 0x98, 0xd1, 0xf2, 0x53, 0x44, 0x9b, 0x2f, 0xd6, 0xf3, 0xa2, 0xb8, 0x31, 0x0b, 0x31, 0x7e, 0xf2, 0x7f, 0x83, 0x76, + 0xf0, 0xff, 0x91, 0x2c, 0x39, 0xff, 0x5b, 0x9b, 0xbd, 0x30, 0xc6, 0xf5, 0xe8, 0x4d, 0xff, 0x16, 0xf0, 0xd1, 0xa9, 0x7c, + 0x03, 0x4d, 0x2a, 0x45, 0xd9, 0x64, 0x96, 0x6a, 0x84, 0x10, 0x06, 0x3a, 0x1c, 0x0b, 0x96, 0x04, 0xe7, 0x0f, 0xd7, 0x99, + 0x8f, 0x82, 0x9f, 0x29, 0xff, 0xcf, 0x7f, 0x0d, 0x40, 0xf5, 0xa2, 0xd6, 0x38, 0x3e, 0xca, 0x76, 0xa4, 0x69, 0xad, 0x07, + 0x6b, 0xd1, 0x76, 0xde, 0xb7, 0x52, 0xc6, 0x81, 0x7b, 0x0b, 0xce, 0x8a, 0xa2, 0x53, 0xe8, 0xf7, 0x6d, 0x6c, 0x91, 0xae, + 0xa5, 0xad, 0xb4, 0xd9, 0xb8, 0x86, 0xcf, 0xa4, 0x50, 0xce, 0x9a, 0x89, 0x79, 0x2f, 0x0b, 0xec, 0xce, 0x1b, 0x70, 0x5a, + 0x31, 0xf8, 0x5e, 0xc5, 0xd2, 0x7f, 0x4b, 0x19, 0xc2, 0x8b, 0xc9, 0xcf, 0xc1, 0x0e, 0x7d, 0x54, 0x35, 0xa5, 0xa7, 0xf5, + 0xb5, 0xa3, 0x76, 0xb8, 0x76, 0xed, 0x77, 0xf4, 0x67, 0x29, 0x39, 0x28, 0x3f, 0x4d, 0xa3, 0xb8, 0xd5, 0xb4, 0x9e, 0x49, + 0xb3, 0xad, 0x48, 0xa5, 0xf1, 0x30, 0xb6, 0xd9, 0x67, 0x93, 0x24, 0x12, 0xaf, 0xb1, 0x75, 0x4e, 0x08, 0x7a, 0x73, 0xde, + 0x21, 0x31, 0x82, 0x14, 0x51, 0x30, 0x82, 0x14, 0x4d, 0x02, 0x01, 0x01, 0x30, 0x81, 0x85, 0x30, 0x79, 0x31, 0x2d, 0x30, + 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x49, 0x44, + 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, 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, 0x02, 0x08, + 0x60, 0x97, 0xa2, 0xe8, 0x89, 0x7f, 0x15, 0xbc, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x01, 0x05, 0x00, 0xa0, 0x82, 0x01, 0xc8, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, + 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x37, 0x31, 0x30, 0x31, 0x30, 0x33, 0x32, + 0x33, 0x33, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, + 0xef, 0x70, 0xcf, 0x83, 0x01, 0xb4, 0x57, 0x33, 0xca, 0x1f, 0xec, 0x9c, 0x7c, 0xe4, 0xfa, 0xc3, 0x24, 0x62, 0xcd, 0xf7, + 0x62, 0x97, 0x3d, 0xd3, 0x2e, 0xfa, 0x6b, 0x7a, 0xca, 0x06, 0x98, 0x4a, 0x30, 0x82, 0x01, 0x5b, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x82, 0x01, 0x4c, 0x04, 0x82, 0x01, 0x48, 0x3c, 0x3f, 0x78, 0x6d, 0x6c, + 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, + 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, + 0x59, 0x50, 0x45, 0x20, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, 0x2d, 0x2f, + 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20, 0x50, 0x4c, 0x49, 0x53, 0x54, 0x20, 0x31, 0x2e, + 0x30, 0x2f, 0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x54, 0x44, 0x73, 0x2f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x2d, 0x31, 0x2e, 0x30, 0x2e, 0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a, 0x3c, 0x70, 0x6c, + 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x3c, + 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x64, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, + 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, + 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x54, 0x35, 0x52, 0x77, 0x70, 0x55, 0x51, 0x58, 0x2f, 0x30, 0x64, 0x74, 0x6e, + 0x79, 0x4b, 0x51, 0x31, 0x6f, 0x4a, 0x6a, 0x4e, 0x33, 0x47, 0x44, 0x4e, 0x57, 0x6f, 0x3d, 0x0a, 0x09, 0x09, 0x3c, 0x2f, + 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x57, 0x79, 0x77, + 0x6b, 0x4c, 0x62, 0x65, 0x66, 0x5a, 0x52, 0x61, 0x68, 0x51, 0x69, 0x43, 0x74, 0x35, 0x6e, 0x55, 0x36, 0x62, 0x53, 0x4c, + 0x45, 0x43, 0x72, 0x63, 0x3d, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, + 0x74, 0x3e, 0x0a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x01, 0x00, 0x16, 0xb5, 0x73, 0xd6, 0x0e, 0x26, 0x56, 0xd7, 0x72, 0x6b, 0x2a, 0xd9, 0xe7, 0xac, 0x53, 0x8c, 0x05, 0x4a, + 0x83, 0x8b, 0x38, 0x56, 0xf8, 0xec, 0xbc, 0x72, 0xf0, 0xfb, 0x2a, 0xba, 0x7b, 0x4c, 0x67, 0x3f, 0x42, 0x47, 0x58, 0xf2, + 0xb4, 0x94, 0x8e, 0x07, 0x01, 0x08, 0x3b, 0xeb, 0xd0, 0x90, 0x9f, 0xad, 0xa9, 0xb5, 0x5b, 0x12, 0x88, 0x73, 0x1b, 0xf1, + 0x6e, 0x1e, 0xc2, 0x0a, 0x15, 0xbd, 0x2a, 0xe9, 0xf9, 0xf2, 0x32, 0x92, 0x82, 0x71, 0x49, 0x11, 0xa8, 0x00, 0x51, 0x2e, + 0xa4, 0xcb, 0xff, 0x50, 0xdb, 0x50, 0x7e, 0x63, 0x1a, 0xcd, 0x26, 0xb7, 0xb4, 0x84, 0x3a, 0x27, 0x17, 0xe1, 0x55, 0xa5, + 0xeb, 0xa7, 0xe0, 0x5c, 0x03, 0x4d, 0x16, 0xe7, 0xbc, 0xd1, 0xf9, 0x12, 0x9a, 0xf8, 0xb0, 0xc9, 0x23, 0xb8, 0xcf, 0x5e, + 0xbb, 0x2d, 0xee, 0x5d, 0xfa, 0xa6, 0xfb, 0x0b, 0x0a, 0x62, 0xf5, 0x2e, 0x3e, 0x52, 0x44, 0x80, 0x54, 0x12, 0x34, 0xdf, + 0xae, 0x86, 0x68, 0xf4, 0x7c, 0x70, 0xd5, 0x55, 0x35, 0x3e, 0x9c, 0x78, 0x92, 0x17, 0x9e, 0xe9, 0x11, 0xa8, 0x52, 0x0b, + 0x47, 0xd9, 0x98, 0xdb, 0xd9, 0xa2, 0xb7, 0x25, 0x2d, 0xfa, 0x51, 0x6d, 0x3a, 0x8e, 0x32, 0xe7, 0xfa, 0x8b, 0xfb, 0x5a, + 0x2e, 0xd7, 0x7f, 0xdf, 0x54, 0xfb, 0x76, 0xb9, 0x0d, 0x2a, 0x7d, 0xb4, 0x98, 0x58, 0x23, 0x10, 0x85, 0x42, 0xc3, 0x67, + 0xb5, 0xd5, 0x90, 0xc9, 0xeb, 0x2c, 0x4e, 0xeb, 0x29, 0xac, 0x92, 0x1e, 0xc4, 0x8c, 0xd6, 0x21, 0x4a, 0xf0, 0x56, 0x77, + 0x5f, 0x4f, 0x43, 0xaf, 0x9a, 0xbd, 0x36, 0x74, 0xb8, 0xf3, 0xdb, 0xd3, 0x54, 0xfe, 0x5a, 0x7f, 0x03, 0x54, 0x8c, 0x06, + 0xa6, 0xf0, 0x70, 0xa6, 0x32, 0x39, 0x1e, 0xed, 0xd7, 0x51, 0x9a, 0x2e, 0xd0, 0x1c, 0xec, 0xe1, 0x91, 0xf7, 0xa1, 0x82, + 0x10, 0xd0, 0x30, 0x82, 0x10, 0xcc, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0e, 0x31, + 0x82, 0x10, 0xbb, 0x30, 0x82, 0x10, 0xb7, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, + 0x10, 0xa8, 0x30, 0x82, 0x10, 0xa4, 0x02, 0x01, 0x03, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0x00, 0x30, 0x7b, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, 0xa0, 0x6c, 0x04, + 0x6a, 0x30, 0x68, 0x02, 0x01, 0x01, 0x06, 0x05, 0x2a, 0x03, 0x04, 0x05, 0x06, 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0xd3, 0x4c, 0x00, 0xe3, 0x42, 0xf2, 0x47, 0x6d, + 0xb2, 0xb4, 0x81, 0xa9, 0x1e, 0x24, 0x5e, 0x94, 0x18, 0x2f, 0xc3, 0x6e, 0x31, 0x63, 0xb2, 0xf5, 0xc8, 0x5d, 0x6d, 0xbb, + 0x11, 0x6b, 0xb1, 0xb7, 0x02, 0x08, 0x45, 0x46, 0x80, 0x73, 0xbe, 0xbb, 0xd4, 0x86, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, + 0x30, 0x37, 0x31, 0x30, 0x31, 0x30, 0x33, 0x32, 0x33, 0x33, 0x5a, 0x30, 0x03, 0x02, 0x01, 0x01, 0x02, 0x09, 0x00, 0xae, + 0x6c, 0xb5, 0x96, 0x2d, 0x6c, 0x0c, 0x95, 0xa0, 0x82, 0x0d, 0xd0, 0x30, 0x82, 0x05, 0x02, 0x30, 0x82, 0x03, 0xea, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x1e, 0x66, 0x56, 0xac, 0xcd, 0x48, 0x6e, 0xe8, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 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, 0x36, 0x32, 0x38, 0x31, 0x39, 0x32, 0x32, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x38, 0x30, 0x39, + 0x31, 0x39, 0x32, 0x32, 0x33, 0x38, 0x5a, 0x30, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x14, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x4c, 0x54, 0x4e, + 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, 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, 0xdd, 0xea, 0xf8, 0x32, 0xf9, 0x08, 0x78, 0xa6, 0x16, 0xa5, 0x81, 0xab, 0xb9, + 0x18, 0x71, 0xf5, 0xe5, 0xee, 0x2f, 0x29, 0xf4, 0x8c, 0xcc, 0xd4, 0x3e, 0xf8, 0xe7, 0x87, 0xa1, 0xa6, 0xb2, 0x3e, 0x68, + 0x84, 0x78, 0x51, 0x8b, 0x58, 0xd5, 0xe9, 0x94, 0x4b, 0xf7, 0x84, 0x83, 0x8a, 0xa8, 0x84, 0xaf, 0xef, 0xa3, 0xa5, 0x09, + 0xbd, 0xf8, 0xbf, 0xe7, 0xbb, 0xe0, 0x2f, 0x81, 0x43, 0x48, 0x85, 0x0a, 0x69, 0xe6, 0x2b, 0x3f, 0xeb, 0x4b, 0x56, 0x2d, + 0xf4, 0xca, 0xeb, 0x7b, 0xe8, 0x81, 0x76, 0xef, 0xf9, 0xe5, 0x6d, 0xfb, 0xd6, 0xf9, 0x5f, 0x70, 0xd4, 0xb8, 0x5c, 0x3c, + 0xcf, 0x04, 0xdc, 0xbc, 0x2d, 0xe6, 0x64, 0xf8, 0xd4, 0x59, 0x85, 0xd3, 0x91, 0x31, 0x33, 0x4b, 0x0d, 0x13, 0x27, 0x56, + 0x2a, 0x8a, 0x77, 0x5e, 0x31, 0x9d, 0x82, 0x19, 0xab, 0xf5, 0xe7, 0x07, 0xe2, 0x71, 0x6f, 0xd6, 0x17, 0x22, 0x8e, 0xe8, + 0x0c, 0xbb, 0x2f, 0xdb, 0x72, 0x9a, 0xb5, 0xa9, 0x0d, 0x45, 0x1e, 0x83, 0x62, 0xaf, 0x72, 0x90, 0x80, 0x20, 0x72, 0x88, + 0xaf, 0x8d, 0x03, 0x79, 0x16, 0x4c, 0x71, 0xf2, 0x5b, 0x9e, 0xb2, 0xab, 0x08, 0xaf, 0x69, 0x1f, 0xa7, 0x1a, 0xf9, 0xf3, + 0xdb, 0x00, 0xfe, 0x7a, 0xd8, 0x41, 0x63, 0x32, 0x8c, 0x8e, 0xba, 0x96, 0x49, 0x08, 0xd8, 0x71, 0x68, 0xec, 0x42, 0x6a, + 0x2d, 0x60, 0x6d, 0xf3, 0x5b, 0x1f, 0xae, 0x5a, 0x36, 0xaa, 0x58, 0xad, 0x72, 0x9d, 0x30, 0x82, 0xec, 0xdd, 0x67, 0x6d, + 0xbe, 0xd9, 0xcb, 0xd6, 0x66, 0x54, 0x76, 0xc2, 0x89, 0xa0, 0xba, 0x86, 0xd5, 0xd8, 0x2f, 0x2b, 0x8d, 0x4d, 0xa7, 0xe9, + 0x46, 0x18, 0xb2, 0xa3, 0x61, 0x20, 0x3a, 0x30, 0x83, 0xb2, 0xea, 0x42, 0x8c, 0x18, 0xc8, 0x75, 0x36, 0x81, 0xeb, 0xb0, + 0x05, 0x9b, 0xd7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xc1, 0x30, 0x82, 0x01, 0xbd, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x28, 0xe1, 0x58, 0x8c, 0x9b, 0x4e, 0xba, 0x68, 0xda, 0x07, 0x78, 0x0e, 0x6f, + 0x25, 0x89, 0x5e, 0xb1, 0x17, 0x49, 0xd9, 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, 0x34, 0xcd, 0x25, 0x4e, 0xcd, 0xde, + 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 0x30, 0x82, 0x01, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x05, 0x30, 0x82, 0x01, 0x01, 0x30, 0x81, 0xfe, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, 0xf0, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, + 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x02, 0x30, 0x81, 0xb6, 0x0c, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, + 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, + 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, + 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x63, 0x72, + 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, + 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x1f, 0x6f, 0x37, 0x73, 0xdf, 0x84, 0x8f, 0xbb, 0xe9, 0x1b, 0xda, 0xa2, 0x67, 0x5f, 0xcf, 0x2a, 0x0c, 0x06, 0x88, + 0x2f, 0x47, 0x9c, 0xb8, 0x37, 0xa2, 0x4e, 0x14, 0x6d, 0xb2, 0x24, 0x8e, 0x41, 0x81, 0x24, 0xa0, 0x94, 0x28, 0xea, 0xed, + 0xda, 0x87, 0x63, 0x5d, 0xb6, 0x88, 0xf6, 0xa6, 0xc5, 0x86, 0xda, 0x6d, 0xf0, 0x46, 0x23, 0x4a, 0xb1, 0xf5, 0xbc, 0x89, + 0xf5, 0xbd, 0x30, 0xed, 0xa3, 0xb8, 0x18, 0x4e, 0x12, 0x4d, 0x95, 0xfc, 0xbc, 0xad, 0xbf, 0xb2, 0x2f, 0x82, 0x9a, 0xf1, + 0x04, 0xb7, 0xda, 0xbc, 0xd9, 0x35, 0x14, 0x59, 0x98, 0xc3, 0x57, 0x50, 0x5e, 0x74, 0x81, 0xc8, 0x6e, 0x8d, 0x44, 0x17, + 0xe3, 0x1c, 0x8a, 0xed, 0x36, 0x1e, 0x87, 0x16, 0xb1, 0x12, 0x65, 0x95, 0x33, 0x56, 0x86, 0xf5, 0xec, 0x58, 0xe9, 0x82, + 0x48, 0x56, 0x18, 0x6e, 0x5e, 0xb8, 0xec, 0x15, 0x06, 0x4c, 0x64, 0xeb, 0xcc, 0x69, 0xb4, 0x5d, 0xc7, 0x56, 0x26, 0x02, + 0xb3, 0xf9, 0x38, 0x68, 0x1b, 0x0e, 0x71, 0x86, 0x5d, 0x81, 0xcc, 0x1c, 0xae, 0x64, 0xee, 0x22, 0xf2, 0xe0, 0x8f, 0xfc, + 0xc0, 0x88, 0x85, 0x6b, 0x8d, 0x69, 0x67, 0xd8, 0x00, 0xf5, 0x3b, 0x81, 0x5b, 0xbe, 0x35, 0x14, 0x2a, 0x9e, 0x10, 0xd5, + 0xcc, 0xa0, 0xdc, 0x8f, 0x44, 0xb2, 0xb1, 0xea, 0xbf, 0x02, 0x97, 0x31, 0x43, 0xa1, 0x1a, 0xe1, 0xfa, 0x09, 0xf1, 0x1f, + 0xef, 0x35, 0x82, 0x6b, 0x86, 0x98, 0x1c, 0xca, 0xee, 0x8e, 0x3c, 0x08, 0xa1, 0xbc, 0x69, 0xbf, 0xb9, 0x72, 0xe7, 0x97, + 0x81, 0x45, 0x7a, 0x74, 0xa6, 0x2c, 0xd9, 0x3a, 0xd0, 0xe6, 0x56, 0xe8, 0x5b, 0x7c, 0x63, 0x46, 0x1c, 0xaf, 0xa6, 0x25, + 0x4d, 0x19, 0x3c, 0x18, 0x63, 0x55, 0xb1, 0x0b, 0x8c, 0x3d, 0x89, 0xa2, 0xd4, 0x36, 0x08, 0xc7, 0x20, 0x30, 0x82, 0x04, + 0x07, 0x30, 0x82, 0x02, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x7d, 0x4c, 0x57, 0x63, 0x9f, 0xf3, 0xf0, 0xb7, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x32, 0x30, 0x34, 0x30, 0x35, 0x31, 0x32, 0x30, 0x32, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x34, 0x30, 0x35, + 0x31, 0x32, 0x30, 0x32, 0x34, 0x34, 0x5a, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, + 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, + 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, 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, 0xd3, 0x77, 0x18, 0xa1, 0xf7, 0x99, 0x10, 0x67, 0x5c, 0xd2, 0x2e, 0x9e, 0xb8, 0x8f, + 0x23, 0x67, 0x3e, 0xfc, 0x42, 0xe2, 0x09, 0x7d, 0x0a, 0x8a, 0xb8, 0x18, 0xfc, 0x73, 0x40, 0x2f, 0xbd, 0xc4, 0xd8, 0x50, + 0xc5, 0x27, 0xc8, 0xfe, 0xb8, 0x34, 0x70, 0xa0, 0x0d, 0x13, 0x3c, 0xbd, 0x08, 0x4e, 0x9a, 0x93, 0x6f, 0x39, 0x37, 0xda, + 0x9e, 0x65, 0xf5, 0xb4, 0x63, 0xf4, 0x90, 0xc8, 0x49, 0x6d, 0x5d, 0x20, 0xd3, 0x39, 0xfd, 0x09, 0xba, 0xf4, 0x3a, 0xf3, + 0xce, 0x4a, 0x69, 0x64, 0x05, 0x99, 0x46, 0xe0, 0xda, 0x35, 0xc4, 0x65, 0x18, 0x1e, 0xc6, 0x16, 0xa3, 0x12, 0x61, 0xb4, + 0x2e, 0xf5, 0xf0, 0x89, 0x0d, 0x8c, 0xdc, 0x3d, 0xf6, 0x06, 0xcf, 0x6f, 0x86, 0x25, 0x4c, 0x09, 0xc2, 0x1b, 0xc8, 0x0e, + 0x78, 0x88, 0x8d, 0xc1, 0x22, 0xb8, 0xba, 0x21, 0x13, 0x9b, 0xca, 0xee, 0x8a, 0x9e, 0xdd, 0x7b, 0x5b, 0xff, 0xa3, 0xe9, + 0xd1, 0xa3, 0x81, 0x7e, 0xfe, 0xff, 0xe6, 0x8c, 0x49, 0xe4, 0x3b, 0x0a, 0xf9, 0x10, 0xa6, 0x72, 0x33, 0xbb, 0x2c, 0xc4, + 0x4a, 0x5a, 0x72, 0x0a, 0x39, 0x50, 0x74, 0xdd, 0x28, 0x6e, 0x79, 0x5f, 0x7e, 0xa7, 0xa8, 0x14, 0xcf, 0x56, 0xb3, 0x56, + 0x6c, 0xa5, 0xe9, 0xf0, 0xc4, 0xae, 0xf9, 0xea, 0x20, 0x8e, 0x18, 0xc7, 0x28, 0x74, 0xe2, 0x08, 0x4d, 0x89, 0x26, 0x42, + 0x79, 0x5e, 0xf6, 0x60, 0xe3, 0x45, 0x58, 0xa1, 0xfb, 0x51, 0x49, 0x5e, 0x92, 0x4a, 0x4d, 0xb9, 0xef, 0xd4, 0x73, 0xb5, + 0xda, 0x04, 0x7b, 0xe3, 0x52, 0x9f, 0xcb, 0xa3, 0x19, 0x5d, 0xac, 0x6b, 0x98, 0x6c, 0x9e, 0xe2, 0xec, 0x74, 0x2d, 0x44, + 0x3e, 0xe0, 0x61, 0x3e, 0x07, 0x45, 0x7e, 0x34, 0x75, 0x26, 0x98, 0x40, 0x9b, 0x75, 0x9e, 0xc8, 0x30, 0xed, 0x4b, 0xbf, + 0x77, 0x8f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x34, 0xcd, 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, 0xf8, 0xf9, 0xe2, 0x29, + 0xde, 0xf2, 0x1c, 0x93, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, + 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, + 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d, + 0x1f, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, + 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x10, + 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x09, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x36, 0xd2, 0xf5, 0xde, + 0x71, 0x53, 0x07, 0xc9, 0x23, 0xd8, 0x78, 0x9b, 0x65, 0xbc, 0xf3, 0xd5, 0x5b, 0xe9, 0xb8, 0x7f, 0x1b, 0x23, 0xc7, 0xa2, + 0xcf, 0xb4, 0xa9, 0x28, 0xe9, 0xf8, 0xdd, 0x70, 0x88, 0x21, 0x39, 0xf3, 0xdb, 0x33, 0x9c, 0xc3, 0x72, 0x43, 0xd6, 0x3d, + 0x42, 0x51, 0x97, 0xba, 0xad, 0x1d, 0x8e, 0x92, 0xd2, 0x75, 0x8b, 0xc3, 0x5d, 0x9c, 0xf5, 0xcb, 0x8c, 0xdc, 0x6a, 0x6a, + 0x3a, 0xdd, 0xeb, 0x54, 0x7d, 0xed, 0x14, 0x6b, 0xf3, 0xd6, 0x3e, 0x93, 0xc8, 0x6d, 0x7a, 0x54, 0x5f, 0xf2, 0x43, 0x8e, + 0x10, 0xd0, 0x76, 0x5c, 0x9b, 0x00, 0x0c, 0x1d, 0x4e, 0xca, 0x3c, 0xcd, 0xfa, 0xe6, 0xf7, 0xc2, 0x3e, 0x72, 0xb7, 0xb8, + 0xde, 0xe8, 0x34, 0xaa, 0x15, 0xa0, 0xae, 0x5c, 0x67, 0xa8, 0x0c, 0xac, 0x9b, 0x1e, 0x65, 0xb3, 0xe3, 0x0f, 0x30, 0x42, + 0x34, 0xe9, 0xae, 0xd3, 0x01, 0xd3, 0xa7, 0xdd, 0x42, 0x73, 0x75, 0x7c, 0x51, 0x43, 0x85, 0x9a, 0x60, 0x10, 0xdc, 0xae, + 0x27, 0xd2, 0x6b, 0x67, 0xc9, 0x33, 0x45, 0x6f, 0xc9, 0x98, 0x1e, 0xa0, 0x9a, 0x7f, 0x4d, 0x11, 0x93, 0xe1, 0x69, 0xff, + 0xec, 0x4b, 0x45, 0xf3, 0x4e, 0xca, 0x22, 0x0e, 0x57, 0xd7, 0x22, 0x07, 0xe5, 0x22, 0xb4, 0x87, 0xe9, 0x9c, 0xd3, 0x45, + 0xcb, 0x6e, 0x3f, 0xe5, 0x8e, 0xb8, 0xfc, 0x46, 0xd5, 0x5c, 0xc9, 0xb0, 0xab, 0x05, 0x3a, 0x6d, 0x37, 0x28, 0xa3, 0xa8, + 0x46, 0x65, 0x6f, 0x55, 0xa1, 0x68, 0x88, 0xea, 0x52, 0x3e, 0xc9, 0xf4, 0xd4, 0xe6, 0xfa, 0x3f, 0xa4, 0xe4, 0x26, 0x80, + 0xb5, 0x3a, 0x6b, 0xd6, 0xc3, 0xe5, 0xf9, 0x32, 0x81, 0xc8, 0x32, 0xa2, 0x48, 0xe1, 0x8e, 0x06, 0xa3, 0x19, 0xe4, 0xb3, + 0xcb, 0x3b, 0x4b, 0xdf, 0xe0, 0xcc, 0x0e, 0xb2, 0xaf, 0x98, 0xd1, 0x83, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, + 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, + 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, + 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 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, 0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, + 0xed, 0x5e, 0x79, 0x84, 0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, + 0x07, 0xab, 0x22, 0x30, 0x02, 0xe8, 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca, 0x66, + 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3, 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b, + 0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4, 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, + 0x5f, 0x9b, 0xf2, 0x25, 0x03, 0xba, 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d, + 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac, + 0x2c, 0x20, 0x6f, 0x70, 0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a, + 0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e, 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92, + 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74, 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, + 0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb, 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41, + 0x89, 0xc4, 0x74, 0x62, 0x0b, 0x10, 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c, + 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, 0x73, 0xff, 0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, + 0x77, 0x94, 0xc9, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, + 0x5e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, + 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, + 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, + 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, + 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, + 0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2, 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47, + 0x37, 0xf2, 0xa9, 0x9b, 0x40, 0x8e, 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f, + 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, 0x3e, 0xf9, 0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, + 0xd3, 0x38, 0xc4, 0xb1, 0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, + 0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b, 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf, 0x0f, + 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d, 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5, + 0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2, 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, + 0x2f, 0x92, 0xb2, 0xf8, 0x44, 0x48, 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7, + 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c, + 0x56, 0xeb, 0xda, 0x0f, 0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7, + 0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8, 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a, + 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c, 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, + 0x09, 0x07, 0x37, 0xb0, 0x75, 0x75, 0x21, 0x31, 0x82, 0x02, 0x3f, 0x30, 0x82, 0x02, 0x3b, 0x02, 0x01, 0x01, 0x30, 0x81, + 0x88, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 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, 0x02, 0x08, 0x1e, 0x66, 0x56, 0xac, 0xcd, 0x48, 0x6e, 0xe8, 0x30, 0x09, 0x06, + 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x81, 0x8c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, 0x30, + 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x37, + 0x31, 0x30, 0x31, 0x30, 0x33, 0x32, 0x33, 0x33, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x04, 0x31, 0x16, 0x04, 0x14, 0xac, 0xa5, 0xf2, 0x94, 0xd6, 0x0b, 0x65, 0x54, 0x09, 0xf8, 0xad, 0x9d, 0x40, 0x93, + 0xda, 0x9f, 0x82, 0xef, 0xb6, 0x86, 0x30, 0x2b, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, + 0x0c, 0x31, 0x1c, 0x30, 0x1a, 0x30, 0x18, 0x30, 0x16, 0x04, 0x14, 0x64, 0x2b, 0x13, 0x96, 0x1d, 0x64, 0x33, 0xd4, 0xdf, + 0x33, 0xb3, 0x04, 0x94, 0xd1, 0x70, 0xbe, 0x43, 0x2c, 0xfb, 0xdf, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x90, 0x6d, 0x04, 0x4c, 0x96, 0x25, 0x41, 0xaa, 0x66, 0x0a, + 0x17, 0x90, 0xdb, 0x28, 0x99, 0xe4, 0x40, 0x81, 0x25, 0xca, 0xd7, 0x47, 0xa6, 0x95, 0x71, 0x95, 0x68, 0x20, 0xb4, 0xfb, + 0xbd, 0x13, 0x17, 0x54, 0x2e, 0x56, 0x0f, 0x7b, 0xa3, 0x65, 0x17, 0xda, 0x94, 0x48, 0x7e, 0xc9, 0xc7, 0xf2, 0xb9, 0x96, + 0xbd, 0xd7, 0xf5, 0xbd, 0xc3, 0x63, 0xe0, 0x95, 0x0b, 0x2d, 0xfc, 0xb2, 0x37, 0xeb, 0xe0, 0xc5, 0x0f, 0xfd, 0xc7, 0x61, + 0x70, 0xcf, 0x5f, 0x35, 0xca, 0x48, 0xf1, 0xb0, 0x20, 0x27, 0xb3, 0x8e, 0x8b, 0x1a, 0xda, 0xeb, 0x0b, 0x55, 0xa6, 0xd5, + 0x2f, 0x9d, 0x7b, 0x53, 0xbd, 0x24, 0x19, 0x06, 0xf8, 0x5e, 0xb5, 0x12, 0x55, 0x0c, 0x49, 0x4b, 0x96, 0xfb, 0x00, 0x2c, + 0xe1, 0xc9, 0xe6, 0x0a, 0x6b, 0x5a, 0x17, 0x29, 0xfb, 0x4d, 0xf1, 0xc5, 0xac, 0x14, 0xb0, 0xe5, 0xc1, 0xa0, 0xd7, 0x89, + 0x3e, 0xbf, 0x1b, 0xa3, 0x69, 0x70, 0xe2, 0x37, 0x17, 0x1d, 0xd5, 0x4a, 0x8b, 0xfe, 0x99, 0x9a, 0x43, 0xba, 0x9f, 0xc3, + 0xc9, 0x37, 0x7d, 0x4d, 0x6d, 0xb9, 0xb3, 0x46, 0x22, 0xc9, 0xc7, 0x5f, 0x59, 0x57, 0x19, 0xac, 0x7d, 0x8d, 0xad, 0x2a, + 0xad, 0xc8, 0x77, 0x8a, 0xcb, 0x44, 0xde, 0x2b, 0xdf, 0x95, 0xac, 0x9d, 0x10, 0x9e, 0x2a, 0xdb, 0x21, 0x9b, 0x21, 0x6f, + 0x72, 0x61, 0x13, 0xad, 0x49, 0x70, 0x52, 0xbf, 0xc6, 0xa2, 0x75, 0x97, 0xf5, 0xef, 0x2d, 0x86, 0x36, 0x2e, 0x07, 0x10, + 0x75, 0x41, 0xf8, 0x21, 0xc6, 0x2d, 0x5e, 0x34, 0x3a, 0xfb, 0x31, 0x1c, 0xf7, 0x13, 0x61, 0x42, 0x12, 0x53, 0xa2, 0x62, + 0x3c, 0x5b, 0x9f, 0x43, 0xb7, 0xae, 0xc5, 0x89, 0xa3, 0x85, 0xdb, 0xd9, 0x42, 0x0d, 0xda, 0x04, 0x0d, 0x9b, 0xd9, 0xe0, + 0xae, 0xa1, 0xa3, 0x90, 0xd0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#endif /* si_34_cms_timestamp_h */ diff --git a/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.m b/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.m new file mode 100644 index 00000000..4662cf15 --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.m @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2018 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@ + */ + +#include "shared_regressions.h" + +#import +#import + +#import +#import +#import +#include +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_OSX +#include +#include +#endif + +#import "si-34-cms-timestamp.h" +#import "si-cms-hash-agility-data.h" // for signing_identity_p12, hash agility attribute data + +static CMSSignerStatus test_verify_timestamp(NSData *content, NSData *message) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus = kCMSSignerUnsigned; + + /* Create decoder and decode */ + require_noerr_action(CMSDecoderCreate(&decoder), fail, fail("Failed to create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, [message bytes], [message length]), fail, + fail("Failed to update decoder with CMS message")); + require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)content), fail, + fail("Failed to set detached content")); + require_noerr_action(CMSDecoderFinalizeMessage(decoder), fail, fail("Failed to finalize decoder")); + + /* Get signer status */ + require_action(policy = SecPolicyCreateBasicX509(), fail, fail("Failed to Create policy")); + require_noerr_action(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + fail, fail("Failed to copy Signer status")); + +fail: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); + return signerStatus; +} + +static void test_matching_messageImprint(void) { + /* If the timestamp is invalid, SecCmsSignerInfoVerifyUnAuthAttrs will fail, so the signer status will be + * kCMSSignerInvalidSignature. */ + CMSSignerStatus expected_mismatch_result = kCMSSignerInvalidSignature; +#if !TIMESTAMPING_SUPPORTED + expected_mismatch_result = kCMSSignerValid; +#endif + + is(test_verify_timestamp([NSData dataWithBytes:_developer_id_data length:sizeof(_developer_id_data)], + [NSData dataWithBytes:_developer_id_sig length:sizeof(_developer_id_sig)]), + kCMSSignerValid, "failed to verify good timestamped signature"); + is(test_verify_timestamp([NSData dataWithBytes:_mismatched_content length:sizeof(_mismatched_content)], + [NSData dataWithBytes:_mismatched_timestamp length:sizeof(_mismatched_timestamp)]), + expected_mismatch_result, "successful verification of bad timestamped signature"); +} + +static void test_create_timestamp(void) { + CFArrayRef tmp_imported_items = NULL; + NSArray *imported_items = nil; + SecIdentityRef identity = nil; + CMSEncoderRef encoder = NULL; + CMSDecoderRef decoder = NULL; + CFDataRef message = NULL; + NSDictionary *attrValues = nil; + + /* Import identity */ + NSDictionary *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" }; + NSData *p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)]; + require_noerr_action(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options, + &tmp_imported_items), exit, + fail("Failed to import identity")); + imported_items = CFBridgingRelease(tmp_imported_items); + require_noerr_action([imported_items count] == 0 && + [imported_items[0] isKindOfClass:[NSDictionary class]], exit, + fail("Wrong imported items output")); + identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]); + require_action(identity, exit, fail("Failed to get identity")); + + /* Create encoder */ + require_noerr_action(CMSEncoderCreate(&encoder), exit, fail("Failed to create CMS encoder")); + require_noerr_action(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit, + fail("Failed to set digest algorithm to SHA256")); + + /* Set identity as signer */ + require_noerr_action(CMSEncoderAddSigners(encoder, identity), exit, fail("Failed to add signer identity")); + + /* Add hash agility attribute */ + require_noerr_action(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgility), exit, + fail("Set hash agility flag")); + require_noerr_action(CMSEncoderSetAppleCodesigningHashAgility(encoder, (__bridge CFDataRef)[NSData dataWithBytes:attribute + length:sizeof(attribute)]), + exit, fail("Set hash agility data")); + + /* Add hash agility v2 attribute */ + attrValues = @{ @(SEC_OID_SHA1) : [NSData dataWithBytes:_attributev2 length:20], + @(SEC_OID_SHA256) : [NSData dataWithBytes:(_attributev2 + 32) length:32], + }; + require_noerr_action(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgilityV2), exit, + fail("Set hash agility flag")); + require_noerr_action(CMSEncoderSetAppleCodesigningHashAgilityV2(encoder, (__bridge CFDictionaryRef)attrValues), exit, + fail("Set hash agility data")); + +#if TIMESTAMPING_SUPPORTED + /* Set timestamp context */ + CmsMessageSetTSAContext(encoder, SecCmsTSAGetDefaultContext(NULL)); +#endif + + /* Load content */ + require_noerr_action(CMSEncoderSetHasDetachedContent(encoder, true), exit, fail("Failed to set detached content")); + require_noerr_action(CMSEncoderUpdateContent(encoder, content, sizeof(content)), exit, fail("Failed to set content")); + + /* output cms message */ + ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); + isnt(message, NULL, "Encoded message exists"); + + /* decode message */ + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), + CFDataGetLength(message)), exit, + fail("Update decoder with CMS message")); + require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:content + length:sizeof(content)]), + exit, fail("Set detached content")); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + +exit: + CFReleaseNull(encoder); + CFReleaseNull(decoder); + CFReleaseNull(message); +#if TARGET_OS_OSX + // SecPKCS12Import adds the items to the keychain on macOS + NSDictionary *query = @{ (__bridge NSString*)kSecValueRef : (__bridge id)identity }; + ok_status(SecItemDelete((__bridge CFDictionaryRef)query), "failed to remove identity from keychain"); +#else + pass("skip test on iOS"); +#endif + CFReleaseNull(identity); +} + +static int ping_host(char *host_name){ + + struct sockaddr_in pin; + struct hostent *nlp_host; + int sd; + int port; + int retries = 5; + + port=80; + + //tries 5 times then give up + while ((nlp_host=gethostbyname(host_name))==0 && retries--){ + printf("Resolve Error! (%s) %d\n", host_name, h_errno); + sleep(1); + } + + if(nlp_host==0) + return 0; + + bzero(&pin,sizeof(pin)); + pin.sin_family=AF_INET; + pin.sin_addr.s_addr=htonl(INADDR_ANY); + pin.sin_addr.s_addr=((struct in_addr *)(nlp_host->h_addr))->s_addr; + pin.sin_port=htons(port); + + sd=socket(AF_INET,SOCK_STREAM,0); + + if (connect(sd,(struct sockaddr*)&pin,sizeof(pin))==-1){ + printf("connect error! (%s) %d\n", host_name, errno); + close(sd); + return 0; + } + else{ + close(sd); + return 1; + } +} + +int si_34_cms_timestamp(int argc, char * const *argv) { + plan_tests(6); + + test_matching_messageImprint(); + + if (!ping_host("timestamp.apple.com")) { + printf("Accessing timestamp.apple.com failed, check the network!\n"); + return 0; + } + test_create_timestamp(); + + return 0; +} diff --git a/OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.h b/OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.h new file mode 100644 index 00000000..4511cd62 --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.h @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + */ + +#ifndef si_35_cms_expiration_time_h +#define si_35_cms_expiration_time_h + + +#endif /* si_35_cms_expiration_time_h */ + +#include "si-cms-signing-identity-p12.h" + +uint8_t _css_content[] = { + 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x0a +}; + +uint8_t _css_gen_expiration_time[] = { + 0x30, 0x82, 0x21, 0x6c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x21, 0x5d, 0x30, + 0x82, 0x21, 0x59, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x01, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x0e, 0xc1, 0x30, 0x82, + 0x05, 0x69, 0x30, 0x82, 0x04, 0x51, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x00, 0xe3, 0xd3, 0xe8, 0xe4, 0xcc, 0xd6, + 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x71, 0x31, 0x2b, + 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x22, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, + 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x20, 0x2d, + 0x20, 0x47, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 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, 0x31, 0x32, + 0x39, 0x32, 0x32, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x31, 0x32, 0x37, 0x32, 0x32, 0x33, 0x35, + 0x35, 0x32, 0x5a, 0x30, 0x3c, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x63, 0x73, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x30, 0x30, 0x33, 0x74, 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, 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, 0xe9, 0xad, + 0x73, 0xbc, 0xa2, 0x60, 0x1a, 0x44, 0x1d, 0x16, 0x2b, 0x21, 0x23, 0xdf, 0xe8, 0x1e, 0x74, 0xc2, 0xe8, 0x14, 0xb3, 0x60, + 0x17, 0x02, 0x8a, 0x54, 0xbf, 0xfd, 0x3e, 0x77, 0x7b, 0xdc, 0x55, 0x49, 0xd7, 0x05, 0x33, 0x6a, 0xd8, 0x4d, 0xa8, 0x2b, + 0xa1, 0xfd, 0xeb, 0xdf, 0xb6, 0xd5, 0x7b, 0x1a, 0x15, 0x02, 0xa3, 0x41, 0xc0, 0x71, 0x12, 0x13, 0x72, 0xe1, 0x8f, 0x23, + 0x65, 0x18, 0xde, 0x7f, 0x66, 0x7c, 0x49, 0x5d, 0x78, 0x75, 0xd7, 0xf6, 0xe2, 0x7c, 0x8c, 0x8d, 0xf6, 0xc7, 0x6d, 0x83, + 0x9e, 0xd9, 0x8b, 0xef, 0xd3, 0xb2, 0xab, 0x31, 0x19, 0x7f, 0xd1, 0x95, 0x0e, 0xaf, 0xe6, 0x16, 0xb8, 0x43, 0x23, 0xa5, + 0x93, 0xc4, 0x0f, 0x8f, 0xde, 0xf3, 0x38, 0xf6, 0x53, 0xbc, 0xdd, 0x5c, 0x3a, 0x5b, 0x06, 0x5e, 0xf1, 0x68, 0x82, 0x2e, + 0xee, 0x29, 0x5d, 0xfa, 0x3f, 0x0f, 0x06, 0xfa, 0xef, 0x8b, 0x54, 0x26, 0xc9, 0xd7, 0xff, 0x92, 0x4f, 0x13, 0x19, 0x6e, + 0x5b, 0x6f, 0x73, 0x58, 0x8e, 0x5d, 0xc1, 0xdf, 0x23, 0xe1, 0x27, 0xb9, 0x16, 0xd2, 0xe5, 0x67, 0x07, 0xc5, 0xcc, 0xe4, + 0xbe, 0xa6, 0xda, 0xfa, 0x37, 0xe6, 0xe1, 0xe1, 0xba, 0x05, 0x68, 0x84, 0xe3, 0xa2, 0xd9, 0xa9, 0x43, 0x93, 0x8b, 0xaa, + 0xd7, 0xc6, 0x98, 0x75, 0xde, 0xb2, 0xfe, 0x2c, 0x28, 0xbf, 0x58, 0x92, 0x60, 0xe5, 0xbc, 0xda, 0x0b, 0xc4, 0x5b, 0x8c, + 0x87, 0x45, 0xad, 0x62, 0x8c, 0x10, 0x6a, 0x31, 0x77, 0x4e, 0x48, 0xc0, 0x76, 0x79, 0x29, 0x91, 0xb3, 0x66, 0x82, 0xeb, + 0xb2, 0x35, 0xd1, 0xc3, 0x5a, 0x2b, 0x13, 0xda, 0x24, 0xf7, 0xa8, 0xad, 0xb7, 0xd2, 0xaf, 0x98, 0xa1, 0x93, 0x43, 0x9a, + 0x07, 0xf8, 0xb5, 0xce, 0xe5, 0x1c, 0xc9, 0x46, 0x63, 0x50, 0x79, 0xa5, 0x1e, 0x1f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x02, 0x38, 0x30, 0x82, 0x02, 0x34, 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, 0xbe, 0x46, 0x64, 0xc6, 0xc9, 0x6d, + 0x92, 0x89, 0x11, 0x41, 0x60, 0x91, 0x87, 0xf1, 0x64, 0x7c, 0x78, 0xd2, 0x7c, 0x94, 0x30, 0x56, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x4a, 0x30, 0x48, 0x30, 0x46, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x01, 0x86, 0x3a, 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, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x63, 0x61, 0x67, 0x32, + 0x30, 0x31, 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, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0d, 0x30, 0x0b, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x04, 0x01, 0x30, 0x49, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x42, 0x30, + 0x40, 0x30, 0x3e, 0xa0, 0x3c, 0xa0, 0x3a, 0x86, 0x38, 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, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x63, 0x61, 0x67, + 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x4e, 0xe9, 0xa9, 0xc3, + 0x2e, 0x25, 0xd2, 0xa2, 0x7a, 0x8b, 0x52, 0x3d, 0x16, 0x3c, 0xaf, 0xee, 0x41, 0xef, 0x79, 0x01, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x11, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x63, 0x64, 0x06, 0x01, 0x1d, 0x02, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0xbe, 0xc8, 0x17, 0x96, 0xe9, 0x50, 0x1e, 0xfa, + 0xfb, 0xa8, 0x99, 0x83, 0xc4, 0x68, 0x3a, 0xc5, 0xb7, 0x80, 0x7a, 0xb0, 0x59, 0x6c, 0xb6, 0x0c, 0xb1, 0xee, 0x40, 0x9a, + 0x18, 0x11, 0x45, 0x16, 0x97, 0xad, 0xd7, 0xe5, 0x10, 0xa2, 0x1f, 0x3c, 0xdd, 0x63, 0xcb, 0xc9, 0x72, 0xd3, 0x6e, 0x72, + 0x4d, 0x90, 0xc4, 0xb2, 0x16, 0x95, 0x16, 0x1c, 0x12, 0x2a, 0xd0, 0xb6, 0x65, 0x4c, 0x54, 0x7e, 0xe0, 0xa6, 0xb7, 0x06, + 0x85, 0x07, 0xac, 0x3f, 0x05, 0x51, 0xcb, 0xd5, 0x20, 0x6a, 0x47, 0x16, 0xb9, 0x6e, 0xd3, 0x93, 0xa1, 0xd6, 0xbc, 0xe2, + 0x15, 0x25, 0x0b, 0x7c, 0xc1, 0x72, 0xcd, 0xee, 0x64, 0xbe, 0x5f, 0x4e, 0xb4, 0xf5, 0x1d, 0x6d, 0x6c, 0xc5, 0x37, 0xf6, + 0xb8, 0xb3, 0xfc, 0xc2, 0x41, 0x01, 0x79, 0x0c, 0x68, 0x2b, 0x24, 0x86, 0xe8, 0x6f, 0x55, 0x19, 0x59, 0x69, 0xa2, 0x36, + 0x01, 0x80, 0x22, 0x78, 0xad, 0xe6, 0xd8, 0xe9, 0xa8, 0x98, 0x75, 0xc7, 0xe8, 0x10, 0x37, 0x7c, 0x8a, 0x80, 0x06, 0xbf, + 0x24, 0xfb, 0xd6, 0xc0, 0x9f, 0xa3, 0x26, 0x7a, 0xee, 0x92, 0xbe, 0xea, 0x7a, 0x18, 0x88, 0x2a, 0xdf, 0xc5, 0x85, 0x1d, + 0x8a, 0x18, 0x66, 0xa9, 0xd5, 0xe5, 0x76, 0x23, 0xc0, 0x47, 0x4f, 0xc2, 0xb9, 0x6a, 0x46, 0x21, 0x8c, 0x6a, 0xd6, 0x95, + 0x04, 0x7d, 0x06, 0xa1, 0x91, 0xf5, 0x0c, 0x77, 0x9b, 0xb4, 0xbb, 0x21, 0xc6, 0xc0, 0x63, 0x5b, 0xe3, 0x47, 0x65, 0x71, + 0xe5, 0x55, 0x89, 0x17, 0xa9, 0x73, 0x70, 0xd0, 0xdf, 0x43, 0x9d, 0xfc, 0x1d, 0xb1, 0x6f, 0x73, 0x83, 0xd5, 0x89, 0x34, + 0xf6, 0x00, 0xa7, 0x87, 0x7d, 0x7b, 0x91, 0xc2, 0x15, 0x18, 0x38, 0x97, 0x7f, 0x81, 0x63, 0x34, 0x64, 0xaa, 0xa4, 0x00, + 0x40, 0x29, 0xbe, 0xfd, 0x96, 0x14, 0xfa, 0x30, 0x82, 0x04, 0x80, 0x30, 0x82, 0x03, 0x68, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x08, 0x30, 0x0c, 0x95, 0xe4, 0x78, 0x4f, 0xf3, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 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, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x35, 0x30, 0x39, + 0x32, 0x32, 0x30, 0x36, 0x31, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x30, 0x71, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x22, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, + 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, 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, 0xd9, 0xdc, 0x8b, 0xf5, 0x7a, 0x4e, 0xb8, 0xcb, 0xee, 0x25, + 0xb2, 0xd6, 0x6a, 0x36, 0x16, 0xd6, 0xf6, 0xdf, 0x9d, 0xd6, 0xcc, 0x65, 0xf3, 0xf4, 0x89, 0xb2, 0x06, 0x3e, 0x41, 0xfd, + 0xc2, 0xf8, 0x5a, 0x7b, 0x16, 0x90, 0x03, 0x9a, 0x60, 0x7c, 0xb0, 0x93, 0x1e, 0x20, 0xc0, 0x8a, 0xce, 0x13, 0x08, 0xd5, + 0x2e, 0x4d, 0x88, 0xd1, 0x10, 0xdc, 0xef, 0xc1, 0x62, 0x50, 0x5a, 0x8b, 0x77, 0x2e, 0x4f, 0x53, 0xa1, 0x0a, 0x0f, 0xb3, + 0xb1, 0xd2, 0x00, 0xd6, 0x6b, 0x6f, 0xa0, 0x20, 0x52, 0xe7, 0x91, 0x4e, 0x9e, 0xd0, 0x85, 0xa6, 0xcd, 0x76, 0x1a, 0xd0, + 0x58, 0x2a, 0x1d, 0xa2, 0x9b, 0xd4, 0xf7, 0xae, 0x05, 0xe7, 0x0a, 0xab, 0xd6, 0x0f, 0x74, 0x29, 0x5b, 0x88, 0x46, 0xc4, + 0x6b, 0x73, 0x4d, 0x56, 0x9d, 0x91, 0xb6, 0x11, 0xc5, 0xab, 0xc0, 0xc7, 0x19, 0x1d, 0x78, 0xe4, 0xa9, 0x2f, 0x8e, 0x0b, + 0x7f, 0x97, 0x85, 0x3a, 0x61, 0x32, 0x1d, 0x94, 0x59, 0x59, 0x30, 0xe6, 0xf7, 0xbc, 0x33, 0x74, 0x74, 0x54, 0x6e, 0xe8, + 0x90, 0xc9, 0xb4, 0xc6, 0x9a, 0xb7, 0x44, 0x02, 0xd7, 0x95, 0x60, 0x72, 0x4c, 0xe2, 0x8f, 0xe9, 0xf8, 0x53, 0x44, 0xd2, + 0x1a, 0x15, 0xac, 0x14, 0xe8, 0x93, 0x9c, 0xe6, 0xd8, 0xf1, 0xa3, 0xc1, 0x59, 0x29, 0x6f, 0x92, 0xb4, 0x53, 0xf4, 0x68, + 0x47, 0x9b, 0x81, 0xcf, 0xfc, 0x7c, 0xe8, 0x65, 0x6c, 0xcd, 0x54, 0x44, 0x80, 0x87, 0xef, 0x45, 0x07, 0x98, 0x82, 0x1d, + 0x07, 0x9b, 0xf2, 0x1f, 0xcc, 0x22, 0x81, 0x98, 0x18, 0xbf, 0x4c, 0x14, 0xb3, 0x2c, 0xa7, 0xae, 0x00, 0x9a, 0x7a, 0x3c, + 0x1e, 0xd1, 0x0d, 0xef, 0xeb, 0x95, 0xba, 0xd4, 0xd4, 0x8d, 0x75, 0x0f, 0xa0, 0x00, 0x01, 0x64, 0x98, 0x49, 0x17, 0x2b, + 0xe3, 0xfb, 0xeb, 0x3e, 0x4d, 0xbd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x24, 0x30, 0x82, 0x01, 0x20, 0x30, + 0x51, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x35, 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, 0x65, 0x73, 0x74, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x72, 0x6f, 0x6f, 0x74, + 0x63, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xbe, 0x46, 0x64, 0xc6, 0xc9, 0x6d, 0x92, + 0x89, 0x11, 0x41, 0x60, 0x91, 0x87, 0xf1, 0x64, 0x7c, 0x78, 0xd2, 0x7c, 0x94, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, + 0x16, 0x80, 0x14, 0x59, 0xb8, 0x2b, 0x94, 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, 0x33, 0xc9, 0x59, + 0xc3, 0x54, 0x98, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, + 0x86, 0x31, 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, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0d, 0x30, 0x0b, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x04, 0x01, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, + 0x06, 0x02, 0x13, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0x1b, 0x61, 0x6c, 0x35, 0xb9, 0x13, 0xb9, 0xb9, 0xac, 0xdc, 0x31, 0x8a, + 0x9c, 0x09, 0xb0, 0x5a, 0xe4, 0x63, 0x07, 0x0e, 0x74, 0xeb, 0xe8, 0x37, 0x28, 0x62, 0x39, 0xdb, 0x25, 0xbe, 0x6c, 0xff, + 0xea, 0x1b, 0xd4, 0x3f, 0x50, 0x23, 0xbd, 0xa6, 0x91, 0x1c, 0xfe, 0x9c, 0x2f, 0x52, 0xb6, 0x67, 0x2b, 0xf1, 0x7a, 0x9c, + 0xd8, 0x66, 0x6c, 0x07, 0xeb, 0x11, 0x88, 0x68, 0x66, 0x2b, 0xb6, 0xd0, 0x72, 0xdb, 0xcc, 0x3a, 0xa8, 0xb8, 0xb8, 0x1f, + 0xd0, 0x05, 0xaa, 0xb3, 0xb2, 0x7b, 0xc1, 0xa9, 0xfe, 0x5e, 0xd3, 0x1b, 0xfb, 0x88, 0xba, 0x60, 0xbe, 0x1e, 0xb1, 0x63, + 0x8a, 0xae, 0x21, 0x35, 0xc6, 0xc0, 0x42, 0xe0, 0xa3, 0x1a, 0xc3, 0x37, 0x25, 0x5c, 0xc5, 0xca, 0x35, 0x65, 0x4d, 0x6d, + 0x9c, 0x13, 0x69, 0xb5, 0xde, 0x07, 0x4c, 0xf8, 0x54, 0x96, 0x9a, 0x60, 0x94, 0xca, 0x1d, 0xa3, 0xb7, 0xf6, 0x49, 0x86, + 0x26, 0x06, 0xa8, 0x6a, 0x70, 0x22, 0x54, 0x4a, 0xd4, 0xfd, 0xd8, 0x2d, 0xae, 0xc1, 0x35, 0x42, 0xac, 0x50, 0x03, 0xe3, + 0x34, 0xd7, 0x52, 0xb5, 0x9e, 0xeb, 0xb6, 0x41, 0x98, 0x0b, 0xdd, 0xec, 0xf9, 0x7e, 0x5a, 0x55, 0xd2, 0xf5, 0x4c, 0xb5, + 0x78, 0x1a, 0xd8, 0x23, 0x31, 0xff, 0x67, 0x7e, 0x7f, 0x05, 0xd6, 0x20, 0x7f, 0xe4, 0x34, 0xd4, 0xd3, 0x8e, 0x8d, 0x75, + 0xe1, 0x8c, 0xf1, 0x60, 0x26, 0x4b, 0x88, 0x87, 0x6b, 0xbd, 0x88, 0x1d, 0xe2, 0xa6, 0x9b, 0xbf, 0x4d, 0xed, 0xd7, 0x31, + 0x13, 0x8f, 0xa0, 0x64, 0x63, 0x27, 0xbc, 0x06, 0xce, 0x9d, 0x91, 0xa4, 0x8d, 0xd3, 0x10, 0x25, 0x0c, 0xe7, 0xac, 0xef, + 0x7f, 0x21, 0xf1, 0xfb, 0xca, 0x80, 0x28, 0x0c, 0x4a, 0xd4, 0x52, 0x61, 0xbc, 0x7c, 0x3b, 0x88, 0x54, 0x16, 0x0e, 0x5f, + 0x14, 0x99, 0x4f, 0x30, 0x82, 0x04, 0xcc, 0x30, 0x82, 0x03, 0xb4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x3d, 0x00, + 0x4b, 0x90, 0x3e, 0xde, 0xe0, 0xd0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, + 0x00, 0x30, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 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, 0x1b, 0x30, + 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, + 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x34, 0x32, 0x32, 0x30, 0x32, 0x31, 0x35, + 0x34, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x67, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 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, 0x1b, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, + 0x20, 0x43, 0x41, 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, 0xc7, 0xd1, 0x43, 0x53, + 0x7f, 0x0d, 0x88, 0x6b, 0xe6, 0xb1, 0x67, 0x9d, 0xee, 0x67, 0xb6, 0xe7, 0x77, 0x12, 0x81, 0xc4, 0xdf, 0x24, 0x6b, 0x7a, + 0x75, 0x24, 0xf7, 0x01, 0x09, 0xce, 0x34, 0x92, 0xf5, 0x38, 0x08, 0x42, 0x7e, 0xec, 0x9d, 0xf2, 0x5d, 0x38, 0x91, 0xb4, + 0x93, 0x98, 0x35, 0x11, 0x3c, 0x98, 0x00, 0x77, 0xd9, 0xd7, 0xf3, 0x4a, 0xf8, 0xf0, 0xbc, 0xeb, 0x97, 0x5d, 0x4b, 0x61, + 0x2e, 0xfb, 0xc5, 0xcc, 0x68, 0xb7, 0x6d, 0x69, 0x10, 0xcc, 0xa5, 0x61, 0x78, 0xa8, 0x81, 0x02, 0x9e, 0xe7, 0x63, 0xc5, + 0xff, 0x29, 0x22, 0x82, 0x68, 0xaa, 0xaa, 0x0e, 0xfb, 0xa9, 0xd8, 0x16, 0x73, 0x25, 0xbf, 0x9d, 0x08, 0x62, 0x2f, 0x78, + 0x04, 0xf6, 0xf6, 0x44, 0x07, 0x37, 0x6e, 0x99, 0x1b, 0x93, 0xd8, 0x7f, 0xee, 0x72, 0xde, 0xe8, 0x32, 0xf6, 0x6d, 0x78, + 0x04, 0xa0, 0xa8, 0x21, 0x26, 0x8a, 0x32, 0xe3, 0xb1, 0x65, 0x85, 0xa1, 0x7b, 0x1a, 0xa9, 0x02, 0xb2, 0xbb, 0xee, 0xdd, + 0xdd, 0x8f, 0x41, 0x49, 0xc8, 0x3f, 0xdc, 0x1e, 0xdf, 0x21, 0xa3, 0x95, 0x99, 0xbb, 0xfc, 0x29, 0xba, 0x40, 0x43, 0xb9, + 0x1c, 0xcd, 0xc9, 0x21, 0x45, 0x73, 0xad, 0xff, 0xfd, 0xa2, 0x6c, 0x5c, 0x3b, 0x1c, 0x37, 0x91, 0x34, 0x8e, 0x5c, 0xd3, + 0xd5, 0x03, 0x58, 0x28, 0xc7, 0xf2, 0x76, 0x6f, 0x11, 0xc0, 0xb5, 0xbd, 0x7e, 0xef, 0x23, 0xb3, 0x3d, 0xb8, 0xbd, 0x38, + 0x66, 0x8c, 0xf2, 0x78, 0x95, 0xc1, 0x8b, 0x32, 0x65, 0x3a, 0x9b, 0x49, 0x1a, 0x5c, 0x41, 0x3c, 0xc6, 0x85, 0x50, 0xec, + 0x85, 0xf0, 0x59, 0x17, 0x81, 0xe8, 0x96, 0xe8, 0x6a, 0xcc, 0xb3, 0xc7, 0x46, 0xbf, 0x81, 0x48, 0xd1, 0x09, 0x1b, 0xbc, + 0x73, 0x1e, 0xd7, 0xe8, 0x27, 0xa8, 0x49, 0x48, 0xa2, 0x1c, 0x41, 0x1d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, + 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x59, 0xb8, 0x2b, 0x94, + 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, 0x33, 0xc9, 0x59, 0xc3, 0x54, 0x98, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x59, 0xb8, 0x2b, 0x94, 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, + 0x33, 0xc9, 0x59, 0xc3, 0x54, 0x98, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x08, 0x30, + 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, + 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, + 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, + 0xb6, 0x0c, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, + 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x10, + 0x5e, 0x6c, 0x69, 0xfc, 0xa6, 0x0f, 0xe2, 0x09, 0xd5, 0x94, 0x90, 0xa6, 0x7c, 0x22, 0xdc, 0xee, 0xb0, 0x8f, 0x24, 0x22, + 0x4f, 0xb3, 0x67, 0xdb, 0x32, 0xb0, 0xd6, 0x24, 0x87, 0xe6, 0xf3, 0xea, 0x9e, 0xd0, 0x95, 0x75, 0xaa, 0xa7, 0x08, 0xff, + 0xb0, 0x35, 0xd7, 0x1f, 0xa3, 0xbf, 0x89, 0x55, 0x0c, 0x1c, 0xa4, 0xd0, 0xf8, 0x00, 0x17, 0x44, 0x94, 0x36, 0x63, 0x3b, + 0x83, 0xfe, 0x4e, 0xe5, 0xb3, 0xec, 0x7b, 0x7d, 0xce, 0xfe, 0xa9, 0x54, 0xed, 0xbb, 0x12, 0xa6, 0x72, 0x2b, 0xb3, 0x48, + 0x00, 0xc7, 0x8e, 0xf5, 0x5b, 0x68, 0xc9, 0x24, 0x22, 0x7f, 0xa1, 0x4d, 0xfc, 0x54, 0xd9, 0xd0, 0x5d, 0x82, 0x53, 0x71, + 0x29, 0x66, 0xcf, 0x0f, 0x6d, 0x32, 0xa6, 0x3f, 0xae, 0x54, 0x27, 0xc2, 0x8c, 0x12, 0x4c, 0xf0, 0xd6, 0xc1, 0x80, 0x75, + 0xc3, 0x33, 0x19, 0xd1, 0x8b, 0x58, 0xe6, 0x00, 0x69, 0x76, 0xe7, 0xe5, 0x3d, 0x47, 0xf9, 0xc0, 0x9c, 0xe7, 0x19, 0x1e, + 0x95, 0xbc, 0x52, 0x15, 0xce, 0x94, 0xf8, 0x30, 0x14, 0x0b, 0x39, 0x0e, 0x8b, 0xaf, 0x29, 0x30, 0x56, 0xaf, 0x5a, 0x28, + 0xac, 0xe1, 0x0f, 0x51, 0x76, 0x76, 0x9a, 0xe7, 0xb9, 0x7d, 0xa3, 0x30, 0xe8, 0xe3, 0x71, 0x15, 0xe8, 0xbf, 0x0d, 0x4f, + 0x12, 0x9b, 0x65, 0xab, 0xef, 0xa4, 0xe9, 0x42, 0xf0, 0xd2, 0x4d, 0x20, 0x55, 0x29, 0x88, 0x58, 0x5c, 0x82, 0x67, 0x63, + 0x20, 0x50, 0xc6, 0xca, 0x04, 0xe8, 0xbc, 0x3d, 0x93, 0x06, 0x21, 0xb2, 0xc0, 0xbf, 0x53, 0x1e, 0xe1, 0x8b, 0x48, 0xa9, + 0xb9, 0xd7, 0xe6, 0x5f, 0x4e, 0x5a, 0x2f, 0x43, 0xac, 0x35, 0xbd, 0x26, 0x60, 0x2f, 0x01, 0xd5, 0x86, 0x6b, 0x64, 0xfa, + 0x67, 0x05, 0x44, 0x55, 0x83, 0x5b, 0x93, 0x9c, 0x7c, 0xa7, 0x26, 0x4e, 0x02, 0x2b, 0x48, 0x31, 0x82, 0x12, 0x71, 0x30, + 0x82, 0x12, 0x6d, 0x02, 0x01, 0x03, 0xa0, 0x16, 0x04, 0x14, 0x4e, 0xe9, 0xa9, 0xc3, 0x2e, 0x25, 0xd2, 0xa2, 0x7a, 0x8b, + 0x52, 0x3d, 0x16, 0x3c, 0xaf, 0xee, 0x41, 0xef, 0x79, 0x01, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0xa0, 0x69, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x51, 0xc4, 0xbf, 0xb0, 0x32, 0xf1, 0x05, 0x0d, 0xd1, 0x16, 0x4f, 0x18, + 0x9f, 0x54, 0x93, 0x36, 0x1c, 0x86, 0xad, 0x78, 0xcc, 0x14, 0x3f, 0xc1, 0xa5, 0x90, 0x1e, 0x78, 0x47, 0x05, 0xb4, 0x4d, + 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x03, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x39, 0x31, + 0x32, 0x33, 0x30, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x31, 0xad, 0x1c, 0x21, 0x85, 0x6d, 0xc8, 0x51, 0x8e, 0x2f, 0x3d, + 0x61, 0x54, 0x81, 0x55, 0xf3, 0x2d, 0x36, 0xea, 0x73, 0x63, 0xdb, 0x3d, 0x32, 0x2b, 0xe8, 0x2b, 0xd0, 0xcc, 0x6d, 0xd3, + 0xcf, 0x00, 0xf7, 0xf0, 0x9a, 0x3b, 0x09, 0xe8, 0x00, 0xaa, 0x94, 0xd4, 0x6a, 0x0d, 0x94, 0xbf, 0x01, 0xe9, 0x45, 0x06, + 0x54, 0xa0, 0xa1, 0xce, 0xa0, 0x4e, 0x2d, 0x41, 0xc4, 0xd4, 0xb9, 0xe0, 0xdd, 0xc7, 0x48, 0x2f, 0x5f, 0x48, 0x65, 0xbc, + 0x4e, 0x91, 0x6c, 0x15, 0x98, 0x91, 0xaa, 0xf6, 0xc1, 0x2b, 0x97, 0xd2, 0x2d, 0xbf, 0x3b, 0x30, 0x4b, 0xb3, 0x7b, 0x3c, + 0x80, 0xb7, 0xcc, 0x67, 0x4f, 0x79, 0xb5, 0x6d, 0x6e, 0xe6, 0x43, 0x86, 0x17, 0x92, 0x88, 0x2d, 0x1e, 0x55, 0x03, 0xcc, + 0x67, 0x7a, 0xe7, 0xdb, 0xa3, 0x99, 0xd9, 0x51, 0x7d, 0xbf, 0x03, 0x53, 0xf4, 0x89, 0x70, 0xbb, 0x8d, 0xaf, 0x61, 0x84, + 0x88, 0x1b, 0xc2, 0xd8, 0x62, 0x55, 0x1d, 0x50, 0x9c, 0x48, 0xd2, 0xc6, 0x90, 0x22, 0x82, 0x01, 0xa0, 0x03, 0xab, 0x63, + 0x9a, 0xab, 0x94, 0xa2, 0x75, 0xf9, 0x97, 0x4a, 0x22, 0x3f, 0xd8, 0xfb, 0xb4, 0x62, 0x1e, 0x83, 0x2a, 0x86, 0x62, 0x15, + 0xbf, 0x4a, 0x8c, 0xf5, 0xa1, 0xc3, 0x8a, 0x8a, 0xa5, 0x1b, 0x00, 0x77, 0x6b, 0x04, 0x85, 0x11, 0x4d, 0x47, 0x11, 0xe0, + 0x8e, 0xaa, 0x86, 0x23, 0x1c, 0xef, 0x74, 0xdf, 0x90, 0x2b, 0xfb, 0xba, 0x61, 0x03, 0xc9, 0xd9, 0x59, 0x9b, 0xb1, 0x01, + 0x77, 0xba, 0x7e, 0x89, 0x1c, 0x3b, 0x65, 0xdf, 0x01, 0xd2, 0x61, 0xfe, 0x51, 0x87, 0x36, 0x4b, 0x91, 0x2a, 0x69, 0xad, + 0xa2, 0xcd, 0x0c, 0xee, 0xb7, 0xe5, 0xb0, 0xbf, 0x8b, 0xc4, 0x0b, 0xeb, 0xbf, 0x11, 0xaa, 0x26, 0x47, 0x9a, 0xc3, 0xfc, + 0x7d, 0x61, 0xeb, 0xed, 0x50, 0xa1, 0x82, 0x10, 0xc3, 0x30, 0x82, 0x10, 0xbf, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0e, 0x31, 0x82, 0x10, 0xae, 0x30, 0x82, 0x10, 0xaa, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x10, 0x9b, 0x30, 0x82, 0x10, 0x97, 0x02, 0x01, 0x03, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x6d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x10, 0x01, 0x04, 0xa0, 0x5e, 0x04, 0x5c, 0x30, 0x5a, 0x02, 0x01, 0x01, 0x06, 0x02, 0x2a, 0x03, 0x30, 0x31, 0x30, + 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0x7e, 0xbb, 0x6f, 0xa9, + 0x87, 0xe1, 0x0b, 0xa5, 0x7e, 0x3b, 0xef, 0x40, 0x89, 0x6a, 0x2b, 0x64, 0x42, 0x29, 0x71, 0x0f, 0x81, 0x1d, 0x26, 0x9b, + 0x0a, 0x84, 0x07, 0xbf, 0x63, 0x61, 0xde, 0x0a, 0x02, 0x08, 0x4a, 0x30, 0x03, 0xb3, 0xaf, 0xe2, 0xb0, 0x10, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x38, 0x30, 0x33, 0x32, 0x37, 0x32, 0x33, 0x34, 0x30, 0x35, 0x35, 0x5a, 0x30, 0x03, 0x02, 0x01, 0x01, + 0xa0, 0x82, 0x0d, 0xd1, 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x55, + 0xbd, 0xb7, 0x92, 0xdb, 0x54, 0x05, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, + 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 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, 0x33, 0x30, 0x36, 0x30, 0x31, + 0x33, 0x30, 0x30, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x34, 0x31, 0x37, 0x30, 0x31, 0x33, 0x30, 0x30, 0x33, 0x5a, + 0x30, 0x42, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x4e, 0x57, 0x4b, 0x32, 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, 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, 0xbc, 0x9b, 0x45, 0x28, 0x53, 0xe1, 0x51, 0xbf, 0xef, 0x09, 0x31, 0x1d, 0x75, 0x65, 0x97, 0x05, 0x46, 0x6e, 0x59, + 0x18, 0xc2, 0x6d, 0x3a, 0x85, 0x1d, 0x0d, 0x2e, 0x78, 0x7c, 0x50, 0xdf, 0x57, 0x02, 0x32, 0x4f, 0x6b, 0x13, 0xb6, 0x33, + 0xdd, 0xff, 0x44, 0x4a, 0xed, 0xdf, 0x6b, 0xcb, 0xd5, 0x21, 0xd2, 0x96, 0x40, 0x43, 0xde, 0x0f, 0x90, 0x8f, 0x29, 0x6a, + 0x09, 0xf4, 0xac, 0x43, 0xd6, 0xbc, 0x61, 0xbb, 0x47, 0xd7, 0xde, 0xba, 0x4e, 0x68, 0x3a, 0x42, 0x4b, 0x45, 0xcc, 0x76, + 0x15, 0xdb, 0x17, 0x3b, 0x51, 0xbf, 0x73, 0x85, 0x7e, 0x00, 0x2c, 0xa4, 0x0a, 0x94, 0x1e, 0x5c, 0x1b, 0x3b, 0x26, 0xe4, + 0x56, 0x52, 0xb5, 0xc2, 0x78, 0x56, 0xbf, 0x43, 0xb9, 0xab, 0xa2, 0x7a, 0x52, 0xbd, 0x3b, 0x3f, 0x7c, 0x11, 0x88, 0x5f, + 0x8c, 0xf3, 0x36, 0x00, 0xb1, 0xe6, 0x43, 0xdb, 0x84, 0xa4, 0x3e, 0x9e, 0x87, 0xcb, 0x09, 0x25, 0x71, 0x8a, 0x45, 0x9e, + 0xbb, 0x0a, 0x62, 0x4c, 0xfa, 0xcc, 0xaa, 0x97, 0xba, 0x6d, 0x90, 0x9e, 0x0d, 0x0c, 0xac, 0x60, 0xe7, 0x5e, 0x61, 0xa2, + 0xc5, 0x29, 0x5c, 0x64, 0x5f, 0xc3, 0xd8, 0x2c, 0xe7, 0x1b, 0x57, 0x32, 0x79, 0x97, 0xae, 0x97, 0x3f, 0x19, 0x1b, 0xe9, + 0xb9, 0x2a, 0x53, 0x23, 0xfc, 0x9b, 0x3c, 0x88, 0x90, 0xaa, 0x58, 0xde, 0x0b, 0x91, 0x45, 0xb1, 0x26, 0xb9, 0xc0, 0x6d, + 0x9e, 0x3b, 0x1e, 0x56, 0x19, 0x7a, 0xf2, 0x5f, 0xa9, 0x82, 0x9d, 0x88, 0xbe, 0x53, 0x10, 0x02, 0x7f, 0x80, 0x79, 0x15, + 0xc1, 0x60, 0xc7, 0xe0, 0xbf, 0xe9, 0x0c, 0x5c, 0x16, 0xb3, 0x6d, 0xda, 0x61, 0xb2, 0xe8, 0x6d, 0x26, 0xf1, 0xe2, 0xb1, + 0xea, 0x1d, 0x66, 0x42, 0xe7, 0x6c, 0x4a, 0xf2, 0xa4, 0xaa, 0x49, 0xfe, 0xfb, 0x7e, 0xbf, 0x5f, 0xbb, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0xc1, 0x30, 0x82, 0x01, 0xbd, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x60, 0xd9, 0x78, 0x59, 0xea, 0xb0, 0x24, 0x26, 0x69, 0xac, 0xd9, 0xc1, 0xa3, 0xac, 0xb0, 0x50, 0xaa, 0x37, 0xcb, + 0x97, 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, 0x34, 0xcd, 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, + 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 0x30, 0x82, 0x01, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, + 0x05, 0x30, 0x82, 0x01, 0x01, 0x30, 0x81, 0xfe, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, + 0x81, 0xf0, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, + 0x6c, 0x65, 0x63, 0x61, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0xb6, + 0x0c, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, + 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, + 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, + 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x34, 0xf6, 0x34, 0x61, 0x30, + 0x1c, 0x0a, 0xa4, 0xf1, 0x2a, 0x4e, 0x47, 0xf2, 0xb3, 0x5a, 0x6b, 0xfe, 0x9e, 0x33, 0x8f, 0xa6, 0x44, 0x8b, 0xd0, 0x37, + 0x2c, 0xff, 0x00, 0xb3, 0x83, 0xaf, 0x42, 0x2e, 0xa5, 0x98, 0x77, 0x5d, 0x1c, 0x75, 0xbd, 0xaa, 0x68, 0x62, 0x5b, 0xbe, + 0x59, 0x91, 0x9e, 0x58, 0xfd, 0xe4, 0x74, 0xe2, 0x7c, 0x5c, 0xb8, 0xb3, 0xb5, 0x66, 0xda, 0x78, 0xda, 0xf7, 0x58, 0x6f, + 0xcd, 0x50, 0x77, 0x01, 0xe3, 0x99, 0x84, 0xf2, 0x77, 0x66, 0xba, 0x7c, 0xbe, 0x97, 0xe9, 0x2d, 0x2e, 0x83, 0x2d, 0xcc, + 0x73, 0x3a, 0x6a, 0x42, 0xed, 0x58, 0xb0, 0x34, 0x7d, 0xe0, 0xa7, 0x48, 0x6b, 0xe9, 0x39, 0x92, 0xdf, 0x67, 0x05, 0xe5, + 0x01, 0x5e, 0xeb, 0x63, 0xc1, 0x35, 0x3a, 0x58, 0xdc, 0x44, 0x35, 0x39, 0x5c, 0xe5, 0xe0, 0x4d, 0x9b, 0x72, 0xb7, 0x0b, + 0x59, 0x5a, 0x4a, 0x0d, 0x07, 0x61, 0x5d, 0x0f, 0xf8, 0x19, 0x42, 0x10, 0xd9, 0x77, 0xaf, 0xdf, 0x3d, 0xac, 0x86, 0xf0, + 0x5f, 0x66, 0x11, 0x4d, 0x94, 0x38, 0x3f, 0xca, 0xb9, 0x0c, 0xbf, 0xbf, 0x7d, 0x00, 0x51, 0x74, 0x61, 0xd2, 0xc7, 0x75, + 0xab, 0xe4, 0x99, 0x0f, 0x18, 0xd2, 0x5e, 0x6d, 0xa0, 0x2a, 0x96, 0x52, 0x36, 0xa9, 0xa3, 0xbb, 0x20, 0xde, 0x0c, 0x6e, + 0xfa, 0x86, 0x25, 0xee, 0x05, 0x80, 0x7f, 0x56, 0x6a, 0xd7, 0xc8, 0xaa, 0xbc, 0x4b, 0x85, 0x94, 0xe8, 0x38, 0xc5, 0x45, + 0xd8, 0x15, 0x97, 0xde, 0x69, 0x1a, 0x14, 0x04, 0xa4, 0xfc, 0x84, 0x8c, 0xef, 0xe3, 0x23, 0x0d, 0xe1, 0x6b, 0x23, 0x5f, + 0xdf, 0x47, 0x93, 0x22, 0x24, 0xe8, 0x12, 0x2b, 0xbd, 0xd1, 0x6f, 0xcb, 0xb5, 0x65, 0x89, 0xa0, 0x9f, 0x78, 0xb3, 0xdb, + 0x55, 0xf5, 0x34, 0x41, 0x99, 0x00, 0xd8, 0x31, 0x49, 0x00, 0xb9, 0x30, 0x82, 0x04, 0x07, 0x30, 0x82, 0x02, 0xef, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x7d, 0x4c, 0x57, 0x63, 0x9f, 0xf3, 0xf0, 0xb7, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, + 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x35, 0x31, + 0x32, 0x30, 0x32, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x34, 0x30, 0x35, 0x31, 0x32, 0x30, 0x32, 0x34, 0x34, + 0x5a, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 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, 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, + 0xd3, 0x77, 0x18, 0xa1, 0xf7, 0x99, 0x10, 0x67, 0x5c, 0xd2, 0x2e, 0x9e, 0xb8, 0x8f, 0x23, 0x67, 0x3e, 0xfc, 0x42, 0xe2, + 0x09, 0x7d, 0x0a, 0x8a, 0xb8, 0x18, 0xfc, 0x73, 0x40, 0x2f, 0xbd, 0xc4, 0xd8, 0x50, 0xc5, 0x27, 0xc8, 0xfe, 0xb8, 0x34, + 0x70, 0xa0, 0x0d, 0x13, 0x3c, 0xbd, 0x08, 0x4e, 0x9a, 0x93, 0x6f, 0x39, 0x37, 0xda, 0x9e, 0x65, 0xf5, 0xb4, 0x63, 0xf4, + 0x90, 0xc8, 0x49, 0x6d, 0x5d, 0x20, 0xd3, 0x39, 0xfd, 0x09, 0xba, 0xf4, 0x3a, 0xf3, 0xce, 0x4a, 0x69, 0x64, 0x05, 0x99, + 0x46, 0xe0, 0xda, 0x35, 0xc4, 0x65, 0x18, 0x1e, 0xc6, 0x16, 0xa3, 0x12, 0x61, 0xb4, 0x2e, 0xf5, 0xf0, 0x89, 0x0d, 0x8c, + 0xdc, 0x3d, 0xf6, 0x06, 0xcf, 0x6f, 0x86, 0x25, 0x4c, 0x09, 0xc2, 0x1b, 0xc8, 0x0e, 0x78, 0x88, 0x8d, 0xc1, 0x22, 0xb8, + 0xba, 0x21, 0x13, 0x9b, 0xca, 0xee, 0x8a, 0x9e, 0xdd, 0x7b, 0x5b, 0xff, 0xa3, 0xe9, 0xd1, 0xa3, 0x81, 0x7e, 0xfe, 0xff, + 0xe6, 0x8c, 0x49, 0xe4, 0x3b, 0x0a, 0xf9, 0x10, 0xa6, 0x72, 0x33, 0xbb, 0x2c, 0xc4, 0x4a, 0x5a, 0x72, 0x0a, 0x39, 0x50, + 0x74, 0xdd, 0x28, 0x6e, 0x79, 0x5f, 0x7e, 0xa7, 0xa8, 0x14, 0xcf, 0x56, 0xb3, 0x56, 0x6c, 0xa5, 0xe9, 0xf0, 0xc4, 0xae, + 0xf9, 0xea, 0x20, 0x8e, 0x18, 0xc7, 0x28, 0x74, 0xe2, 0x08, 0x4d, 0x89, 0x26, 0x42, 0x79, 0x5e, 0xf6, 0x60, 0xe3, 0x45, + 0x58, 0xa1, 0xfb, 0x51, 0x49, 0x5e, 0x92, 0x4a, 0x4d, 0xb9, 0xef, 0xd4, 0x73, 0xb5, 0xda, 0x04, 0x7b, 0xe3, 0x52, 0x9f, + 0xcb, 0xa3, 0x19, 0x5d, 0xac, 0x6b, 0x98, 0x6c, 0x9e, 0xe2, 0xec, 0x74, 0x2d, 0x44, 0x3e, 0xe0, 0x61, 0x3e, 0x07, 0x45, + 0x7e, 0x34, 0x75, 0x26, 0x98, 0x40, 0x9b, 0x75, 0x9e, 0xc8, 0x30, 0xed, 0x4b, 0xbf, 0x77, 0x8f, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x34, 0xcd, + 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, + 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x27, 0x30, 0x25, 0x30, + 0x23, 0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, + 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x63, 0x64, 0x06, 0x02, 0x09, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x36, 0xd2, 0xf5, 0xde, 0x71, 0x53, 0x07, 0xc9, 0x23, 0xd8, + 0x78, 0x9b, 0x65, 0xbc, 0xf3, 0xd5, 0x5b, 0xe9, 0xb8, 0x7f, 0x1b, 0x23, 0xc7, 0xa2, 0xcf, 0xb4, 0xa9, 0x28, 0xe9, 0xf8, + 0xdd, 0x70, 0x88, 0x21, 0x39, 0xf3, 0xdb, 0x33, 0x9c, 0xc3, 0x72, 0x43, 0xd6, 0x3d, 0x42, 0x51, 0x97, 0xba, 0xad, 0x1d, + 0x8e, 0x92, 0xd2, 0x75, 0x8b, 0xc3, 0x5d, 0x9c, 0xf5, 0xcb, 0x8c, 0xdc, 0x6a, 0x6a, 0x3a, 0xdd, 0xeb, 0x54, 0x7d, 0xed, + 0x14, 0x6b, 0xf3, 0xd6, 0x3e, 0x93, 0xc8, 0x6d, 0x7a, 0x54, 0x5f, 0xf2, 0x43, 0x8e, 0x10, 0xd0, 0x76, 0x5c, 0x9b, 0x00, + 0x0c, 0x1d, 0x4e, 0xca, 0x3c, 0xcd, 0xfa, 0xe6, 0xf7, 0xc2, 0x3e, 0x72, 0xb7, 0xb8, 0xde, 0xe8, 0x34, 0xaa, 0x15, 0xa0, + 0xae, 0x5c, 0x67, 0xa8, 0x0c, 0xac, 0x9b, 0x1e, 0x65, 0xb3, 0xe3, 0x0f, 0x30, 0x42, 0x34, 0xe9, 0xae, 0xd3, 0x01, 0xd3, + 0xa7, 0xdd, 0x42, 0x73, 0x75, 0x7c, 0x51, 0x43, 0x85, 0x9a, 0x60, 0x10, 0xdc, 0xae, 0x27, 0xd2, 0x6b, 0x67, 0xc9, 0x33, + 0x45, 0x6f, 0xc9, 0x98, 0x1e, 0xa0, 0x9a, 0x7f, 0x4d, 0x11, 0x93, 0xe1, 0x69, 0xff, 0xec, 0x4b, 0x45, 0xf3, 0x4e, 0xca, + 0x22, 0x0e, 0x57, 0xd7, 0x22, 0x07, 0xe5, 0x22, 0xb4, 0x87, 0xe9, 0x9c, 0xd3, 0x45, 0xcb, 0x6e, 0x3f, 0xe5, 0x8e, 0xb8, + 0xfc, 0x46, 0xd5, 0x5c, 0xc9, 0xb0, 0xab, 0x05, 0x3a, 0x6d, 0x37, 0x28, 0xa3, 0xa8, 0x46, 0x65, 0x6f, 0x55, 0xa1, 0x68, + 0x88, 0xea, 0x52, 0x3e, 0xc9, 0xf4, 0xd4, 0xe6, 0xfa, 0x3f, 0xa4, 0xe4, 0x26, 0x80, 0xb5, 0x3a, 0x6b, 0xd6, 0xc3, 0xe5, + 0xf9, 0x32, 0x81, 0xc8, 0x32, 0xa2, 0x48, 0xe1, 0x8e, 0x06, 0xa3, 0x19, 0xe4, 0xb3, 0xcb, 0x3b, 0x4b, 0xdf, 0xe0, 0xcc, + 0x0e, 0xb2, 0xaf, 0x98, 0xd1, 0x83, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x62, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, + 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, + 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, + 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 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, 0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84, 0x2d, 0xeb, + 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30, 0x02, 0xe8, + 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3, + 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b, 0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4, + 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25, 0x03, 0xba, + 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d, 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, + 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f, 0x70, 0xb6, 0x3f, + 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e, + 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74, + 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, 0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb, + 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62, 0x0b, 0x10, + 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c, 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, + 0x73, 0xff, 0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, + 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, + 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, + 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, + 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, + 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, + 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 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, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, + 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, 0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2, + 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b, 0x40, 0x8e, + 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f, 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, + 0x3e, 0xf9, 0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1, 0xbf, 0x9a, + 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b, + 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d, + 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5, 0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2, + 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8, 0x44, 0x48, + 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7, 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, + 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda, 0x0f, 0x21, 0x0e, + 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8, + 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c, + 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, 0x09, 0x07, 0x37, 0xb0, 0x75, 0x75, + 0x21, 0x31, 0x82, 0x02, 0x3f, 0x30, 0x82, 0x02, 0x3b, 0x02, 0x01, 0x01, 0x30, 0x81, 0x88, 0x30, 0x7c, 0x31, 0x30, 0x30, + 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 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, 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, 0x02, 0x08, 0x55, 0xbd, 0xb7, 0x92, 0xdb, 0x54, 0x05, 0xfd, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0x00, 0xa0, 0x81, 0x8c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0d, + 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32, 0x37, 0x32, 0x33, 0x34, 0x30, + 0x35, 0x35, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14, + 0xc4, 0xbb, 0xb7, 0xc5, 0x0e, 0x2a, 0x51, 0x27, 0x41, 0x95, 0x46, 0x04, 0x67, 0x08, 0xc6, 0x3e, 0xf3, 0xb7, 0x57, 0x21, + 0x30, 0x2b, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0c, 0x31, 0x1c, 0x30, 0x1a, 0x30, + 0x18, 0x30, 0x16, 0x04, 0x14, 0xc5, 0xe5, 0x93, 0x54, 0xe1, 0x09, 0x59, 0x31, 0x49, 0x9b, 0x0e, 0xde, 0xbb, 0xda, 0x5c, + 0xc9, 0x20, 0x94, 0x1c, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x04, 0x82, 0x01, 0x00, 0x01, 0x3c, 0x74, 0x68, 0x64, 0x90, 0x55, 0xb1, 0x78, 0x2b, 0xa4, 0xd6, 0x4a, 0x79, 0xe6, 0x25, + 0x38, 0xe6, 0x2c, 0xc7, 0xe4, 0xa2, 0x59, 0xab, 0xc5, 0x54, 0x62, 0x05, 0xf3, 0xb0, 0x9a, 0xf8, 0x04, 0xf6, 0x73, 0x25, + 0x91, 0x9c, 0x0e, 0xc4, 0xe4, 0xf9, 0x75, 0xbd, 0xdb, 0xcc, 0xfc, 0x2d, 0x36, 0xa1, 0x1b, 0x86, 0x0e, 0xef, 0x56, 0x12, + 0x60, 0xc4, 0x48, 0xd9, 0x13, 0x80, 0x95, 0x8f, 0x74, 0x77, 0xae, 0x0c, 0x0d, 0x84, 0x71, 0x90, 0x2f, 0x31, 0x2f, 0x23, + 0x05, 0xe9, 0xbb, 0x80, 0x77, 0xc5, 0x5f, 0x4d, 0x56, 0x26, 0x68, 0xa1, 0xc4, 0x9e, 0x3c, 0xe8, 0x61, 0x49, 0xb2, 0x79, + 0x6c, 0x03, 0x04, 0x41, 0x2b, 0x12, 0x3d, 0x28, 0x10, 0xac, 0xc4, 0x2f, 0xca, 0x66, 0x59, 0xd1, 0xaa, 0x3c, 0xaa, 0x8d, + 0x08, 0xdd, 0x85, 0x3e, 0x09, 0xe5, 0xfd, 0x72, 0xed, 0xe5, 0x01, 0xd9, 0xc9, 0x25, 0xc9, 0xa5, 0x47, 0x04, 0xa0, 0xe8, + 0x13, 0xa2, 0x7b, 0xf1, 0x6d, 0xe2, 0x15, 0x74, 0xf9, 0x37, 0x86, 0x8b, 0x6c, 0x5f, 0x24, 0xbc, 0x13, 0x02, 0xdd, 0x95, + 0x73, 0x69, 0xb0, 0xc1, 0xdb, 0x92, 0xea, 0xbf, 0x4c, 0xe1, 0xd7, 0xca, 0x3c, 0x58, 0x1b, 0xa1, 0x61, 0x8b, 0x0a, 0x3d, + 0x22, 0x11, 0xad, 0xd3, 0xa2, 0x4c, 0xfd, 0x5f, 0x38, 0x58, 0xdf, 0x24, 0x9b, 0xbf, 0xb8, 0x0e, 0xb4, 0x8e, 0xd9, 0xe7, + 0x10, 0x43, 0xa6, 0x2e, 0x49, 0x4d, 0x4c, 0xdf, 0xee, 0xb4, 0x96, 0x49, 0x27, 0x00, 0x6c, 0xd3, 0x15, 0xbf, 0xf4, 0x7b, + 0x70, 0x1b, 0x94, 0xad, 0xd7, 0x68, 0x24, 0x3a, 0x14, 0x84, 0x45, 0x52, 0xe9, 0x31, 0x66, 0xea, 0x28, 0x9c, 0xd4, 0x44, + 0x78, 0xea, 0x0a, 0x8e, 0x26, 0xde, 0xa7, 0xb1, 0xe9, 0x1a, 0xff, 0x21, 0x3d, 0xc7, 0x21, 0xea, 0xbb, 0x08, 0x3d, 0xee +}; + +uint8_t _no_expiration_attr[] = { + 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, + 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 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, 0x02, 0x47, 0x30, 0x82, 0x02, 0x43, 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, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x69, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x33, 0x31, 0x38, + 0x31, 0x33, 0x32, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, + 0x31, 0x22, 0x04, 0x20, 0x33, 0x1f, 0x3a, 0xc4, 0x95, 0x97, 0x64, 0x1c, 0x99, 0x9b, 0x37, 0xc8, 0xf2, 0xba, 0xd0, 0xb4, + 0x38, 0xa5, 0x9c, 0x3a, 0xa3, 0x78, 0xf9, 0xfb, 0x66, 0x28, 0x4e, 0x6a, 0x90, 0xcc, 0x0e, 0x4c, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xae, 0x6d, 0xa9, 0xa7, 0xee, + 0x0c, 0x94, 0x1b, 0xf3, 0x93, 0x40, 0x43, 0x11, 0x41, 0x20, 0x11, 0x60, 0xd9, 0x4e, 0xb6, 0x2d, 0x3e, 0x98, 0xfe, 0x06, + 0xd2, 0xc4, 0xe4, 0x0a, 0x66, 0xdc, 0xbb, 0xbd, 0x4d, 0x8e, 0xcb, 0xe1, 0x87, 0x39, 0x3f, 0xb3, 0x4b, 0xf8, 0xe7, 0x18, + 0x6f, 0x39, 0xad, 0x01, 0xd4, 0xe8, 0x85, 0x8c, 0x84, 0x96, 0x2c, 0x3a, 0xd4, 0xcf, 0x3c, 0xe5, 0x05, 0xdd, 0xc7, 0xc0, + 0xb7, 0x72, 0x7b, 0x32, 0xa1, 0xff, 0x69, 0x51, 0xd4, 0xc9, 0x3e, 0x1f, 0x89, 0x71, 0x39, 0xd9, 0x99, 0x1e, 0xa9, 0x33, + 0x83, 0xc1, 0x37, 0x3e, 0xf2, 0xbd, 0xad, 0x8f, 0xa9, 0x24, 0x82, 0xad, 0x7d, 0x54, 0x8f, 0x6f, 0x8a, 0xdb, 0xbf, 0xd4, + 0xd4, 0x9c, 0x0a, 0x11, 0x8a, 0xb2, 0x0c, 0xd9, 0x32, 0xf1, 0xe6, 0x76, 0x4a, 0x09, 0x1a, 0x6a, 0xdf, 0x48, 0x2f, 0xf4, + 0x89, 0x73, 0xc8, 0x37, 0xb0, 0x14, 0xa9, 0x59, 0xc3, 0x94, 0x63, 0x6c, 0xfd, 0x90, 0x2c, 0x3a, 0x58, 0xa4, 0x5e, 0xbb, + 0x2f, 0x5e, 0x1d, 0xdc, 0x57, 0x47, 0x09, 0x77, 0xbc, 0x2b, 0x76, 0xfa, 0x97, 0x85, 0x63, 0x4b, 0xd6, 0x32, 0xac, 0x7e, + 0xa0, 0x41, 0xd1, 0xc7, 0x1a, 0x59, 0x3f, 0x39, 0xd1, 0xa7, 0x3f, 0xa7, 0x3f, 0x23, 0x11, 0x3e, 0x19, 0x6d, 0x63, 0xa1, + 0x4c, 0xcd, 0x03, 0x22, 0x07, 0x72, 0x4c, 0x44, 0x07, 0xd9, 0x85, 0x18, 0x63, 0x8c, 0x96, 0x29, 0x20, 0xc4, 0x1b, 0xac, + 0x6e, 0x4f, 0x95, 0x7d, 0x97, 0x9f, 0xcc, 0x94, 0xf4, 0xfe, 0x8b, 0x08, 0x1c, 0x8a, 0x9d, 0x19, 0x6d, 0x42, 0x92, 0x73, + 0xa9, 0xd0, 0xb3, 0x4c, 0x46, 0x40, 0x88, 0xcb, 0x51, 0x2f, 0x73, 0xec, 0x43, 0x4c, 0x09, 0xa7, 0xb5, 0x89, 0x4b, 0xe4, + 0xbc, 0xdc, 0x1d, 0x17, 0xf9, 0x55, 0xe5, 0x59, 0xea, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.m b/OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.m new file mode 100644 index 00000000..da84844a --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.m @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2018 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@ + */ + +#include +#import + +#include +#include +#include +#include + +#include + +#if TARGET_OS_OSX +#include +#include +#include +#endif + +#include "shared_regressions.h" + +#include "si-35-cms-expiration-time.h" + +/* MARK: SecCMS tests */ +static void SecCMS_positive_tests(void) { + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFDictionaryRef tmpAttrs = NULL; + NSDictionary* attrs = nil; + NSData *expirationDateOid = nil, *unparsedExpirationDate = nil; + NSArray *attrValues = nil; + NSDate *expirationDate = nil, *expectedDate = [NSDate dateWithTimeIntervalSinceReferenceDate: 599400000.0]; + + NSData *message = [NSData dataWithBytes:_css_gen_expiration_time length:sizeof(_css_gen_expiration_time)]; + NSData *content = [NSData dataWithBytes:_css_content length:sizeof(_css_content)]; + policy = SecPolicyCreateBasicX509(); + + /* verify a valid message and copy out attributes */ + ok_status(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, (__bridge CFDataRef)content, policy, &trust, NULL, &tmpAttrs), + "Failed to verify valid CMS message and get out attributes"); + require_action(attrs = CFBridgingRelease(tmpAttrs), exit, fail("Failed to copy attributes")); + + /* verify we can get the parsed expiration date attribute out */ + uint8_t appleExpirationDateOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x3 }; + expirationDateOid = [NSData dataWithBytes:appleExpirationDateOid length:sizeof(appleExpirationDateOid)]; + attrValues = attrs[expirationDateOid]; + is([attrValues count], (size_t)1, "Wrong number of attribute values"); + require_action(unparsedExpirationDate = attrValues[0], exit, fail("Failed to get expiration date attribute value")); + uint8_t expectedUTCData[] = { 0x31, 0x39, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a }; + is([unparsedExpirationDate isEqualToData:[NSData dataWithBytes:expectedUTCData length:sizeof(expectedUTCData)]], true, "Failed to get correct expiration date"); + + /* verify we can get the "cooked" expiration data out */ + ok(expirationDate = attrs[(__bridge NSString*)kSecCMSExpirationDate], "Failed to get pre-parsed expiration date from attributes"); + is([expirationDate isEqualToDate:expectedDate], true, "Failed to get correct expiration date"); + +exit: + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +static void SecCMS_negative_date_changed(void) { + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + + NSMutableData *invalid_message = [NSMutableData dataWithBytes:_css_gen_expiration_time length:sizeof(_css_gen_expiration_time)]; + [invalid_message resetBytesInRange:NSMakeRange(3980, 1)]; // reset byte in expiration date attribute of _css_gen_expiration_time + NSData *content = [NSData dataWithBytes:_css_content length:sizeof(_css_content)]; + policy = SecPolicyCreateBasicX509(); + + /* Verify message with expiration date changed fails*/ + is(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)invalid_message, (__bridge CFDataRef)content, policy, &trust, NULL, NULL), + errSecAuthFailed, "Failed to verify valid CMS message and get out attributes"); + + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +static void SecCMS_negative_missing_date(void) { + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFDictionaryRef tmpAttrs = NULL; + NSDictionary *attrs = nil; + NSData *expirationDateOid = nil; + + NSData *message = [NSData dataWithBytes:_no_expiration_attr length:sizeof(_no_expiration_attr)]; + policy = SecPolicyCreateBasicX509(); + + /* verify a message with no expiration date */ + ok_status(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, NULL, policy, &trust, NULL, &tmpAttrs), + "Failed to verify valid CMS message and get out attributes"); + require_action(attrs = CFBridgingRelease(tmpAttrs), exit, fail("Failed to copy attributes")); + + /* verify we can't get the expiration date out */ + uint8_t appleExpirationDateOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x3 }; + expirationDateOid = [NSData dataWithBytes:appleExpirationDateOid length:sizeof(appleExpirationDateOid)]; + is(attrs[expirationDateOid], NULL, "Got an expiration date attribute from message with no expiration date"); + is(attrs[(__bridge NSString*)kSecCMSExpirationDate], NULL, "Got an expiration date attribute from message with no expiration date"); + +exit: + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +static void SecCMS_tests(void) { + SecCMS_positive_tests(); + SecCMS_negative_date_changed(); + SecCMS_negative_missing_date(); +} + +/* MARK: CMSEncoder tests */ +static void CMSEncoder_tests(SecIdentityRef identity) { + CMSEncoderRef encoder = NULL; + CMSDecoderRef decoder = NULL; + CFDataRef message = NULL; + + /* Create encoder */ + require_noerr_action(CMSEncoderCreate(&encoder), exit, fail("Failed to create CMS encoder")); + require_noerr_action(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit, + fail("Failed to set digest algorithm to SHA256")); + + /* Set identity as signer */ + require_noerr_action(CMSEncoderAddSigners(encoder, identity), exit, fail("Failed to add signer identity")); + + /* Add signing time attribute for 6 June 2018 */ + require_noerr_action(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), exit, + fail("Failed to set signing time flag")); + require_noerr_action(CMSEncoderSetSigningTime(encoder, 550000000.0), exit, fail("Failed to set signing time")); + + /* Add expiration date attribute for 30 September 2018 */ + ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleExpirationTime), + "Set expiration date flag"); + ok_status(CMSEncoderSetAppleExpirationTime(encoder, 560000000.0), "Set Expiration time"); + + /* Load content */ + require_noerr_action(CMSEncoderSetHasDetachedContent(encoder, true), exit, fail("Failed to set detached content")); + require_noerr_action(CMSEncoderUpdateContent(encoder, _css_content, sizeof(_css_content)), exit, fail("Failed to set content")); + + /* output cms message */ + ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); + isnt(message, NULL, "Encoded message exists"); + + /* decode message */ + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), + CFDataGetLength(message)), exit, + fail("Update decoder with CMS message")); + require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:_css_content + length:sizeof(_css_content)]), + exit, fail("Set detached content")); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + +exit: + CFReleaseNull(encoder); + CFReleaseNull(message); + CFReleaseNull(decoder); +} + +/* MARK: CMSDecoder tests */ +static void CMSDecoder_positive_tests(void) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + NSData *_css_contentData = nil; + CFAbsoluteTime expirationTime = 0; + NSDate *expirationDate = nil, *expectedDate = [NSDate dateWithTimeIntervalSinceReferenceDate: 599400000.0]; + + /* Create decoder and decode */ + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, _css_gen_expiration_time, sizeof(_css_gen_expiration_time)), exit, + fail("Failed to update decoder with CMS message")); + _css_contentData = [NSData dataWithBytes:_css_content length:sizeof(_css_content)]; + require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)_css_contentData), exit, + fail("Failed to set detached _css_content")); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy")); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Expiration Time Attribute value */ + ok_status(CMSDecoderCopySignerAppleExpirationTime(decoder, 0, &expirationTime), + "Got expiration time from message with no expiration attribute"); + expirationDate = [NSDate dateWithTimeIntervalSinceReferenceDate:expirationTime]; + is([expirationDate isEqualToDate:expectedDate], true, "Got wrong expiration time"); // 31 December 2019 12:00:00 Zulu + +exit: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +static void CMSDecoder_negative_date_changed(void) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + NSData *_css_contentData = nil; + NSMutableData *invalid_message = nil; + + /* Create decoder and decode */ + invalid_message = [NSMutableData dataWithBytes:_css_gen_expiration_time length:sizeof(_css_gen_expiration_time)]; + [invalid_message resetBytesInRange:NSMakeRange(3980, 1)]; // reset byte in expiration date attribute of _css_gen_expiration_time + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, [invalid_message bytes], [invalid_message length]), exit, + fail("Failed to update decoder with CMS message")); + _css_contentData = [NSData dataWithBytes:_css_content length:sizeof(_css_content)]; + require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)_css_contentData), exit, + fail("Failed to set detached _css_content")); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy")); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerInvalidSignature, "Valid signature"); + +exit: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +static void CMSDecoder_negative_missing_date(void) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + CFAbsoluteTime expirationTime = 0.0; + + /* Create decoder and decode */ + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, _no_expiration_attr, sizeof(_no_expiration_attr)), exit, + fail("Failed to update decoder with CMS message")); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy")); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Expiration Time Attribute value */ + is(CMSDecoderCopySignerAppleExpirationTime(decoder, 0, &expirationTime), -1, + "Got expiration time from message with no expiration attribute"); + +exit: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +static void CMSDecoder_tests(void) { + CMSDecoder_positive_tests(); + CMSDecoder_negative_date_changed(); + CMSDecoder_negative_missing_date(); +} + +static bool setup_keychain(const uint8_t *p12, size_t p12_len, SecIdentityRef *identity) { + CFArrayRef tmp_imported_items = NULL; + NSArray *imported_items = nil; + + NSDictionary *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" }; + NSData *p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)]; + require_noerr_action(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options, + &tmp_imported_items), exit, + fail("Failed to import identity")); + imported_items = CFBridgingRelease(tmp_imported_items); + require_noerr_action([imported_items count] == 0 && + [imported_items[0] isKindOfClass:[NSDictionary class]], exit, + fail("Wrong imported items output")); + *identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]); + require_action(*identity, exit, fail("Failed to get identity")); + + return true; + +exit: + return false; +} + +static void cleanup_keychain(SecIdentityRef identity) { +#if TARGET_OS_OSX + // SecPKCS12Import adds the items to the keychain on macOS + NSDictionary *query = @{ (__bridge NSString*)kSecValueRef : (__bridge id)identity }; + ok_status(SecItemDelete((__bridge CFDictionaryRef)query), "failed to remove identity from keychain"); +#else + pass("skip test on iOS"); +#endif + CFReleaseNull(identity); +} + +int si_35_cms_expiration_time(int argc, char *const *argv) { + plan_tests(5+1+3+5+5+3+4+1); + + SecIdentityRef identity = NULL; + + if (setup_keychain(signing_identity_p12 , sizeof(signing_identity_p12), &identity)) { + SecCMS_tests(); + CMSEncoder_tests(identity); + CMSDecoder_tests(); + } + + cleanup_keychain(identity); + + return 0; +} diff --git a/OSX/sec/Security/Regressions/secitem/si-50-secrandom.c b/OSX/sec/Security/Regressions/secitem/si-50-secrandom.c index c7bebf89..51d6d086 100644 --- a/OSX/sec/Security/Regressions/secitem/si-50-secrandom.c +++ b/OSX/sec/Security/Regressions/secitem/si-50-secrandom.c @@ -29,6 +29,9 @@ #include "Security_regressions.h" +static int dummy; +static SecRandomRef kSecRandomNotDefault = (SecRandomRef)&dummy; + /* Test basic add delete update copy matching stuff. */ static void tests(void) { @@ -36,11 +39,12 @@ static void tests(void) CFIndex size = 42; UInt8 *p = bytes + 23; ok_status(SecRandomCopyBytes(kSecRandomDefault, size, p), "generate some random bytes"); + ok_status(SecRandomCopyBytes(kSecRandomNotDefault, size, p), "ignore random implementation specifier"); } int si_50_secrandom(int argc, char *const *argv) { - plan_tests(1); + plan_tests(2); tests(); diff --git a/OSX/sec/Security/Regressions/secitem/si-61-pkcs12.c b/OSX/sec/Security/Regressions/secitem/si-61-pkcs12.c index 2c2c16e6..af1dbea2 100644 --- a/OSX/sec/Security/Regressions/secitem/si-61-pkcs12.c +++ b/OSX/sec/Security/Regressions/secitem/si-61-pkcs12.c @@ -166,7 +166,7 @@ static void tests(void) SecKeyRef pubkey = NULL; #if TARGET_OS_OSX - ok_status(SecCertificateCopyPublicKey(cert, &pubkey), "get public key from cert"); + ok(pubkey = SecCertificateCopyKey(cert), "get public key from cert"); #else ok(pubkey = SecKeyCopyPublicKey(pkey), "get public key from private key"); #endif diff --git a/OSX/sec/Security/Regressions/secitem/si-66-smime.c b/OSX/sec/Security/Regressions/secitem/si-66-smime.c index 799b1ccb..8fc837e5 100644 --- a/OSX/sec/Security/Regressions/secitem/si-66-smime.c +++ b/OSX/sec/Security/Regressions/secitem/si-66-smime.c @@ -2484,7 +2484,8 @@ static void tests(void) CFRelease(anchor_array); ok_status(SecTrustEvaluate(trust, &result), "evaluate trust"); - ok(result == kSecTrustResultRecoverableTrustFailure, "private root"); + // the root of this chain has a MD2 signature; a weak digest algorithm error is now considered fatal. + ok(result == kSecTrustResultFatalTrustFailure, "private root"); #if DUMP_CERTS // debug code to save a cert chain retrieved from a SecTrustRef (written to /tmp/c[0-9].cer) diff --git a/OSX/sec/Security/Regressions/secitem/si-70-sectrust-unified.c b/OSX/sec/Security/Regressions/secitem/si-70-sectrust-unified.c index d0469d9c..80038cc8 100644 --- a/OSX/sec/Security/Regressions/secitem/si-70-sectrust-unified.c +++ b/OSX/sec/Security/Regressions/secitem/si-70-sectrust-unified.c @@ -58,177 +58,145 @@ //OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData) -/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Operations/CN=xedge2.apple.com - issuer :/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority */ -const uint8_t xedge2_cert[1385]={ -0x30,0x82,0x05,0x65,0x30,0x82,0x04,0xCE,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x46, -0x9C,0xDF,0x96,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, -0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74, -0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04, -0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, -0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62, -0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C, -0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C, -0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74, -0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38, -0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, -0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72, -0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41, -0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x31, -0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x32, -0x38,0x31,0x39,0x30,0x33,0x31,0x32,0x5A,0x30,0x81,0x83,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04, -0x08,0x13,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30, -0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E, -0x6F,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x13,0x09,0x41,0x70,0x70,0x6C, -0x65,0x20,0x49,0x6E,0x63,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x13,0x13, -0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,0x4F,0x70,0x65,0x72,0x61,0x74,0x69, -0x6F,0x6E,0x73,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x78,0x65, -0x64,0x67,0x65,0x32,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x81, -0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00, -0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC7,0xF3,0xA1,0x0E,0x0E, -0xA4,0xDF,0xC5,0x3F,0x24,0x87,0xC3,0x6E,0xE7,0xD0,0x7C,0x2B,0x5A,0x1C,0xF3,0x67, -0x6C,0x6B,0x56,0x0A,0x95,0xC9,0xE5,0x13,0x28,0x6E,0x16,0x9D,0x4F,0xB1,0x76,0xFB, -0x7D,0x42,0x5B,0x2A,0x7C,0xCC,0x97,0x75,0xAA,0xA6,0xA9,0xDE,0xB2,0xEC,0xEF,0xE2, -0xAB,0x40,0xAE,0x9A,0x23,0xF0,0x6A,0x10,0xB3,0x75,0x27,0xF0,0xF4,0x7D,0x08,0x67, -0x8F,0xCE,0x41,0x24,0x74,0xAA,0x37,0xB6,0xC1,0x32,0x61,0xCF,0x7D,0x1C,0x21,0xCD, -0xCF,0x7C,0x9E,0xE2,0x48,0x03,0x7E,0x78,0xB3,0x86,0x3D,0x06,0x6B,0x39,0xEC,0xC8, -0x73,0x68,0xDB,0xE7,0x5B,0x97,0xF4,0xF9,0xA3,0xE7,0xFB,0x81,0x2E,0x4D,0x0B,0x3F, -0xA9,0xCA,0xDE,0x32,0x26,0xF3,0xF0,0x97,0x72,0x65,0xAB,0x02,0x03,0x01,0x00,0x01, -0xA3,0x82,0x02,0xA2,0x30,0x82,0x02,0x9E,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04, -0x04,0x03,0x02,0x05,0xA0,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,0x22, -0x80,0x0F,0x32,0x30,0x30,0x38,0x30,0x31,0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33, -0x5A,0x81,0x0F,0x32,0x30,0x31,0x30,0x30,0x31,0x32,0x38,0x31,0x39,0x30,0x33,0x31, -0x32,0x5A,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04, -0x04,0x03,0x02,0x06,0x40,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A, -0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x82,0x01,0x68,0x06,0x03, -0x55,0x1D,0x20,0x04,0x82,0x01,0x5F,0x30,0x82,0x01,0x5B,0x30,0x82,0x01,0x57,0x06, -0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x4B,0x02,0x30,0x82,0x01,0x48,0x30,0x26, -0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70, -0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, -0x65,0x74,0x2F,0x63,0x70,0x73,0x30,0x82,0x01,0x1C,0x06,0x08,0x2B,0x06,0x01,0x05, -0x05,0x07,0x02,0x02,0x30,0x82,0x01,0x0E,0x1A,0x82,0x01,0x0A,0x54,0x68,0x65,0x20, -0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x53,0x53,0x4C,0x20,0x57,0x65,0x62,0x20, -0x53,0x65,0x72,0x76,0x65,0x72,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,0x20,0x28,0x43,0x50,0x53,0x29,0x20,0x61,0x76, -0x61,0x69,0x6C,0x61,0x62,0x6C,0x65,0x20,0x61,0x74,0x20,0x77,0x77,0x77,0x2E,0x65, -0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x63,0x70,0x73,0x20,0x20, -0x69,0x73,0x20,0x68,0x65,0x72,0x65,0x62,0x79,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70, -0x6F,0x72,0x61,0x74,0x65,0x64,0x20,0x69,0x6E,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72, -0x20,0x75,0x73,0x65,0x20,0x6F,0x72,0x20,0x72,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65, -0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69, -0x63,0x61,0x74,0x65,0x2E,0x20,0x20,0x54,0x68,0x69,0x73,0x20,0x43,0x50,0x53,0x20, -0x63,0x6F,0x6E,0x74,0x61,0x69,0x6E,0x73,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74, -0x69,0x6F,0x6E,0x73,0x20,0x6F,0x6E,0x20,0x77,0x61,0x72,0x72,0x61,0x6E,0x74,0x69, -0x65,0x73,0x20,0x61,0x6E,0x64,0x20,0x6C,0x69,0x61,0x62,0x69,0x6C,0x69,0x74,0x69, -0x65,0x73,0x2E,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63, -0x29,0x20,0x32,0x30,0x30,0x32,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x4C, -0x69,0x6D,0x69,0x74,0x65,0x64,0x30,0x33,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2C,0x30, -0x2A,0x30,0x28,0xA0,0x26,0xA0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, -0x63,0x72,0x6C,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F, -0x73,0x65,0x72,0x76,0x65,0x72,0x31,0x2E,0x63,0x72,0x6C,0x30,0x33,0x06,0x08,0x2B, -0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x27,0x30,0x25,0x30,0x23,0x06,0x08,0x2B, -0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x17,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F, -0x6F,0x63,0x73,0x70,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74, -0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62, -0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0, -0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2D,0xEF,0xD9,0xAF, -0x1A,0x89,0x40,0x53,0x75,0x48,0x26,0x59,0x2F,0xEC,0x11,0x18,0xC0,0xD1,0x7A,0x34, -0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x19,0x06,0x09,0x2A, -0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B,0x04,0x56,0x37, -0x2E,0x31,0x03,0x02,0x03,0x28,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x77,0x33,0x2A,0x69,0x45,0x5A,0xB2, -0xF5,0x74,0xF7,0xDF,0xC7,0x08,0x85,0x86,0x88,0x98,0x41,0x7F,0x57,0x49,0x01,0xBA, -0x13,0x21,0x40,0xD0,0x0A,0x5C,0xA7,0x37,0xDF,0xB3,0x7E,0xF8,0xED,0x04,0x63,0xC3, -0xE8,0x0F,0xA0,0xE5,0xC4,0x4F,0x3A,0x90,0xE4,0x87,0x5F,0xEC,0xDB,0x65,0x8B,0x6E, -0x88,0x6E,0x6E,0xE4,0xBC,0x6A,0x7E,0x37,0x47,0x04,0xFF,0x09,0xC6,0x70,0xE1,0x65, -0x8F,0xE3,0xE9,0x60,0xEB,0xE8,0x8E,0x29,0xAE,0xF9,0x81,0xCA,0x9A,0x97,0x3C,0x6F, -0x7C,0xFA,0xA8,0x49,0xB4,0x33,0x76,0x9C,0x65,0x92,0x12,0xF6,0x7F,0x6A,0x62,0x84, -0x29,0x5F,0x14,0x26,0x6E,0x07,0x6F,0x5C,0xB5,0x7C,0x21,0x64,0x7C,0xD9,0x93,0xF4, -0x9C,0xC8,0xE7,0xEC,0xC6,0xAC,0x13,0xC4,0xF0 +/* subject:/C=US/ST=California/L=Mountain View/O=Google LLC/CN=www.google.com */ +/* issuer :/C=US/O=Google Trust Services/CN=Google Internet Authority G3 */ +const uint8_t google_cert[]={ + 0x30,0x82,0x03,0xC7,0x30,0x82,0x02,0xAF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x55, + 0x81,0x47,0xC4,0x26,0x8C,0x3F,0xC2,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, + 0x06,0x13,0x02,0x55,0x53,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15, + 0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x53,0x65,0x72, + 0x76,0x69,0x63,0x65,0x73,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x03,0x13,0x1C, + 0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20, + 0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D, + 0x31,0x38,0x30,0x35,0x30,0x38,0x31,0x34,0x34,0x37,0x34,0x33,0x5A,0x17,0x0D,0x31, + 0x38,0x30,0x37,0x33,0x31,0x31,0x33,0x32,0x37,0x30,0x30,0x5A,0x30,0x68,0x31,0x0B, + 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06, + 0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61, + 0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74, + 0x61,0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04, + 0x0A,0x0C,0x0A,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x4C,0x4C,0x43,0x31,0x17,0x30, + 0x15,0x06,0x03,0x55,0x04,0x03,0x0C,0x0E,0x77,0x77,0x77,0x2E,0x67,0x6F,0x6F,0x67, + 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,0xDD,0x10,0xCB,0x4F,0xB1,0x49,0xF9,0xE8,0xC2,0x8E,0xB5,0xB9,0xC3,0x7D,0xCC, + 0x9D,0x94,0x3A,0x91,0x19,0x7C,0xA9,0xB3,0x78,0x81,0x21,0x01,0xC0,0x76,0x12,0xA9, + 0x84,0x65,0xDF,0xD3,0xE2,0x51,0xFF,0x17,0x9F,0x69,0x0F,0x0B,0xFA,0x04,0x0D,0xBA, + 0x35,0xBB,0xE8,0x1F,0x14,0x66,0xB7,0xC7,0xD7,0xFC,0xEB,0x10,0xD6,0xCD,0x79,0x8A, + 0x22,0xA3,0x82,0x01,0x52,0x30,0x82,0x01,0x4E,0x30,0x13,0x06,0x03,0x55,0x1D,0x25, + 0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x0E, + 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x19, + 0x06,0x03,0x55,0x1D,0x11,0x04,0x12,0x30,0x10,0x82,0x0E,0x77,0x77,0x77,0x2E,0x67, + 0x6F,0x6F,0x67,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x68,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x01,0x01,0x04,0x5C,0x30,0x5A,0x30,0x2D,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x30,0x02,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x70,0x6B, + 0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x67,0x73,0x72,0x32,0x2F,0x47,0x54,0x53,0x47, + 0x49,0x41,0x47,0x33,0x2E,0x63,0x72,0x74,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05, + 0x05,0x07,0x30,0x01,0x86,0x1D,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73, + 0x70,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x47,0x54,0x53,0x47,0x49, + 0x41,0x47,0x33,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2B,0x53, + 0xE0,0x79,0xD4,0xFD,0xA4,0xD4,0xDF,0x18,0x6B,0xDD,0x80,0x4D,0x11,0x35,0xC7,0xB2, + 0x41,0xCC,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,0x77,0xC2,0xB8, + 0x50,0x9A,0x67,0x76,0x76,0xB1,0x2D,0xC2,0x86,0xD0,0x83,0xA0,0x7E,0xA6,0x7E,0xBA, + 0x4B,0x30,0x21,0x06,0x03,0x55,0x1D,0x20,0x04,0x1A,0x30,0x18,0x30,0x0C,0x06,0x0A, + 0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x05,0x03,0x30,0x08,0x06,0x06,0x67,0x81, + 0x0C,0x01,0x02,0x02,0x30,0x31,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2A,0x30,0x28,0x30, + 0x26,0xA0,0x24,0xA0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72, + 0x6C,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x47,0x54,0x53,0x47,0x49, + 0x41,0x47,0x33,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6E,0x85,0x02,0xC0,0xF0, + 0x15,0xBF,0xAF,0x4F,0x29,0x73,0x19,0x87,0x7F,0x30,0xB3,0x24,0xD1,0xEE,0xA7,0xDC, + 0x90,0x44,0x30,0xC1,0xA0,0x84,0x65,0x52,0x26,0xE6,0xAD,0x0D,0xCA,0x43,0xEE,0xB6, + 0x6B,0x37,0x9D,0xFF,0x97,0x80,0x09,0x85,0x58,0x46,0xEC,0xFF,0xF2,0x42,0x6A,0xBB, + 0xE6,0xA3,0xB4,0x9B,0x26,0x26,0xA8,0x53,0xA9,0xB9,0x95,0xB6,0x42,0x06,0x94,0xED, + 0x31,0xC5,0x33,0xF7,0x91,0x6A,0x90,0x4B,0xD2,0x8A,0x45,0xAE,0x3A,0xA0,0x10,0x27, + 0xAE,0xF4,0x9A,0xC9,0x5E,0x63,0x20,0xAD,0xF2,0xCB,0xDC,0x74,0xA8,0x83,0x32,0x56, + 0x6D,0xAA,0x6C,0xCA,0xBC,0xCC,0x71,0x23,0xD4,0xAC,0xA9,0xAE,0xEA,0x04,0xD6,0x75, + 0xE7,0xBF,0x18,0xC7,0x9C,0xCC,0x7B,0xE6,0x81,0x62,0xC6,0xFA,0x17,0xA8,0x82,0x2F, + 0xCC,0xE9,0xAC,0xEF,0x81,0xCC,0xAE,0x1A,0x1C,0x79,0x35,0x7B,0x54,0xFE,0x06,0x57, + 0x2F,0x58,0xD0,0x7C,0x4E,0x5A,0x75,0xAE,0xCC,0x31,0xD6,0x20,0xA6,0xB1,0xDA,0x39, + 0x9E,0x46,0x5B,0x15,0x76,0xF2,0x3E,0x2C,0xB1,0x5E,0xBF,0x7F,0x29,0xE3,0xBE,0xC6, + 0xF3,0xE5,0xEB,0xD5,0x91,0x48,0x84,0x41,0x7B,0xB6,0x3B,0x83,0xC6,0xCE,0x1B,0xE2, + 0x88,0x44,0x91,0x89,0x72,0x27,0xF9,0xD2,0x72,0x33,0xCF,0xC3,0xB2,0x52,0x38,0x65, + 0x17,0x14,0x00,0x4E,0x36,0x1C,0xC2,0xAD,0xBF,0x7F,0x3A,0x18,0xF7,0x52,0xFA,0x3B, + 0x86,0x18,0xF3,0x24,0x97,0xF7,0x35,0x58,0x48,0x0D,0x7D,0x93,0x18,0xA7,0x14,0x52, + 0x1A,0x19,0x9D,0xDB,0xD5,0xCC,0xA3,0xC5,0x48,0x6D,0x8A, }; -const uint8_t _entrust1024RootCA[1244]={ - 0x30,0x82,0x04,0xD8,0x30,0x82,0x04,0x41,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x37, - 0x4A,0xD2,0x43,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, - 0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, - 0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74, - 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04, - 0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, - 0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62, - 0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C, - 0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C, - 0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74, - 0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38, - 0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E, - 0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72, - 0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41, - 0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x35, - 0x32,0x35,0x31,0x36,0x30,0x39,0x34,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x35,0x32, - 0x35,0x31,0x36,0x33,0x39,0x34,0x30,0x5A,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06, - 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04, - 0x0A,0x13,0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B, - 0x30,0x39,0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74, - 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63, - 0x6F,0x72,0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69, - 0x6D,0x69,0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06, - 0x03,0x55,0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45, - 0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74, - 0x65,0x64,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74, - 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20, - 0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, - 0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x81, - 0x9D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00, - 0x03,0x81,0x8B,0x00,0x30,0x81,0x87,0x02,0x81,0x81,0x00,0xCD,0x28,0x83,0x34,0x54, - 0x1B,0x89,0xF3,0x0F,0xAF,0x37,0x91,0x31,0xFF,0xAF,0x31,0x60,0xC9,0xA8,0xE8,0xB2, - 0x10,0x68,0xED,0x9F,0xE7,0x93,0x36,0xF1,0x0A,0x64,0xBB,0x47,0xF5,0x04,0x17,0x3F, - 0x23,0x47,0x4D,0xC5,0x27,0x19,0x81,0x26,0x0C,0x54,0x72,0x0D,0x88,0x2D,0xD9,0x1F, - 0x9A,0x12,0x9F,0xBC,0xB3,0x71,0xD3,0x80,0x19,0x3F,0x47,0x66,0x7B,0x8C,0x35,0x28, - 0xD2,0xB9,0x0A,0xDF,0x24,0xDA,0x9C,0xD6,0x50,0x79,0x81,0x7A,0x5A,0xD3,0x37,0xF7, - 0xC2,0x4A,0xD8,0x29,0x92,0x26,0x64,0xD1,0xE4,0x98,0x6C,0x3A,0x00,0x8A,0xF5,0x34, - 0x9B,0x65,0xF8,0xED,0xE3,0x10,0xFF,0xFD,0xB8,0x49,0x58,0xDC,0xA0,0xDE,0x82,0x39, - 0x6B,0x81,0xB1,0x16,0x19,0x61,0xB9,0x54,0xB6,0xE6,0x43,0x02,0x01,0x03,0xA3,0x82, - 0x01,0xD7,0x30,0x82,0x01,0xD3,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8, - 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07,0x30,0x82,0x01,0x19,0x06,0x03,0x55, - 0x1D,0x1F,0x04,0x82,0x01,0x10,0x30,0x82,0x01,0x0C,0x30,0x81,0xDE,0xA0,0x81,0xDB, - 0xA0,0x81,0xD8,0xA4,0x81,0xD5,0x30,0x81,0xD2,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, - 0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13, - 0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39, - 0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75, - 0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72, - 0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69, - 0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55, - 0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74, - 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64, - 0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75, - 0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65, - 0x72,0x76,0x65,0x72,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,0x0D,0x30,0x0B, - 0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4C,0x31,0x30,0x29,0xA0,0x27,0xA0, - 0x25,0x86,0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E, - 0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x52,0x4C,0x2F,0x6E,0x65, - 0x74,0x31,0x2E,0x63,0x72,0x6C,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30, - 0x22,0x80,0x0F,0x31,0x39,0x39,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39,0x34, - 0x30,0x5A,0x81,0x0F,0x32,0x30,0x31,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39, - 0x34,0x30,0x5A,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x06, - 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62, - 0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0, - 0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xF0,0x17,0x62,0x13, - 0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,0x1A, - 0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x19, - 0x06,0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B, - 0x04,0x56,0x34,0x2E,0x30,0x03,0x02,0x04,0x90,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, - 0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x90,0xDC,0x30,0x02, - 0xFA,0x64,0x74,0xC2,0xA7,0x0A,0xA5,0x7C,0x21,0x8D,0x34,0x17,0xA8,0xFB,0x47,0x0E, - 0xFF,0x25,0x7C,0x8D,0x13,0x0A,0xFB,0xE4,0x98,0xB5,0xEF,0x8C,0xF8,0xC5,0x10,0x0D, - 0xF7,0x92,0xBE,0xF1,0xC3,0xD5,0xD5,0x95,0x6A,0x04,0xBB,0x2C,0xCE,0x26,0x36,0x65, - 0xC8,0x31,0xC6,0xE7,0xEE,0x3F,0xE3,0x57,0x75,0x84,0x7A,0x11,0xEF,0x46,0x4F,0x18, - 0xF4,0xD3,0x98,0xBB,0xA8,0x87,0x32,0xBA,0x72,0xF6,0x3C,0xE2,0x3D,0x9F,0xD7,0x1D, - 0xD9,0xC3,0x60,0x43,0x8C,0x58,0x0E,0x22,0x96,0x2F,0x62,0xA3,0x2C,0x1F,0xBA,0xAD, - 0x05,0xEF,0xAB,0x32,0x78,0x87,0xA0,0x54,0x73,0x19,0xB5,0x5C,0x05,0xF9,0x52,0x3E, - 0x6D,0x2D,0x45,0x0B,0xF7,0x0A,0x93,0xEA,0xED,0x06,0xF9,0xB2, +/* subject:/C=US/O=Google Trust Services/CN=Google Internet Authority G3 */ +/* issuer :/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign */ +const uint8_t _GIAG3[]={ + 0x30,0x82,0x04,0x5C,0x30,0x82,0x03,0x44,0xA0,0x03,0x02,0x01,0x02,0x02,0x0D,0x01, + 0xE3,0xA9,0x30,0x1C,0xFC,0x72,0x06,0x38,0x3F,0x9A,0x53,0x1D,0x30,0x0D,0x06,0x09, + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x4C,0x31,0x20,0x30, + 0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69, + 0x67,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x32,0x31, + 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C, + 0x53,0x69,0x67,0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47, + 0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30, + 0x36,0x31,0x35,0x30,0x30,0x30,0x30,0x34,0x32,0x5A,0x17,0x0D,0x32,0x31,0x31,0x32, + 0x31,0x35,0x30,0x30,0x30,0x30,0x34,0x32,0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06, + 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04, + 0x0A,0x13,0x15,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x54,0x72,0x75,0x73,0x74,0x20, + 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04, + 0x03,0x13,0x1C,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x49,0x6E,0x74,0x65,0x72,0x6E, + 0x65,0x74,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x47,0x33,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, + 0xCA,0x52,0x4B,0xEA,0x1E,0xFF,0xCE,0x24,0x6B,0xA8,0xDA,0x72,0x18,0x68,0xD5,0x56, + 0x5D,0x0E,0x48,0x5A,0x2D,0x35,0x09,0x76,0x5A,0xCF,0xA4,0xC8,0x1C,0xB1,0xA9,0xFE, + 0x53,0x89,0xFB,0xAD,0x34,0xFF,0x88,0x5B,0x9F,0xBB,0xE7,0xE8,0x00,0x01,0xDC,0x35, + 0x73,0x75,0x03,0xAD,0xB3,0xB1,0xB9,0xA4,0x7D,0x2B,0x26,0x79,0xCE,0x15,0x40,0x0A, + 0xEF,0x51,0xB8,0x9F,0x32,0x8C,0x7C,0x70,0x86,0x52,0x4B,0x16,0xFE,0x6A,0x27,0x6B, + 0xE6,0x36,0x7A,0x62,0x50,0xD8,0xDF,0x9A,0x89,0xCC,0x09,0x29,0xEB,0x4F,0x29,0x14, + 0x88,0x80,0x0B,0x8F,0x38,0x1E,0x80,0x6A,0x18,0x7C,0x1D,0xBD,0x97,0x3B,0x78,0x7D, + 0x45,0x49,0x36,0x4F,0x41,0xCD,0xA2,0xE0,0x76,0x57,0x3C,0x68,0x31,0x79,0x64,0xC9, + 0x6E,0xD7,0x51,0x1E,0x66,0xC3,0xA2,0x64,0x2C,0x79,0xC0,0xE7,0x65,0xC3,0x56,0x84, + 0x53,0x5A,0x43,0x6D,0xCB,0x9A,0x02,0x20,0xD2,0xEF,0x1A,0x69,0xD1,0xB0,0x9D,0x73, + 0xA2,0xE0,0x2A,0x60,0x65,0x50,0x31,0xCF,0xFB,0xB3,0x2F,0xBF,0x11,0x88,0x40,0x2E, + 0xB5,0x49,0x10,0x0F,0x0A,0x6E,0xDC,0x97,0xFA,0xBF,0x2C,0x9F,0x05,0x39,0x0B,0x58, + 0x54,0xAF,0x06,0x96,0xE8,0xC5,0x8E,0x01,0x16,0xBC,0xA8,0x1A,0x4D,0x41,0xC5,0x93, + 0x91,0xA2,0x1E,0xA1,0x8B,0xF2,0xFE,0xC1,0x88,0x24,0x49,0xA3,0x47,0x4B,0xC5,0x13, + 0x01,0xDD,0xA7,0x57,0x12,0x69,0x62,0x2B,0xEB,0xFE,0x20,0xEF,0x69,0xFB,0x3A,0xA5, + 0xF0,0x7E,0x29,0xEE,0xED,0x96,0x16,0xF7,0xB1,0x1F,0xA0,0xE4,0x90,0x25,0xE0,0x33, + 0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x33,0x30,0x82,0x01,0x2F,0x30,0x0E,0x06, + 0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x1D,0x06, + 0x03,0x55,0x1D,0x25,0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, + 0x03,0x01,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x12,0x06,0x03, + 0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00, + 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x77,0xC2,0xB8,0x50,0x9A, + 0x67,0x76,0x76,0xB1,0x2D,0xC2,0x86,0xD0,0x83,0xA0,0x7E,0xA6,0x7E,0xBA,0x4B,0x30, + 0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x9B,0xE2,0x07,0x57, + 0x67,0x1C,0x1E,0xC0,0x6A,0x06,0xDE,0x59,0xB4,0x9A,0x2D,0xDF,0xDC,0x19,0x86,0x2E, + 0x30,0x35,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x29,0x30,0x27, + 0x30,0x25,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x19,0x68,0x74, + 0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F, + 0x6F,0x67,0x2F,0x67,0x73,0x72,0x32,0x30,0x32,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2B, + 0x30,0x29,0x30,0x27,0xA0,0x25,0xA0,0x23,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F, + 0x2F,0x63,0x72,0x6C,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x67,0x73, + 0x72,0x32,0x2F,0x67,0x73,0x72,0x32,0x2E,0x63,0x72,0x6C,0x30,0x3F,0x06,0x03,0x55, + 0x1D,0x20,0x04,0x38,0x30,0x36,0x30,0x34,0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x02, + 0x30,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C, + 0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67, + 0x2F,0x72,0x65,0x70,0x6F,0x73,0x69,0x74,0x6F,0x72,0x79,0x2F,0x30,0x0D,0x06,0x09, + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00, + 0x1C,0xB7,0x89,0x96,0xE4,0x53,0xED,0xBB,0xEC,0xDB,0xA8,0x32,0x01,0x9F,0x2C,0xA3, + 0xCD,0x6D,0xAD,0x42,0x12,0x77,0xB3,0xB8,0xE6,0xC9,0x03,0x52,0x60,0x20,0x7B,0x57, + 0x27,0xC6,0x11,0xB5,0x3F,0x67,0x0D,0x99,0x2C,0x5B,0x5A,0xCA,0x22,0x0A,0xDD,0x9E, + 0xBB,0x1F,0x4B,0x48,0x3F,0x8F,0x02,0x3D,0x8B,0x21,0x84,0x45,0x1D,0x6D,0xF5,0xFF, + 0xAC,0x68,0x89,0xCD,0x64,0xE2,0xD6,0xD6,0x5E,0x40,0xC2,0x8E,0x2A,0xF7,0xEF,0x14, + 0xD3,0x36,0xA4,0x40,0x30,0xF5,0x32,0x15,0x15,0x92,0x76,0xFB,0x7E,0x9E,0x53,0xEA, + 0xC2,0x76,0xFC,0x39,0xAD,0x88,0xFE,0x66,0x92,0x26,0xE9,0x1C,0xC4,0x38,0xCD,0x49, + 0xFA,0x43,0x87,0xF0,0x5D,0xD6,0x56,0x4D,0x81,0xD7,0x7F,0xF1,0xC2,0xDD,0xB0,0x4D, + 0xFE,0xC3,0x2A,0x6E,0x7C,0x9F,0x6E,0x5C,0xED,0x62,0x42,0x99,0xE1,0xF7,0x36,0xEE, + 0x14,0x8C,0x2C,0x20,0xE3,0x46,0x97,0x5A,0x77,0x03,0xC0,0xA0,0xC6,0x4A,0x88,0xFD, + 0x40,0x22,0x87,0x72,0x5A,0x18,0xEA,0x9C,0xA5,0xC7,0x5A,0x08,0x8C,0xE4,0x05,0xA4, + 0x7D,0xB9,0x84,0x35,0x5F,0x89,0x36,0x56,0x0E,0x40,0x3D,0x12,0xE8,0xBB,0x35,0x72, + 0xED,0xAF,0x08,0x56,0x4E,0xB0,0xBB,0x2E,0xA9,0x9B,0xE4,0xFB,0x1D,0x3E,0x0B,0x63, + 0xC8,0x9B,0x4B,0x91,0x44,0x66,0x57,0xC0,0x14,0xB4,0x96,0xF0,0xDC,0x2C,0x57,0x3F, + 0x52,0x04,0xAD,0x95,0xAA,0x7D,0x4D,0xD0,0xF2,0x0C,0x9F,0x9C,0x40,0xE8,0xD6,0x55, + 0x73,0xBA,0x3C,0xDF,0x90,0xCB,0x00,0x5B,0x21,0x11,0x67,0xC2,0xED,0x32,0x1E,0xDE, }; @@ -240,32 +208,32 @@ static void tests(void) CFArrayRef certs = NULL; CFDateRef date = NULL; - const void *cert_xedge2; - isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_cert, - sizeof(xedge2_cert)), NULL, "create cert_xedge2"); - certs = CFArrayCreate(NULL, &cert_xedge2, 1, NULL); + const void *cert_google; + isnt(cert_google = SecCertificateCreateWithBytes(NULL, google_cert, + sizeof(google_cert)), NULL, "create cert_google"); + certs = CFArrayCreate(NULL, &cert_google, 1, NULL); bool server = true; - policy = SecPolicyCreateSSL(server, CFSTR("xedge.apple.com")); // deliberate hostname mismatch + policy = SecPolicyCreateSSL(server, CFSTR("www2.google.com")); // deliberate hostname mismatch ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), - "create trust for ssl server xedge.apple.com"); + "create trust for ssl server www2.google.com"); CFReleaseSafe(certs); - date = CFDateCreate(NULL, 252288000.0); /* Jan 1st 2009 */ - ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to Jan 1st 2009"); + date = CFDateCreate(NULL, 548800000.0); /* May 23, 2018" */ + ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to May 23, 2018"); /* This test uses a root which is no longer in our trust store, * so we need explicitly set it as a trusted anchor */ - SecCertificateRef _root; - isnt(_root = SecCertificateCreateWithBytes(NULL, _entrust1024RootCA, sizeof(_entrust1024RootCA)), + SecCertificateRef _anchor; + isnt(_anchor = SecCertificateCreateWithBytes(NULL, _GIAG3, sizeof(_GIAG3)), NULL, "create root"); - const void *v_roots[] = { _root }; + const void *v_roots[] = { _anchor }; CFArrayRef _anchors; isnt(_anchors = CFArrayCreate(NULL, v_roots, array_size(v_roots), NULL), NULL, "create anchors"); SecTrustSetAnchorCertificates(trust, _anchors); - ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge trust"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate google trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure (hostname mismatch)"); @@ -315,7 +283,7 @@ static void tests(void) CFReleaseNull(policy); { const void *keys[] = { kSecPolicyName, kSecPolicyClient }; - const void *values[] = { CFSTR("xedge2.apple.com"), kCFBooleanFalse }; + const void *values[] = { CFSTR("www.google.com"), kCFBooleanFalse }; CFDictionaryRef properties = CFDictionaryCreate(NULL, keys, values, array_size(keys), &kCFTypeDictionaryKeyCallBacks, @@ -332,7 +300,7 @@ static void tests(void) isnt(properties = SecPolicyCopyProperties(policy), NULL, "copy policy properties"); CFTypeRef value = NULL; is(CFDictionaryGetValueIfPresent(properties, kSecPolicyName, (const void **)&value) && - kCFCompareEqualTo == CFStringCompare((CFStringRef)value, CFSTR("xedge2.apple.com"), 0), + kCFCompareEqualTo == CFStringCompare((CFStringRef)value, CFSTR("www.google.com"), 0), true, "has policy name"); is(CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value) && CFEqual(value, kSecPolicyAppleSSL) , true, "has SSL policy"); @@ -341,7 +309,7 @@ static void tests(void) /* Test setting new policy on a trust via SecTrustSetPolicies */ ok_status(SecTrustSetPolicies(trust, policy)); /* Evaluation should now succeed, since our new policy has the correct hostname */ - ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate google trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); @@ -360,9 +328,9 @@ errOut: CFReleaseSafe(trust); CFReleaseSafe(policy); CFReleaseSafe(date); - CFReleaseSafe(cert_xedge2); + CFReleaseSafe(cert_google); - CFReleaseSafe(_root); + CFReleaseSafe(_anchor); CFReleaseSafe(_anchors); } diff --git a/OSX/sec/Security/Regressions/secitem/si-82-token-ag.c b/OSX/sec/Security/Regressions/secitem/si-82-token-ag.c index 39cade8f..1863bf1f 100644 --- a/OSX/sec/Security/Regressions/secitem/si-82-token-ag.c +++ b/OSX/sec/Security/Regressions/secitem/si-82-token-ag.c @@ -19,7 +19,7 @@ static void tests(void) { CFDictionaryAddValue(dict, kSecAttrService, CFSTR("test")); CFDictionaryAddValue(dict, kSecAttrAccessGroup, kSecAttrAccessGroupToken); - is_status(SecItemAdd(dict, NULL), errSecParam); + is_status(SecItemAdd(dict, NULL), errSecMissingEntitlement); is_status(SecItemCopyMatching(dict, NULL), errSecItemNotFound); CFRelease(dict); diff --git a/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.h b/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.h index 1570cf96..24a3efc7 100644 --- a/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.h +++ b/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.h @@ -360,3 +360,79 @@ unsigned char _test_leaf2[1043]={ 0x65,0xE6,0x30,0xFD,0xED,0x1F,0x0A,0x9E,0x27,0x8D,0x56,0x59,0x7A,0xFB,0xBF,0x52, 0x99,0x50,0xCE, }; + +/* subject:/C=US/O=Apple Inc./OU=Security Engineering/CN=JAPPLESEED/emailAddress=jony.appleseed@apple.com */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Sub-CA */ +/* X509v3 Subject Alternative Name: + email:jony.appleseed@apple.com + */ +uint8_t _test_leaf3[] = { + 0x30,0x82,0x04,0x3A,0x30,0x82,0x03,0x22,0xA0,0x03,0x02,0x01,0x02,0x02,0x13,0x63, + 0x82,0xBA,0x4B,0x18,0xB2,0x48,0xF9,0x10,0x06,0xFA,0x70,0x00,0x5D,0x3B,0xF9,0x9E, + 0xE3,0x13,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x91,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, + 0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69, + 0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C, + 0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x13,0x30,0x11,0x06,0x03, + 0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31, + 0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x0C,0x14,0x53,0x65,0x63,0x75,0x72,0x69, + 0x74,0x79,0x20,0x45,0x6E,0x67,0x69,0x6E,0x65,0x65,0x72,0x69,0x6E,0x67,0x31,0x25, + 0x30,0x23,0x06,0x03,0x55,0x04,0x03,0x0C,0x1C,0x4E,0x61,0x6D,0x65,0x20,0x43,0x6F, + 0x6E,0x73,0x74,0x72,0x61,0x69,0x6E,0x74,0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x53, + 0x75,0x62,0x2D,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x35,0x32,0x33,0x31, + 0x37,0x32,0x32,0x32,0x34,0x5A,0x17,0x0D,0x31,0x39,0x30,0x35,0x32,0x33,0x31,0x37, + 0x32,0x32,0x32,0x34,0x5A,0x30,0x7F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, + 0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41, + 0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55, + 0x04,0x0B,0x0C,0x14,0x53,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x45,0x6E,0x67, + 0x69,0x6E,0x65,0x65,0x72,0x69,0x6E,0x67,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x0A,0x4A,0x41,0x50,0x50,0x4C,0x45,0x53,0x45,0x45,0x44,0x31,0x27,0x30, + 0x25,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x18,0x6A,0x6F, + 0x6E,0x79,0x2E,0x61,0x70,0x70,0x6C,0x65,0x73,0x65,0x65,0x64,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,0x9C,0xD4,0x41,0x24,0x71,0x19,0x8B,0xBB,0x06, + 0x26,0xD1,0xE0,0x2D,0x81,0xF2,0x82,0x7D,0x87,0x01,0x59,0x65,0x3E,0xC0,0xC5,0xDD, + 0xA5,0x18,0xD8,0x42,0x9F,0x0E,0xFD,0xF6,0x12,0x34,0x16,0x27,0xA0,0x60,0x1F,0x1E, + 0x7C,0xA7,0xA6,0x64,0xDF,0x74,0xC3,0x23,0x28,0x14,0x7C,0x3C,0xF7,0xE0,0x1A,0x3C, + 0xB2,0x6B,0x41,0x48,0x11,0x5D,0xEA,0xCF,0x9C,0xAE,0xBB,0x03,0x56,0x2E,0x43,0xF2, + 0xAF,0x34,0x74,0x19,0xE3,0x4F,0x9C,0x0F,0x0A,0xA0,0xF7,0x7B,0xC9,0xD7,0x47,0xEE, + 0xD5,0xED,0x0C,0xAC,0x62,0x65,0xC9,0x27,0xE7,0x9A,0xA2,0xD7,0x8A,0x8D,0xAE,0x67, + 0x94,0x58,0x1D,0xC4,0x2E,0x3F,0x3F,0x1A,0x65,0xD8,0x74,0x2D,0x5D,0xFD,0x24,0xAA, + 0xA7,0x94,0xDB,0x8C,0xB0,0x2E,0x3F,0x98,0xD9,0x51,0x01,0xFE,0x0E,0xED,0x28,0xC4, + 0x26,0x5B,0x11,0x2E,0xDA,0x14,0xA7,0xC9,0x72,0x41,0x4D,0x21,0xA3,0x9A,0xBF,0xA8, + 0xE0,0xEA,0x1E,0x24,0x02,0x14,0x50,0x12,0x7D,0x22,0x5F,0x5E,0xC0,0x6B,0x45,0x68, + 0xD2,0x7C,0x81,0xE3,0xF0,0x26,0xEE,0x04,0xC5,0x61,0xCF,0x60,0x56,0x32,0x87,0xB3, + 0x46,0xE1,0xC1,0xFD,0x42,0x17,0x22,0xBE,0x38,0xA3,0xF3,0xA9,0x99,0x95,0x08,0x14, + 0xA8,0xA0,0xB3,0x81,0xD6,0x7F,0xEC,0xD6,0xAB,0xA6,0xCC,0x33,0xB1,0x55,0x6F,0xC9, + 0xF1,0x80,0x0F,0xFB,0xD7,0xB3,0x7A,0xF2,0xD9,0x51,0xC1,0x48,0xAC,0x58,0xB9,0x8A, + 0x3A,0xDB,0x6D,0x3F,0x64,0x06,0x5A,0xE9,0x32,0xF9,0x1B,0x40,0xD0,0xF2,0x65,0xA3, + 0xC7,0x21,0xE0,0xA4,0xB2,0x89,0xAD,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x9B,0x30, + 0x81,0x98,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00, + 0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x03,0x04,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04, + 0x04,0x03,0x02,0x05,0xA0,0x30,0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30,0x1A, + 0x81,0x18,0x6A,0x6F,0x6E,0x79,0x2E,0x61,0x70,0x70,0x6C,0x65,0x73,0x65,0x65,0x64, + 0x40,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1D,0x06,0x03,0x55,0x1D, + 0x0E,0x04,0x16,0x04,0x14,0xD7,0xA6,0x4F,0x23,0xDF,0x52,0x4E,0xAB,0x30,0xD6,0x02, + 0x54,0x10,0xD9,0x4A,0x95,0x9C,0xF7,0x8E,0x2F,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0x43,0xD7,0xC9,0x6E,0x6E,0x28,0x69,0x32,0xB9,0xB7, + 0x4F,0x36,0x5A,0xD3,0x51,0x80,0x23,0x41,0x9A,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x84,0xFD, + 0x54,0x30,0x53,0xC8,0x24,0xCB,0x13,0x6F,0xDA,0xE5,0x51,0xDC,0xAC,0x28,0x0D,0xEB, + 0xD4,0x69,0x1D,0x4B,0x23,0x78,0x52,0xF3,0x1D,0xE8,0xBD,0xB4,0xF4,0xB8,0x2F,0x6D, + 0x53,0x03,0x21,0xC0,0x68,0x44,0x6F,0x85,0xF1,0x7D,0xC6,0xBD,0xC6,0x86,0xEC,0xF5, + 0xAA,0x7A,0xCF,0x0F,0xCB,0x11,0xB4,0xC7,0x81,0xAF,0xE1,0x88,0xAD,0x90,0x42,0x3F, + 0x88,0xD0,0x26,0x85,0xA9,0xA5,0x47,0x37,0xE3,0xC8,0x83,0x88,0xF6,0x52,0x93,0xFD, + 0xE7,0x37,0x83,0xC0,0xE6,0xFC,0x4C,0xCC,0x9F,0x9D,0x90,0x6D,0x2A,0x10,0x62,0x2C, + 0xA5,0x1A,0xD3,0xD4,0x69,0x5C,0x3E,0x81,0x2E,0x65,0x8C,0x68,0x7A,0x83,0xF4,0x61, + 0x3C,0xEC,0xCE,0xE6,0x90,0x76,0xF0,0x11,0xE8,0x2C,0xCE,0xA8,0x1E,0xC9,0x03,0xF6, + 0xC5,0x2D,0x9D,0x50,0xB9,0x37,0xE2,0x5C,0x1B,0x17,0x5D,0xA7,0x41,0xA1,0x1F,0xE3, + 0x11,0xA0,0x35,0xE1,0xB3,0xA1,0x17,0x2E,0x1A,0x40,0xD3,0x32,0x5B,0xF4,0xCF,0x58, + 0xDB,0x9B,0xB7,0x0C,0xB7,0x97,0x70,0xAE,0x3A,0x60,0x9F,0xC1,0xD1,0xEF,0x0C,0x95, + 0xF5,0x4D,0xD3,0x61,0xC3,0xBF,0x28,0xBA,0x6D,0x04,0xB5,0x2B,0x7A,0xEC,0x8B,0x30, + 0x69,0xA9,0xA8,0x22,0xD1,0x60,0xDE,0x8C,0x3C,0xC2,0x46,0x13,0x3D,0xFF,0x1A,0x4F, + 0xDF,0xE9,0x99,0x88,0x2E,0x93,0xE9,0x0F,0x8D,0xD1,0xF4,0xBF,0xEC,0x8A,0xF2,0x79, + 0xFA,0xA8,0xDE,0xD4,0x7C,0xE7,0xB5,0x7F,0xD1,0x6D,0x4F,0x48,0xF6,0x37,0x77,0x3B, + 0x78,0x8A,0x01,0xC4,0x68,0x5B,0x37,0x31,0x71,0x99,0xDF,0x28,0xF4,0x1F, +}; diff --git a/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m b/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m index 651ea37d..130ae6dd 100644 --- a/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m +++ b/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m @@ -21,8 +21,8 @@ static void tests(void) { - SecCertificateRef root = NULL, subca = NULL, leaf1 = NULL, leaf2 = NULL; - NSArray *certs1 = nil, *certs2, *anchors = nil; + SecCertificateRef root = NULL, subca = NULL, leaf1 = NULL, leaf2 = NULL, leaf3 = NULL; + NSArray *certs1 = nil, *certs2 = nil, *certs3 = nil, *anchors = nil; SecPolicyRef policy = SecPolicyCreateBasicX509(); SecTrustRef trust = NULL; SecTrustResultType trustResult = kSecTrustResultInvalid; @@ -36,11 +36,15 @@ static void tests(void) { fail("Failed to create leaf cert 1")); require_action(leaf2 = SecCertificateCreateWithBytes(NULL, _test_leaf2, sizeof(_test_leaf2)), errOut, fail("Failed to create leaf cert 2")); + require_action(leaf3 = SecCertificateCreateWithBytes(NULL, _test_leaf3, sizeof(_test_leaf3)), errOut, + fail("Failed to create leaf cert 3"));; certs1 = @[(__bridge id)leaf1, (__bridge id)subca]; certs2 = @[(__bridge id)leaf2, (__bridge id)subca]; + certs3 = @[(__bridge id)leaf3, (__bridge id)subca]; anchors = @[(__bridge id)root]; + /* Test multiple pre-pended labels and intersecting name constraints in the subCA */ require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1, policy, &trust), errOut, fail("Failed to create trust for leaf 1")); @@ -55,16 +59,33 @@ static void tests(void) { CFReleaseNull(trust); trustResult = kSecTrustResultInvalid; + /* Test no pre-pended labels */ require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs2, policy, &trust), errOut, - fail("Failed to create trust for leaf 1")); + fail("Failed to create trust for leaf 2")); require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("Failed to set verify date")); require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("Failed to set anchors")); require_noerr_action(SecTrustEvaluate(trust, &trustResult), errOut, fail("Failed to evaluate trust")); - is(trustResult, kSecTrustResultUnspecified, "Got wrong trust result for leaf 1"); + is(trustResult, kSecTrustResultUnspecified, "Got wrong trust result for leaf 2"); + + CFReleaseNull(trust); + trustResult = kSecTrustResultInvalid; + + /* Test DNS-looking Common Name */ + date = [NSDate dateWithTimeIntervalSinceReferenceDate:548800000.0]; // 23 May 2018 + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs3, + policy, &trust), errOut, + fail("Failed to create trust for leaf 3")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, + fail("Failed to set verify date")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, + fail("Failed to set anchors")); + require_noerr_action(SecTrustEvaluate(trust, &trustResult), errOut, + fail("Failed to evaluate trust")); + is(trustResult, kSecTrustResultUnspecified, "Got wrong trust result for leaf 3"); errOut: CFReleaseNull(root); @@ -350,7 +371,7 @@ static void cleanup(NSURL *tmpDir) { int si_87_sectrust_name_constraints(int argc, char *const *argv) { NSArray *testsArray = getTestsArray(); - plan_tests(2 + (int)(2 * [testsArray count])); + plan_tests(3 + (int)(2 * [testsArray count])); tests(); if(untar_test_certs()) { diff --git a/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.m b/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.m index dbb98096..dbe3b245 100644 --- a/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.m +++ b/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2015-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -27,11 +27,17 @@ #include #include #include +#include +#include #include -#include "Security_regressions.h" +#if TARGET_OS_OSX +#include +#endif + +#include "shared_regressions.h" -#include "si-89-cms-hash-agility.h" +#include "si-cms-hash-agility-data.h" static void ios_shim_tests(void) { @@ -42,14 +48,15 @@ static void ios_shim_tests(void) CFArrayRef attrValues = NULL; CFDateRef signingTime = NULL, expectedTime = NULL; - ok(message = CFDataCreate(NULL, valid_message, sizeof(valid_message)), "Create valid message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok(message = CFDataCreate(NULL, valid_message, valid_message_size), "Create valid message"); + ok(contentData = CFDataCreate(NULL, content, content_size), "Create detached content"); ok(policy = SecPolicyCreateBasicX509(), "Create policy"); /* verify the valid message and copy out attributes */ is(SecCMSVerifyCopyDataAndAttributes(message, contentData, policy, &trust, NULL, &attrs), errSecSuccess, "Verify valid CMS message and get attributes"); isnt(attrs, NULL, "Copy CMS attributes"); + CFReleaseNull(trust); /* verify we can get the parsed attribute */ uint8_t appleHashAgilityOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x1 }; @@ -79,14 +86,16 @@ static void ios_shim_tests(void) CFReleaseNull(message); /* verify the invalid message */ - ok(message = CFDataCreate(NULL, invalid_message, sizeof(invalid_message)), "Create invalid message"); + ok(message = CFDataCreate(NULL, invalid_message, invalid_message_size), "Create invalid message"); is(SecCMSVerify(message, contentData, policy, &trust, NULL), errSecAuthFailed, "Verify invalid CMS message"); CFReleaseNull(message); + CFReleaseNull(trust); + CFReleaseNull(attrs); /* verify the valid message with no hash agility attribute */ - ok(message = CFDataCreate(NULL, valid_no_attr, sizeof(valid_no_attr)), + ok(message = CFDataCreate(NULL, valid_no_attr, valid_no_attr_size), "Create valid message with no hash agility value"); is(SecCMSVerifyCopyDataAndAttributes(message, contentData, policy, &trust, NULL, &attrs), errSecSuccess, "Verify 2nd valid CMS message and get attributes"); @@ -109,43 +118,18 @@ static void ios_shim_tests(void) } /* MARK: macOS Shim tests */ -#include -#include - /* encode test */ -static void encode_test(void) +static void encode_test(SecIdentityRef identity) { CMSEncoderRef encoder = NULL; - CFDataRef attributeData = NULL, message = NULL, p12Data = NULL; - CFArrayRef imported_items = NULL; - SecIdentityRef identity = NULL; - CFStringRef password = CFSTR("password"); - CFDictionaryRef options = CFDictionaryCreate(NULL, - (const void **)&kSecImportExportPassphrase, - (const void **)&password, 1, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFDictionaryRef itemDict = NULL; - + CFDataRef attributeData = NULL, message = NULL; /* Create encoder */ ok_status(CMSEncoderCreate(&encoder), "Create CMS encoder"); ok_status(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), "Set digest algorithm to SHA256"); - /* Load identity and set as signer */ - ok(p12Data = CFDataCreate(NULL, signing_identity_p12, sizeof(signing_identity_p12)), - "Create p12 data"); - ok_status(SecPKCS12Import(p12Data, options, &imported_items), - "Import identity"); - is(CFArrayGetCount(imported_items),1,"Imported 1 items"); - is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items, 0)), CFDictionaryGetTypeID(), - "Got back a dictionary"); - ok(itemDict = CFArrayGetValueAtIndex(imported_items, 0), "Retreive item dictionary"); - is(CFGetTypeID(CFDictionaryGetValue(itemDict, kSecImportItemIdentity)), SecIdentityGetTypeID(), - "Got back an identity"); - ok(identity = (SecIdentityRef) CFRetainSafe(CFDictionaryGetValue(itemDict, kSecImportItemIdentity)), - "Retrieve identity"); + /* Set identity as signer */ ok_status(CMSEncoderAddSigners(encoder, identity), "Set Signer identity"); /* Add signing time attribute for 3 November 2015 */ @@ -163,7 +147,7 @@ static void encode_test(void) /* Load content */ ok_status(CMSEncoderSetHasDetachedContent(encoder, true), "Set detached content"); - ok_status(CMSEncoderUpdateContent(encoder, content, sizeof(content)), "Set content"); + ok_status(CMSEncoderUpdateContent(encoder, content, content_size), "Set content"); /* output cms message */ ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); @@ -175,15 +159,11 @@ static void encode_test(void) ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); ok_status(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), CFDataGetLength(message)), "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok(contentData = CFDataCreate(NULL, content, content_size), "Create detached content"); ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - CFReleaseNull(encoder); - CFReleaseNull(p12Data); - CFReleaseNull(imported_items); - CFReleaseNull(identity); CFReleaseNull(attributeData); CFReleaseNull(message); CFReleaseNull(decoder); @@ -201,9 +181,9 @@ static void decode_positive_test(void) /* Create decoder and decode */ ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), + ok_status(CMSDecoderUpdateMessage(decoder, valid_message, valid_message_size), "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok(contentData = CFDataCreate(NULL, content, content_size), "Create detached content"); ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); @@ -242,9 +222,9 @@ static void decode_negative_test(void) /* Create decoder and decode */ ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, sizeof(invalid_message)), + ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, invalid_message_size), "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok(contentData = CFDataCreate(NULL, content, content_size), "Create detached content"); ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); @@ -270,9 +250,9 @@ static void decode_no_attr_test(void) /* Create decoder and decode */ ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, sizeof(valid_no_attr)), + ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, valid_no_attr_size), "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok(contentData = CFDataCreate(NULL, content, content_size), "Create detached content"); ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); @@ -294,8 +274,8 @@ static void decode_no_attr_test(void) CFReleaseNull(attrValue); } -static void macos_shim_tests(void) { - encode_test(); +static void macos_shim_tests(SecIdentityRef identity) { + encode_test(identity); decode_positive_test(); decode_negative_test(); decode_no_attr_test(); @@ -312,30 +292,25 @@ static void ios_shim_V2_tests(void) { NSArray *attrValues = nil; NSDate *signingTime = nil; - message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)]; - contentData = [NSData dataWithBytes:content length:sizeof(content)]; + message = [NSMutableData dataWithBytes:_V2_valid_message length:_V2_valid_message_size]; + contentData = [NSData dataWithBytes:content length:content_size]; policy = SecPolicyCreateBasicX509(); /* verify the valid message and copy out attributes */ is(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL, &tmpAttrs), errSecSuccess, "Verify valid CMS message and get attributes"); attrs = CFBridgingRelease(tmpAttrs); - require_string(attrs, exit, "Copy CMS attributes"); + require_action(attrs, exit, fail("Copy CMS attributes")); /* verify we can get the parsed attribute */ uint8_t appleHashAgilityOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x2 }; hashAgilityV2Oid = [NSData dataWithBytes:appleHashAgilityOid length:sizeof(appleHashAgilityOid)]; attrValues = attrs[hashAgilityV2Oid]; - require_string([attrValues count] == (size_t)1, exit, "One attribute value"); - require_string(hashAgilityValue = attrValues[0], exit, "Get hash agility value"); - ok([hashAgilityValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]], - "Got wrong SHA1 agility value"); - ok([hashAgilityValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]], - "Got wrong SHA256 agility value"); + is([attrValues count], (size_t)2, "Two attribute values"); /* verify we can get the "cooked" parsed attribute */ - require_string(hashAgilityValue = (NSDictionary *)attrs[(__bridge NSString*)kSecCMSHashAgilityV2], exit, - "Get cooked hash agility value"); + require_action(hashAgilityValue = (NSDictionary *)attrs[(__bridge NSString*)kSecCMSHashAgilityV2], exit, + fail("Get cooked hash agility value")); ok([hashAgilityValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]], "Got wrong SHA1 agility value"); ok([hashAgilityValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]], @@ -344,17 +319,17 @@ static void ios_shim_V2_tests(void) { attrValues = NULL; /*verify we can get the signing time attribute */ - require_string(signingTime = attrs[(__bridge NSString*)kSecCMSSignDate], exit, "Failed to get signing time"); + require_action(signingTime = attrs[(__bridge NSString*)kSecCMSSignDate], exit, fail("Failed to get signing time")); ok([signingTime isEqualToDate:[NSDate dateWithTimeIntervalSinceReferenceDate:530700000.0]], "Got wrong signing time"); /* verify the invalid message */ - message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)]; - [message resetBytesInRange:NSMakeRange(2110, 0)]; /* reset byte in hash agility attribute */ + message = [NSMutableData dataWithBytes:_V2_valid_message length:_V2_valid_message_size]; + [message resetBytesInRange:NSMakeRange(2110, 1)]; /* reset byte in hash agility attribute */ is(SecCMSVerify((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL), errSecAuthFailed, "Verify invalid CMS message"); /* verify the valid message with no hash agility attribute */ - message = [NSMutableData dataWithBytes:valid_no_attr length:sizeof(valid_no_attr)]; + message = [NSMutableData dataWithBytes:valid_no_attr length:valid_no_attr_size]; is(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL, &tmpAttrs), errSecSuccess, "Verify 2nd valid CMS message and get attributes"); attrs = CFBridgingRelease(tmpAttrs); @@ -370,38 +345,24 @@ exit: } /* macOS shim test - encode */ -static void encode_V2_test(void) { +static void encode_V2_test(SecIdentityRef identity) { CMSEncoderRef encoder = NULL; CMSDecoderRef decoder = NULL; - NSData *p12Data = nil; - CFArrayRef tmp_imported_items = NULL; - NSArray *imported_items = nil; - SecIdentityRef identity = NULL; CFDataRef message = NULL; - NSDictionary *attrValues = nil, *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" }; + NSDictionary *attrValues = nil; /* Create encoder */ - require_noerr_string(CMSEncoderCreate(&encoder), exit, "Failed to create CMS encoder"); - require_noerr_string(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit, - "Failed to set digest algorithm to SHA256"); + require_noerr_action(CMSEncoderCreate(&encoder), exit, fail("Failed to create CMS encoder")); + require_noerr_action(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit, + fail("Failed to set digest algorithm to SHA256")); - /* Load identity and set as signer */ - p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)]; - require_noerr_string(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options, - &tmp_imported_items), exit, - "Failed to import identity"); - imported_items = CFBridgingRelease(tmp_imported_items); - require_noerr_string([imported_items count] == 0 && - [imported_items[0] isKindOfClass:[NSDictionary class]], exit, - "Wrong imported items output"); - identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]); - require_string(identity, exit, "Failed to get identity"); - require_noerr_string(CMSEncoderAddSigners(encoder, identity), exit, "Failed to add signer identity"); + /* Set identity as signer */ + require_noerr_action(CMSEncoderAddSigners(encoder, identity), exit, fail("Failed to add signer identity")); /* Add signing time attribute for 26 October 2017 */ - require_noerr_string(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), exit, - "Failed to set signing time flag"); - require_noerr_string(CMSEncoderSetSigningTime(encoder, 530700000.0), exit, "Failed to set signing time"); + require_noerr_action(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), exit, + fail("Failed to set signing time flag")); + require_noerr_action(CMSEncoderSetSigningTime(encoder, 530700000.0), exit, fail("Failed to set signing time")); /* Add hash agility attribute */ attrValues = @{ @(SEC_OID_SHA1) : [NSData dataWithBytes:_attributev2 length:20], @@ -413,26 +374,25 @@ static void encode_V2_test(void) { "Set hash agility data"); /* Load content */ - require_noerr_string(CMSEncoderSetHasDetachedContent(encoder, true), exit, "Failed to set detached content"); - require_noerr_string(CMSEncoderUpdateContent(encoder, content, sizeof(content)), exit, "Failed to set content"); + require_noerr_action(CMSEncoderSetHasDetachedContent(encoder, true), exit, fail("Failed to set detached content")); + require_noerr_action(CMSEncoderUpdateContent(encoder, content, content_size), exit, fail("Failed to set content")); /* output cms message */ ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); isnt(message, NULL, "Encoded message exists"); /* decode message */ - require_noerr_string(CMSDecoderCreate(&decoder), exit, "Create CMS decoder"); - require_noerr_string(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), CFDataGetLength(message)), exit, - "Update decoder with CMS message"); - require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:content - length:sizeof(content)]), - exit, "Set detached content"); + fail("Update decoder with CMS message")); + require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:content + length:content_size]), + exit, fail("Set detached content")); ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); exit: CFReleaseNull(encoder); - CFReleaseNull(identity); CFReleaseNull(message); CFReleaseNull(decoder); } @@ -448,16 +408,16 @@ static void decode_V2_positive_test(void) { NSDictionary *attrValue = nil; /* Create decoder and decode */ - require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); - require_noerr_string(CMSDecoderUpdateMessage(decoder, _V2_valid_message, sizeof(_V2_valid_message)), exit, - "Failed to update decoder with CMS message"); - contentData = [NSData dataWithBytes:content length:sizeof(content)]; - require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, - "Failed to set detached content"); + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, _V2_valid_message, _V2_valid_message_size), exit, + fail("Failed to update decoder with CMS message")); + contentData = [NSData dataWithBytes:content length:content_size]; + require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, + fail("Failed to set detached content")); ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); /* Get signer status */ - require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); + require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy")); ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), "Copy Signer status"); is(signerStatus, kCMSSignerValid, "Valid signature"); @@ -487,18 +447,18 @@ static void decode_V2_negative_test(void) { NSMutableData *invalid_message = nil; /* Create decoder and decode */ - invalid_message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)]; + invalid_message = [NSMutableData dataWithBytes:_V2_valid_message length:_V2_valid_message_size]; [invalid_message resetBytesInRange:NSMakeRange(2110, 1)]; /* reset byte in hash agility attribute */ - require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); - require_noerr_string(CMSDecoderUpdateMessage(decoder, [invalid_message bytes], [invalid_message length]), exit, - "Failed to update decoder with CMS message"); - contentData = [NSData dataWithBytes:content length:sizeof(content)]; - require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, - "Failed to set detached content"); + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, [invalid_message bytes], [invalid_message length]), exit, + fail("Failed to update decoder with CMS message")); + contentData = [NSData dataWithBytes:content length:content_size]; + require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, + fail("Failed to set detached content")); ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); /* Get signer status */ - require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); + require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy")); ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), "Copy Signer status"); is(signerStatus, kCMSSignerInvalidSignature, "Valid signature"); @@ -519,16 +479,16 @@ static void decodeV2_no_attr_test(void) { CFDictionaryRef attrValue = NULL; /* Create decoder and decode */ - require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); - require_noerr_string(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), exit, - "Failed to update decoder with CMS message"); - contentData = [NSData dataWithBytes:content length:sizeof(content)]; - require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, - "Failed to set detached content"); + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, valid_message, valid_message_size), exit, + fail("Failed to update decoder with CMS message")); + contentData = [NSData dataWithBytes:content length:content_size]; + require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, + fail("Failed to set detached content")); ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); /* Get signer status */ - require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); + require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy")); ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), "Copy Signer status"); is(signerStatus, kCMSSignerValid, "Valid signature"); @@ -545,21 +505,60 @@ exit: CFReleaseNull(attrValue); } -static void macOS_shim_V2_tests(void) { - encode_V2_test(); +static void macOS_shim_V2_tests(SecIdentityRef identity) { + encode_V2_test(identity); decode_V2_positive_test(); decode_V2_negative_test(); decodeV2_no_attr_test(); } +static bool setup_keychain(const uint8_t *p12, size_t p12_len, SecIdentityRef *identity) { + CFArrayRef tmp_imported_items = NULL; + NSArray *imported_items = nil; + + NSDictionary *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" }; + NSData *p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)]; + require_noerr_action(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options, + &tmp_imported_items), exit, + fail("Failed to import identity")); + imported_items = CFBridgingRelease(tmp_imported_items); + require_noerr_action([imported_items count] == 0 && + [imported_items[0] isKindOfClass:[NSDictionary class]], exit, + fail("Wrong imported items output")); + *identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]); + require_action(*identity, exit, fail("Failed to get identity")); + + return true; + +exit: + return false; +} + +static void cleanup_keychain(SecIdentityRef identity) { +#if TARGET_OS_OSX + // SecPKCS12Import adds the items to the keychain on macOS + NSDictionary *query = @{ (__bridge NSString*)kSecValueRef : (__bridge id)identity }; + ok_status(SecItemDelete((__bridge CFDictionaryRef)query), "failed to remove identity from keychain"); +#else + pass("skip test on iOS"); +#endif + CFReleaseNull(identity); +} + int si_89_cms_hash_agility(int argc, char *const *argv) { - plan_tests(99); + plan_tests(102); + + SecIdentityRef identity = NULL; + + if (setup_keychain(signing_identity_p12 , sizeof(signing_identity_p12), &identity)) { + ios_shim_tests(); + macos_shim_tests(identity); + ios_shim_V2_tests(); + macOS_shim_V2_tests(identity); + } - ios_shim_tests(); - macos_shim_tests(); - ios_shim_V2_tests(); - macOS_shim_V2_tests(); + cleanup_keychain(identity); return 0; } diff --git a/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.h b/OSX/sec/Security/Regressions/secitem/si-cms-hash-agility-data.c similarity index 71% rename from OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.h rename to OSX/sec/Security/Regressions/secitem/si-cms-hash-agility-data.c index a52b5fb5..8417722e 100644 --- a/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.h +++ b/OSX/sec/Security/Regressions/secitem/si-cms-hash-agility-data.c @@ -1,30 +1,4 @@ -/* - * Copyright (c) 2015 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@ - */ - -#ifndef si_89_cms_hash_agility_h -#define si_89_cms_hash_agility_h - -#include +#include "si-cms-hash-agility-data.h" /* Random data for content */ unsigned char content[1024] = { @@ -81,6 +55,7 @@ unsigned char content[1024] = { 0x6f, 0x00, 0x70, 0x91, 0x86, 0x57, 0x36, 0x23, 0x1f, 0x29, 0x8b, 0x52, 0xb2, 0x31, 0xd5, 0x8d, 0xc5, 0xa3, 0x5f, 0xd3, 0x7a, 0xe4, 0x2e, 0x3a }; +size_t content_size = sizeof(content); /* Random data for hash agility attribute */ unsigned char attribute[32] = { @@ -266,6 +241,7 @@ uint8_t valid_message[] = { 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +size_t valid_message_size = sizeof(valid_message); /* * Invalid CMS message on content with hash agility attribute. @@ -440,6 +416,7 @@ uint8_t invalid_message[] = { 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +size_t invalid_message_size = sizeof(invalid_message); /* Valid CMS message with no hash agility attribute */ unsigned char valid_no_attr[] = { @@ -608,239 +585,9 @@ unsigned char valid_no_attr[] = { 0xb9, 0x65, 0x43, 0x49, 0xae, 0x31, 0x25, 0x76, 0x4b, 0xfb, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +size_t valid_no_attr_size = sizeof(valid_no_attr); -/* - * password: "password" - * localKeyID: 01 AE 1A 61 75 AE 23 D9 11 5C 28 93 A9 E2 49 5E 74 28 4C 08 - * subject=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer - * issuer=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer - */ -unsigned char signing_identity_p12[4477] = { - 0x30, 0x82, 0x11, 0x79, 0x02, 0x01, 0x03, 0x30, 0x82, 0x11, 0x3f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x07, 0x01, 0xa0, 0x82, 0x11, 0x30, 0x04, 0x82, 0x11, 0x2c, 0x30, 0x82, 0x11, 0x28, 0x30, 0x82, 0x07, 0x57, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x07, 0x48, 0x30, 0x82, 0x07, 0x44, 0x02, 0x01, 0x00, - 0x30, 0x82, 0x07, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xed, 0xd8, 0x65, 0x57, 0xbb, 0xca, 0x25, - 0x46, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x07, 0x10, 0xc0, 0x1d, 0x0d, 0x5c, 0x7f, 0x3b, 0xbe, 0x20, 0xd4, 0x9a, 0x0d, - 0xaf, 0xb6, 0x4b, 0xc7, 0x7f, 0xa8, 0xa8, 0x3f, 0x6c, 0x96, 0x1c, 0xea, 0x90, 0xd2, 0x79, 0x9f, 0x56, 0x3a, 0x5a, 0x29, - 0x93, 0xff, 0x72, 0x39, 0x9e, 0x41, 0xd9, 0x5a, 0xfc, 0xb5, 0x54, 0x2d, 0x89, 0x60, 0x18, 0xf2, 0xea, 0x8c, 0xeb, 0x7f, - 0xba, 0x87, 0xc6, 0x70, 0x42, 0x25, 0x55, 0x24, 0xc5, 0x4f, 0x26, 0x66, 0x8d, 0x78, 0x44, 0x47, 0x85, 0x36, 0x53, 0x86, - 0xc9, 0x18, 0x83, 0x33, 0x4b, 0x4b, 0x08, 0x2d, 0x7b, 0x68, 0x37, 0x29, 0x4c, 0x20, 0x74, 0xd4, 0x4f, 0xbb, 0x6e, 0x97, - 0x7a, 0xf4, 0xbf, 0xcb, 0x40, 0x26, 0x2d, 0xac, 0x95, 0x82, 0xe0, 0x88, 0xfe, 0x54, 0x80, 0xe9, 0xf5, 0xda, 0x8e, 0x6e, - 0x3a, 0x47, 0x2d, 0xc8, 0xd4, 0xe7, 0x2e, 0xff, 0xec, 0xfa, 0xa5, 0x70, 0xcd, 0x2e, 0x99, 0x26, 0x32, 0xc8, 0x1d, 0x53, - 0x60, 0x1e, 0x6f, 0x68, 0xcb, 0x49, 0xd0, 0xa2, 0xf8, 0x47, 0x70, 0x1b, 0x9e, 0x85, 0xbe, 0x4e, 0x56, 0xb5, 0x8b, 0x66, - 0x45, 0x57, 0xe3, 0xbd, 0x57, 0xed, 0x94, 0x53, 0xf6, 0x72, 0xd7, 0xb7, 0xc6, 0x9f, 0x05, 0xf5, 0x98, 0xb4, 0x13, 0x35, - 0x69, 0x24, 0x94, 0xd9, 0x3d, 0x80, 0xbc, 0xa8, 0xea, 0x78, 0x0c, 0xe0, 0xa2, 0xfe, 0x1b, 0xd2, 0x82, 0x3d, 0x83, 0x34, - 0x76, 0xb4, 0x45, 0xf8, 0x14, 0x09, 0x66, 0x02, 0x68, 0xc3, 0x1b, 0xcb, 0x6c, 0x91, 0x6b, 0x3e, 0xdc, 0x35, 0x68, 0xab, - 0x49, 0x47, 0x6c, 0x60, 0xea, 0xe3, 0xd5, 0x59, 0x82, 0x9c, 0x18, 0xb0, 0x6d, 0x45, 0xc0, 0x2f, 0x58, 0xf1, 0x44, 0x79, - 0xe3, 0xd2, 0xd6, 0x16, 0xbc, 0xde, 0x17, 0xae, 0xf7, 0xea, 0x3c, 0xe4, 0xb4, 0x7b, 0xdf, 0xba, 0x9b, 0xf1, 0xb8, 0xa8, - 0xb0, 0x51, 0xeb, 0xe8, 0xc3, 0xe9, 0x9c, 0x1b, 0x06, 0xdd, 0x89, 0x07, 0x98, 0xf8, 0x01, 0x7f, 0xde, 0x7e, 0x05, 0xa6, - 0x72, 0x0b, 0x3f, 0xf4, 0x7d, 0xca, 0x74, 0x7b, 0xc9, 0x87, 0x0d, 0x35, 0x8b, 0x05, 0x3a, 0x73, 0x04, 0x08, 0x7a, 0x51, - 0x34, 0x29, 0x5b, 0xd8, 0x90, 0x0f, 0xa7, 0xf0, 0x48, 0xfc, 0x9c, 0x74, 0xca, 0xe9, 0x34, 0x75, 0x1c, 0xd1, 0xa6, 0xd1, - 0xfb, 0x9f, 0xc7, 0x82, 0x40, 0x75, 0x87, 0xdd, 0xa2, 0x22, 0xeb, 0x91, 0xd7, 0x85, 0x1a, 0x2c, 0xa7, 0x3d, 0xd5, 0xe4, - 0xca, 0x85, 0x00, 0x33, 0x11, 0x6d, 0x62, 0xa8, 0xb7, 0xd3, 0x45, 0x46, 0xdc, 0xb4, 0xa3, 0xeb, 0xae, 0x5e, 0x8c, 0xc2, - 0x7a, 0x0b, 0x83, 0x98, 0x5a, 0x94, 0x0f, 0x68, 0x61, 0x36, 0x57, 0x6e, 0x94, 0xe0, 0x6d, 0x93, 0x76, 0xa0, 0x5d, 0x3f, - 0x25, 0x8b, 0x3b, 0x46, 0x1e, 0x0c, 0x15, 0x6b, 0x9f, 0x1d, 0xc3, 0x5f, 0x61, 0x42, 0xd5, 0xf8, 0x79, 0xcd, 0xd1, 0x0a, - 0x96, 0xce, 0x49, 0x8a, 0xff, 0x54, 0x46, 0x77, 0x65, 0x37, 0x70, 0xcd, 0x65, 0x6f, 0x3d, 0x49, 0xc1, 0x29, 0x8d, 0x16, - 0xbd, 0x36, 0x47, 0x54, 0xa5, 0x4d, 0x06, 0xfb, 0x33, 0x00, 0x29, 0xd8, 0x31, 0x09, 0x58, 0x12, 0x4c, 0xfe, 0xef, 0x8e, - 0xf9, 0x1e, 0x30, 0xf7, 0x05, 0xb2, 0xd8, 0xd4, 0x7d, 0xae, 0xab, 0x57, 0xb7, 0x46, 0x09, 0xff, 0xca, 0xc7, 0x7b, 0xca, - 0x73, 0xfa, 0xf9, 0x50, 0xa0, 0xb8, 0x09, 0xc2, 0x80, 0x43, 0x0d, 0x99, 0x7f, 0x4e, 0xdf, 0xd5, 0x6c, 0xc4, 0x42, 0x1a, - 0x05, 0xbd, 0x65, 0xf4, 0x57, 0x2a, 0xe5, 0xc4, 0xcb, 0x79, 0x3f, 0x8f, 0x74, 0x93, 0x66, 0x8d, 0x93, 0xda, 0xba, 0x23, - 0x77, 0x3f, 0xad, 0xd3, 0x8b, 0xae, 0xf5, 0xf1, 0x5c, 0xc1, 0xd2, 0x00, 0x3a, 0x60, 0x8e, 0xc3, 0x32, 0xd6, 0x8e, 0xce, - 0x95, 0x24, 0x03, 0x79, 0x03, 0xf2, 0xb8, 0x2a, 0x94, 0xeb, 0x15, 0x97, 0xdc, 0x18, 0x8d, 0xc7, 0xd9, 0xc2, 0x63, 0x69, - 0xfb, 0xf9, 0x8f, 0x05, 0xd3, 0x7c, 0x60, 0x5a, 0x57, 0xe4, 0xa5, 0xc1, 0xdf, 0x1d, 0x11, 0x84, 0x69, 0xba, 0x20, 0xd8, - 0x79, 0xc3, 0x34, 0x3a, 0xb1, 0x63, 0x4c, 0xd2, 0x91, 0x2d, 0x87, 0x1e, 0xec, 0x06, 0xea, 0x35, 0x97, 0x0e, 0x59, 0x54, - 0x83, 0x50, 0x3e, 0xac, 0xf2, 0xea, 0x6c, 0x0c, 0xa0, 0x57, 0xfb, 0xe8, 0x6b, 0xf9, 0xd1, 0x25, 0xc0, 0xa2, 0xb0, 0xa2, - 0xcd, 0xde, 0x2b, 0xa7, 0xb3, 0x40, 0x75, 0x36, 0xf7, 0x20, 0xbe, 0xd7, 0xd1, 0x2e, 0x66, 0xc5, 0x3c, 0xf8, 0x6e, 0xce, - 0xcb, 0x76, 0x7f, 0x1d, 0x32, 0x3b, 0x14, 0x27, 0x9c, 0x9e, 0xa3, 0xeb, 0x0c, 0x2f, 0x71, 0xba, 0x0d, 0xca, 0x27, 0x90, - 0x42, 0xfd, 0xd4, 0x34, 0xb9, 0x96, 0xae, 0xcb, 0xd8, 0xfe, 0x31, 0x62, 0xe8, 0x4c, 0x07, 0x71, 0xb9, 0x0c, 0x9f, 0xe2, - 0x8e, 0x66, 0xc2, 0x39, 0xc5, 0xc3, 0x1c, 0xfd, 0x5e, 0x18, 0x0b, 0xd4, 0x93, 0x3d, 0x98, 0x33, 0xaf, 0x6d, 0xb4, 0x6f, - 0xe6, 0x75, 0x67, 0x62, 0xe7, 0x42, 0xee, 0xc6, 0xf2, 0x2e, 0x21, 0xa9, 0x75, 0xde, 0x0a, 0x8c, 0x39, 0xb7, 0x4b, 0x54, - 0x01, 0xa7, 0xeb, 0x5a, 0x88, 0x79, 0xa8, 0xb3, 0x3f, 0x31, 0x8c, 0x47, 0x08, 0x94, 0x47, 0x52, 0xcf, 0x3c, 0xac, 0xd9, - 0x32, 0x57, 0x4a, 0x18, 0x55, 0x5b, 0x66, 0xdc, 0x89, 0xd2, 0xc6, 0xa1, 0x11, 0x40, 0x19, 0x9c, 0x46, 0x88, 0x21, 0x77, - 0xc1, 0x7f, 0x09, 0xc7, 0xfb, 0x52, 0x92, 0xec, 0x1a, 0xe0, 0xdd, 0x76, 0xb9, 0xfd, 0xa7, 0x8f, 0x61, 0xe3, 0xf0, 0x1b, - 0x4e, 0xdb, 0xa0, 0xde, 0x90, 0xd6, 0x49, 0xea, 0xe9, 0x86, 0xc6, 0x5d, 0xac, 0xd0, 0xc2, 0xc5, 0x01, 0xcb, 0x3f, 0xcb, - 0xf0, 0x62, 0x90, 0xa1, 0x17, 0x4b, 0x72, 0x5c, 0xc8, 0xe9, 0x24, 0x93, 0xda, 0x5c, 0x75, 0x24, 0x96, 0x35, 0x54, 0xf4, - 0xfa, 0xc8, 0x27, 0xe1, 0xdd, 0x32, 0xda, 0x2f, 0x2b, 0x7d, 0xf6, 0xd8, 0x0b, 0xf2, 0xca, 0xb5, 0xee, 0x8a, 0xcf, 0xb6, - 0x26, 0x71, 0x65, 0x85, 0xfe, 0x8c, 0x37, 0xf1, 0x17, 0x6b, 0x5e, 0x8a, 0xee, 0xb4, 0xc7, 0x0a, 0xff, 0xb2, 0x9a, 0x72, - 0xe5, 0x85, 0xf3, 0xc0, 0xf9, 0x84, 0xbc, 0xe0, 0x18, 0x3c, 0x12, 0x0c, 0xa1, 0xe9, 0x10, 0xd4, 0x3b, 0x1a, 0x21, 0x35, - 0xc6, 0x06, 0x93, 0xa0, 0xdf, 0x0d, 0x68, 0xa3, 0xf1, 0x06, 0xd9, 0xed, 0xb7, 0xa7, 0xba, 0xb0, 0x22, 0xc2, 0x0b, 0x6b, - 0x70, 0x50, 0xf5, 0x49, 0x9a, 0x4f, 0x99, 0xaa, 0x1e, 0x9c, 0xa6, 0xf3, 0x99, 0x3a, 0xfd, 0x3b, 0xd2, 0xeb, 0xce, 0x1e, - 0x72, 0x62, 0x99, 0xc0, 0x1e, 0x2b, 0x09, 0x75, 0x4a, 0xfb, 0xc8, 0x26, 0xcf, 0x76, 0xa2, 0x0e, 0xef, 0xf4, 0xa8, 0x70, - 0x31, 0xd8, 0xa1, 0x22, 0x62, 0xcc, 0x9f, 0xd5, 0xa3, 0x55, 0xc2, 0x78, 0xd7, 0x27, 0xfc, 0x3c, 0x53, 0xe8, 0xeb, 0x7e, - 0x7a, 0x27, 0xcf, 0x6d, 0x52, 0xb5, 0x9a, 0x2b, 0x49, 0x8d, 0x3f, 0x89, 0x80, 0x1a, 0x5c, 0x39, 0xe7, 0x53, 0xb3, 0xf3, - 0x33, 0x97, 0xcf, 0x7d, 0xfb, 0x8e, 0x19, 0xf4, 0x72, 0xeb, 0xe7, 0xdf, 0xb1, 0xe3, 0xc1, 0x6c, 0x7f, 0x17, 0x89, 0x34, - 0x4f, 0x45, 0x0f, 0xc5, 0xfc, 0x15, 0xb3, 0x3f, 0xc6, 0xdc, 0x25, 0xa6, 0xda, 0x28, 0x85, 0x5d, 0x25, 0x02, 0x78, 0x74, - 0xd9, 0x74, 0xb8, 0x65, 0x48, 0x3a, 0x8a, 0x2a, 0xd5, 0xa9, 0xb8, 0x7f, 0xaa, 0x9d, 0xe7, 0xaf, 0xbd, 0xdf, 0xfd, 0x00, - 0x67, 0xab, 0x39, 0xe1, 0x2c, 0x3d, 0xd1, 0x5c, 0x9b, 0x61, 0x2b, 0x51, 0xdc, 0x87, 0x19, 0x6c, 0xa0, 0x12, 0xd4, 0x60, - 0xed, 0x94, 0xe9, 0xeb, 0x4e, 0x51, 0xd8, 0x50, 0xcb, 0x97, 0x8a, 0x20, 0x21, 0xdf, 0xe9, 0x2c, 0xd2, 0xe2, 0x04, 0x14, - 0xaf, 0x7b, 0x7e, 0xd6, 0xeb, 0x1d, 0x25, 0x09, 0x98, 0x8e, 0x9e, 0x56, 0xf8, 0x7d, 0xfc, 0x0f, 0xbf, 0xd2, 0x6b, 0xbc, - 0xab, 0xed, 0xca, 0x43, 0x6d, 0x28, 0xbe, 0xd5, 0x20, 0x44, 0xcb, 0x6b, 0xbc, 0x80, 0x5a, 0x82, 0x13, 0x50, 0xbd, 0xda, - 0x18, 0x10, 0xac, 0xae, 0x56, 0xb9, 0x46, 0xc5, 0xa2, 0xca, 0xb2, 0x03, 0xf0, 0x57, 0xfe, 0xcd, 0x9a, 0x1b, 0x81, 0x6a, - 0x10, 0x51, 0x2e, 0x88, 0x30, 0x57, 0x3c, 0xfe, 0x7c, 0x56, 0x0c, 0x00, 0x89, 0x5c, 0x21, 0x57, 0x19, 0x96, 0x85, 0x98, - 0xeb, 0x43, 0x71, 0x0d, 0x8a, 0x35, 0xc3, 0xae, 0x36, 0x59, 0x72, 0x97, 0x12, 0x6d, 0xcd, 0x28, 0x64, 0x17, 0x9e, 0xe7, - 0x2c, 0x28, 0xfd, 0x32, 0xa8, 0x10, 0x67, 0x4e, 0xc0, 0x14, 0x21, 0x7c, 0x36, 0x20, 0xe9, 0x46, 0x68, 0x62, 0xc1, 0xff, - 0xb0, 0xdf, 0xaa, 0x87, 0xff, 0x94, 0xa4, 0xf3, 0xb3, 0xc8, 0x53, 0x57, 0x18, 0x92, 0x15, 0xc7, 0x78, 0x2d, 0x91, 0xba, - 0xb3, 0x1f, 0x06, 0x13, 0x79, 0x21, 0x86, 0x1d, 0xa2, 0x38, 0x2c, 0xda, 0x35, 0x31, 0xbb, 0x04, 0x65, 0xa3, 0x01, 0xa6, - 0x63, 0xa4, 0x4a, 0xa2, 0xc1, 0xad, 0x04, 0xc1, 0xfa, 0x78, 0xe1, 0xb6, 0x50, 0x46, 0xab, 0xad, 0x1c, 0xcf, 0xf4, 0xe5, - 0xba, 0xa5, 0xe2, 0x91, 0x29, 0x4b, 0xa1, 0xc6, 0x4b, 0x30, 0xa5, 0x31, 0x02, 0xe9, 0xd0, 0x50, 0x72, 0x2c, 0x8e, 0xbd, - 0xb2, 0x12, 0xd9, 0x4f, 0x7c, 0x87, 0x4b, 0xa0, 0x45, 0x71, 0x0c, 0x23, 0x37, 0x6b, 0x60, 0xd7, 0x9f, 0x19, 0xe8, 0x0b, - 0x85, 0x57, 0x72, 0xb6, 0xbb, 0x20, 0x23, 0xd3, 0x7d, 0x9a, 0x9b, 0x9a, 0x05, 0x46, 0x5c, 0xf5, 0x02, 0xf1, 0x56, 0x00, - 0xc2, 0x05, 0x85, 0x48, 0xd3, 0x8d, 0x8e, 0xe1, 0xcb, 0xc5, 0x83, 0x1f, 0x78, 0xd0, 0xc5, 0xb1, 0xdf, 0x80, 0x9d, 0x04, - 0xe7, 0xac, 0xd1, 0x68, 0x1a, 0x19, 0x18, 0x16, 0xfa, 0x3a, 0xe2, 0xd2, 0x30, 0x08, 0x17, 0x4d, 0x50, 0x2b, 0xd4, 0xa3, - 0xbe, 0x98, 0x5f, 0xe0, 0xcf, 0xed, 0x7d, 0x74, 0x94, 0xd1, 0xb2, 0x77, 0xbc, 0x72, 0xbc, 0xf5, 0xc7, 0x82, 0x26, 0x53, - 0x14, 0xcc, 0xf9, 0xf7, 0x71, 0xea, 0x97, 0xaa, 0xbf, 0x21, 0x46, 0x59, 0x2c, 0x9a, 0xc4, 0xeb, 0xa3, 0x4a, 0x97, 0x91, - 0x11, 0xf1, 0x01, 0x19, 0x7e, 0xb1, 0xb2, 0x63, 0x0d, 0xf0, 0x5d, 0xaf, 0x53, 0xdf, 0x4d, 0xa1, 0x90, 0xe5, 0x12, 0x82, - 0x33, 0x6f, 0x1d, 0x73, 0xdf, 0xdb, 0x1f, 0x18, 0xa0, 0x72, 0xc1, 0xd6, 0xa7, 0x4d, 0xb2, 0x3e, 0x24, 0xb7, 0xa7, 0x76, - 0x15, 0x46, 0x22, 0x48, 0x49, 0x55, 0xd1, 0xfb, 0x66, 0x32, 0x02, 0xa9, 0xfc, 0xbe, 0x7e, 0x16, 0xcf, 0xac, 0x32, 0xbc, - 0xdb, 0xd5, 0xd8, 0xa3, 0x23, 0x6a, 0x10, 0xa6, 0x37, 0x03, 0xf6, 0x2a, 0xde, 0xba, 0xde, 0x2d, 0x7d, 0xef, 0x1d, 0xb9, - 0xf3, 0x93, 0xd4, 0xf2, 0x13, 0xf4, 0x9c, 0x5a, 0x32, 0xba, 0x5f, 0xef, 0x7b, 0xd0, 0x6b, 0xd7, 0x91, 0x6d, 0x7b, 0xe1, - 0x4d, 0xf2, 0x8c, 0xe7, 0xf1, 0x66, 0xb9, 0xad, 0xc6, 0x30, 0x08, 0x9e, 0x51, 0xd4, 0x39, 0x87, 0x09, 0xfa, 0x6b, 0x7a, - 0xa7, 0x5f, 0x1a, 0x9c, 0x98, 0xc5, 0x76, 0xb0, 0x71, 0x76, 0xf5, 0xfc, 0x56, 0x88, 0x1c, 0xca, 0xee, 0x76, 0xd4, 0x2c, - 0xa6, 0x64, 0x80, 0x59, 0x12, 0x8c, 0x08, 0xce, 0x83, 0xb3, 0xd9, 0x68, 0x59, 0xc1, 0x26, 0x86, 0xa7, 0x80, 0x10, 0xbc, - 0x41, 0x28, 0x6c, 0x45, 0xd4, 0x6d, 0x15, 0xd0, 0x76, 0x44, 0x0e, 0xcf, 0xc1, 0xde, 0xef, 0x7a, 0x97, 0x36, 0x8f, 0x0d, - 0x8a, 0xf5, 0x45, 0xde, 0xae, 0x61, 0xd0, 0x55, 0xe9, 0x8d, 0x62, 0xfd, 0xa3, 0x0d, 0x44, 0x0f, 0x49, 0xb6, 0x5a, 0xa4, - 0xaa, 0x03, 0x4e, 0x60, 0x35, 0x53, 0x86, 0x9e, 0xec, 0x75, 0xd9, 0x0a, 0xca, 0x14, 0xe3, 0x1b, 0x06, 0x05, 0xd6, 0x8f, - 0x4f, 0x11, 0xb3, 0x13, 0xdd, 0x26, 0x35, 0xbd, 0x56, 0x55, 0xf1, 0x43, 0x89, 0x5e, 0x5b, 0x25, 0x4d, 0xa8, 0x09, 0xdd, - 0xf2, 0x6d, 0x9e, 0x8c, 0xcd, 0xa2, 0xde, 0x84, 0x00, 0x6a, 0x0a, 0xc6, 0x92, 0x30, 0x82, 0xcf, 0xa4, 0x31, 0x67, 0xbd, - 0xd4, 0x36, 0x6a, 0x8b, 0xc6, 0x33, 0xdf, 0x8b, 0xde, 0x33, 0x01, 0x7b, 0x9d, 0xbf, 0xe9, 0x12, 0x35, 0x8a, 0x97, 0x07, - 0x72, 0x0b, 0x6b, 0x60, 0xe6, 0x1e, 0x7d, 0x78, 0x22, 0x9f, 0xbf, 0x66, 0x8e, 0x02, 0xf4, 0xdc, 0xa1, 0xb0, 0x42, 0x73, - 0x86, 0xca, 0x34, 0xf0, 0xa7, 0x2e, 0x15, 0x84, 0xa4, 0x60, 0xa8, 0x47, 0x05, 0x80, 0x03, 0x27, 0xa8, 0x04, 0x03, 0xfe, - 0x47, 0xd4, 0xeb, 0x33, 0x27, 0xbf, 0x89, 0xff, 0x4c, 0xd9, 0x27, 0x0e, 0xd0, 0xa9, 0x41, 0x8b, 0xd5, 0x7c, 0xc4, 0x14, - 0x7a, 0x9c, 0xb3, 0xaa, 0x13, 0x32, 0xa4, 0x67, 0xd5, 0x95, 0xdc, 0x4a, 0x3d, 0xf2, 0x54, 0xd7, 0x02, 0xf8, 0x06, 0x7b, - 0x1d, 0x9a, 0xa4, 0x53, 0xa0, 0x9c, 0x76, 0x7d, 0xf4, 0x01, 0xa3, 0x4b, 0xb2, 0x8b, 0x44, 0x85, 0xf6, 0x80, 0x99, 0x2f, - 0x77, 0x08, 0x20, 0xea, 0x08, 0xf8, 0x14, 0x76, 0xfe, 0xa0, 0x5a, 0xf9, 0x1f, 0x87, 0x03, 0xff, 0x8d, 0x1f, 0x5d, 0x02, - 0x64, 0x8a, 0xf4, 0xa5, 0x8c, 0xb7, 0x0a, 0x34, 0x68, 0xaa, 0xca, 0xc8, 0xe1, 0x78, 0x9b, 0xd3, 0x6c, 0x5c, 0x07, 0x99, - 0xc1, 0x10, 0x3f, 0x77, 0x0c, 0x45, 0xa2, 0xda, 0xda, 0xab, 0x7c, 0xf0, 0x90, 0x12, 0xa2, 0x7c, 0x84, 0x30, 0x82, 0x09, - 0xc9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x09, 0xba, 0x04, 0x82, 0x09, 0xb6, - 0x30, 0x82, 0x09, 0xb2, 0x30, 0x82, 0x09, 0xae, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, - 0x02, 0xa0, 0x82, 0x09, 0x76, 0x30, 0x82, 0x09, 0x72, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0xd3, 0x5d, 0xa8, 0x14, 0xbc, 0x7a, 0xaa, 0x5f, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x09, 0x50, 0xaf, 0xe9, 0x63, 0xb6, 0x05, 0x8b, 0x48, 0xe1, 0x11, 0xd0, 0x37, 0x1d, 0x48, 0x71, 0x22, 0x70, 0xdc, - 0xbd, 0xca, 0x98, 0x5d, 0x72, 0xca, 0x38, 0xdc, 0x2e, 0x4f, 0xd4, 0x71, 0xd3, 0xac, 0xf3, 0x0c, 0xcf, 0x78, 0x4e, 0x5c, - 0x63, 0x35, 0xaa, 0xac, 0x5a, 0xf0, 0xef, 0x6c, 0xc0, 0x89, 0x28, 0xc4, 0x64, 0xec, 0x5c, 0x92, 0x72, 0xbc, 0xe5, 0x30, - 0xe9, 0x5c, 0x35, 0xff, 0xe0, 0xb1, 0x1f, 0xc6, 0x37, 0x50, 0xb7, 0x3d, 0x94, 0x28, 0xbd, 0x3b, 0xf0, 0xd9, 0x5c, 0xb1, - 0x45, 0x93, 0xde, 0x41, 0x5b, 0x12, 0xba, 0xfa, 0x27, 0x49, 0x6b, 0xb7, 0x9a, 0xa6, 0x46, 0x8e, 0xe3, 0x15, 0x1b, 0x7f, - 0x2c, 0x91, 0x2e, 0x33, 0xf3, 0xef, 0x7a, 0x9b, 0x9d, 0xa8, 0x82, 0x95, 0xa0, 0x7e, 0x43, 0xd6, 0x9d, 0xe2, 0xfb, 0xb1, - 0xb0, 0xcf, 0xbd, 0xb6, 0x9b, 0x55, 0x4c, 0xc8, 0x4a, 0xc7, 0x82, 0xeb, 0x3d, 0x09, 0x8d, 0x85, 0x6f, 0x8c, 0x42, 0x6d, - 0x10, 0x7d, 0x77, 0x57, 0x29, 0x00, 0xe2, 0xd8, 0x2f, 0xed, 0x7c, 0x10, 0x5b, 0x03, 0xfa, 0x60, 0x34, 0xc9, 0x63, 0x25, - 0x4d, 0x02, 0x77, 0x8f, 0x7f, 0x4b, 0x53, 0xe4, 0x8d, 0x1e, 0x4e, 0x2c, 0x0c, 0x7f, 0x0e, 0x48, 0x4b, 0xcd, 0xc8, 0x6a, - 0xfa, 0xd3, 0x9f, 0x6f, 0x20, 0x4e, 0x2c, 0x77, 0x2a, 0x84, 0x5e, 0x6c, 0xc3, 0x57, 0xba, 0x97, 0xa7, 0xa8, 0xcb, 0x6f, - 0x22, 0xc1, 0xa7, 0x61, 0xf7, 0x7e, 0x7a, 0xae, 0xda, 0xbd, 0x3a, 0xea, 0xb3, 0x46, 0x54, 0x8d, 0x46, 0x48, 0x1f, 0xf3, - 0x5c, 0xaa, 0x2e, 0x44, 0xe1, 0x83, 0x69, 0x45, 0x30, 0x02, 0x49, 0x63, 0xa6, 0xdd, 0xf0, 0x25, 0xce, 0x81, 0xab, 0x66, - 0x20, 0x04, 0x12, 0x2f, 0x94, 0x2f, 0x8f, 0xf9, 0x88, 0xea, 0x5b, 0xba, 0x87, 0xd7, 0xbe, 0x63, 0x2e, 0xb4, 0xa4, 0x15, - 0xe8, 0x56, 0x9e, 0xb5, 0x7b, 0x27, 0xf8, 0x06, 0xfd, 0xf5, 0x21, 0x93, 0x2b, 0x64, 0xb0, 0xe2, 0x31, 0xb3, 0x19, 0xe0, - 0x6b, 0x10, 0x8c, 0xa5, 0xa5, 0x38, 0x27, 0x78, 0xc9, 0x9c, 0x01, 0xa7, 0x42, 0x22, 0x3d, 0xf8, 0x8c, 0x23, 0x46, 0xc5, - 0x4e, 0x47, 0xa5, 0x9e, 0xd7, 0xa5, 0x50, 0x24, 0x02, 0x30, 0xe9, 0x15, 0x3e, 0x17, 0xba, 0x2c, 0xf2, 0x5e, 0xc7, 0x01, - 0x25, 0x9a, 0x74, 0x73, 0x5c, 0x5e, 0xca, 0x01, 0xe2, 0x58, 0x96, 0x47, 0x3e, 0x4c, 0xb9, 0x0f, 0x95, 0xbf, 0xf3, 0xc4, - 0x24, 0x98, 0x6c, 0xc5, 0x40, 0xd2, 0xf3, 0x88, 0x62, 0xb0, 0x25, 0x54, 0xb5, 0xf6, 0x2b, 0xfd, 0xf5, 0x6a, 0x6d, 0x15, - 0xb2, 0x18, 0x7d, 0xef, 0x3e, 0x66, 0x7d, 0x38, 0x4c, 0xda, 0xc9, 0x1a, 0xcd, 0x40, 0x2a, 0xc6, 0x7b, 0x2e, 0x8a, 0x15, - 0xa7, 0xae, 0x99, 0xf5, 0x93, 0x39, 0x20, 0xd2, 0xd8, 0xfd, 0x1f, 0x87, 0x2e, 0xa0, 0xcd, 0x95, 0xa2, 0xd7, 0xd0, 0x48, - 0xf7, 0x6e, 0x81, 0x91, 0x1c, 0x37, 0x8a, 0x28, 0x6f, 0x22, 0x7b, 0x37, 0x69, 0x30, 0x3a, 0x64, 0x6e, 0x4a, 0x5f, 0x0a, - 0xa6, 0xd7, 0x53, 0xce, 0x1d, 0x60, 0x88, 0xa5, 0x0b, 0xde, 0xf5, 0x01, 0x3a, 0x20, 0xfa, 0xd6, 0x08, 0xdf, 0x83, 0x39, - 0x2e, 0xb8, 0x3a, 0x91, 0xec, 0x39, 0x47, 0xaa, 0x66, 0x8a, 0xb4, 0x35, 0x70, 0xaf, 0x88, 0x24, 0xb2, 0xc3, 0xdc, 0x7c, - 0xd0, 0x8f, 0x93, 0x0d, 0xa4, 0x53, 0xf1, 0x55, 0x92, 0xae, 0xd9, 0xeb, 0x31, 0xa0, 0x68, 0x29, 0xf5, 0xdb, 0x2f, 0xd1, - 0xa3, 0xfe, 0x34, 0x2f, 0xcd, 0x64, 0x0c, 0x11, 0x13, 0x14, 0x50, 0xeb, 0x27, 0x56, 0xda, 0xc0, 0x30, 0x3a, 0x8c, 0x92, - 0xb3, 0xb8, 0xc8, 0xb7, 0x19, 0xea, 0x4c, 0x74, 0xb9, 0x95, 0x46, 0x9f, 0xc0, 0x63, 0xfd, 0x72, 0x35, 0x0b, 0xb9, 0x1d, - 0x1e, 0x85, 0xf8, 0xf9, 0x23, 0xf7, 0x42, 0xe2, 0xf4, 0x67, 0xbf, 0x3d, 0x30, 0x4b, 0x6a, 0xf2, 0x44, 0x2f, 0xcb, 0x6f, - 0xe9, 0x73, 0x4b, 0x8f, 0x09, 0x29, 0x69, 0xcd, 0x8d, 0xcd, 0xc7, 0xd4, 0xa2, 0x0c, 0x6a, 0xc4, 0x9a, 0x33, 0xe2, 0x64, - 0x5f, 0x07, 0xf2, 0xb6, 0xf8, 0x86, 0x7f, 0x05, 0x04, 0xf1, 0x1d, 0x9d, 0xd1, 0xc8, 0x3c, 0x16, 0x6e, 0x18, 0x96, 0x15, - 0x33, 0xda, 0x84, 0xb6, 0xfd, 0x13, 0x29, 0x2f, 0x5e, 0xa0, 0x0e, 0xaa, 0xf6, 0x24, 0xb4, 0xa5, 0x48, 0x01, 0x02, 0x07, - 0x31, 0x98, 0x0d, 0x9c, 0x65, 0x59, 0x68, 0x61, 0x22, 0xdb, 0x64, 0x16, 0x05, 0xae, 0xd8, 0x64, 0x5f, 0xba, 0x51, 0xab, - 0x5e, 0xe0, 0xbe, 0x3d, 0x29, 0x67, 0x20, 0x94, 0x63, 0xfe, 0xc7, 0x90, 0x30, 0xc9, 0x43, 0xf1, 0xce, 0x9c, 0x53, 0x01, - 0x2c, 0x64, 0x56, 0x85, 0xb7, 0x3b, 0xa4, 0x05, 0x5d, 0x88, 0xdf, 0x44, 0xda, 0x18, 0xf3, 0x8c, 0xdb, 0xae, 0xd2, 0x9f, - 0xee, 0x4e, 0x08, 0x17, 0xf9, 0xd8, 0xe0, 0xc9, 0x7d, 0xa5, 0xad, 0x79, 0x06, 0x1b, 0x8c, 0x92, 0xe7, 0x53, 0xdf, 0xde, - 0xa3, 0xa5, 0x84, 0x1d, 0xd8, 0x75, 0x35, 0x78, 0x32, 0x55, 0x6f, 0x4f, 0x29, 0x34, 0x4e, 0x6f, 0x32, 0x16, 0xe4, 0xfd, - 0xbc, 0xf5, 0x76, 0x99, 0xf3, 0x48, 0x5b, 0xa0, 0x65, 0xb2, 0xef, 0xeb, 0x58, 0x6c, 0xf4, 0x1e, 0x97, 0x34, 0xee, 0xf9, - 0x74, 0xe2, 0x94, 0xc0, 0xf2, 0xf5, 0x0b, 0x97, 0x40, 0xce, 0x25, 0xd6, 0xe5, 0xdf, 0x0b, 0x3b, 0x6b, 0xf3, 0x38, 0x28, - 0xc3, 0xa6, 0x30, 0xa5, 0x22, 0x3c, 0xb0, 0xbd, 0x4d, 0xd5, 0x79, 0x25, 0xb9, 0xb2, 0xb4, 0xc4, 0x31, 0x62, 0x0b, 0xe7, - 0x73, 0x4e, 0xf9, 0xa7, 0x57, 0xdf, 0x33, 0x0e, 0xf0, 0xb9, 0x3b, 0x6d, 0xff, 0x6b, 0x11, 0xb0, 0x90, 0x10, 0x2a, 0x7b, - 0xb5, 0x0b, 0x41, 0x17, 0x0b, 0x12, 0xc7, 0x61, 0xef, 0xb1, 0x9b, 0x57, 0x3a, 0x01, 0x55, 0x91, 0xe3, 0xd5, 0xc8, 0xd5, - 0xeb, 0x26, 0x90, 0x2b, 0x67, 0x5b, 0xc2, 0x0b, 0xad, 0x6f, 0x26, 0x3a, 0xf5, 0x45, 0xb2, 0xd7, 0x6a, 0x78, 0xaa, 0x43, - 0xd0, 0xdb, 0x53, 0x6f, 0x1a, 0x7a, 0x5c, 0x92, 0xe1, 0xb7, 0xe5, 0xad, 0xda, 0xac, 0x3b, 0x5a, 0x20, 0x06, 0xe1, 0x56, - 0xf0, 0x55, 0x66, 0x64, 0x42, 0xd4, 0xe4, 0x77, 0x3b, 0xa5, 0x60, 0x8d, 0x5b, 0x24, 0x7a, 0x2a, 0xb9, 0xe2, 0x2f, 0xc6, - 0x02, 0xd1, 0x21, 0xf3, 0x08, 0xbd, 0x7b, 0xf4, 0x44, 0x47, 0x00, 0xd2, 0xca, 0x3c, 0x80, 0x37, 0xb0, 0xf2, 0x3d, 0x07, - 0x87, 0xbd, 0xe8, 0x59, 0x01, 0x17, 0x7b, 0xb3, 0x1b, 0xc3, 0xce, 0x45, 0x77, 0x3c, 0x0e, 0xdd, 0xac, 0x38, 0xf1, 0x5e, - 0xde, 0x5e, 0xdd, 0xad, 0xf2, 0xc9, 0x0f, 0xed, 0xec, 0xe5, 0x00, 0x8b, 0x61, 0xf4, 0x62, 0xd5, 0x58, 0x37, 0xec, 0xbf, - 0x36, 0xcf, 0x7a, 0x6a, 0x55, 0x1f, 0x25, 0x53, 0xba, 0xcd, 0x76, 0xc3, 0x07, 0x5e, 0x12, 0xf0, 0xc3, 0x82, 0x52, 0x5f, - 0xc6, 0x24, 0x54, 0x76, 0x49, 0xa3, 0xf1, 0xdd, 0x67, 0x29, 0x81, 0x19, 0x5f, 0x7b, 0xcd, 0xc6, 0x60, 0x3e, 0x80, 0x02, - 0xb3, 0xd9, 0xb6, 0x9d, 0x29, 0x59, 0xdc, 0x79, 0x90, 0xab, 0x53, 0xf4, 0xe6, 0x23, 0xb4, 0x77, 0x0f, 0xc8, 0xf2, 0x88, - 0xb3, 0x1c, 0x70, 0xb4, 0xeb, 0xa8, 0xdf, 0x25, 0x5b, 0x94, 0xa6, 0xce, 0x80, 0xbd, 0x46, 0xe6, 0x26, 0x8c, 0x4f, 0xee, - 0x37, 0x81, 0x84, 0xc6, 0xff, 0x0a, 0x37, 0x2e, 0xa4, 0xcb, 0xdf, 0x62, 0x81, 0x79, 0x3b, 0xa2, 0xdb, 0x07, 0x14, 0x0c, - 0xf7, 0x44, 0x1e, 0xda, 0xe0, 0x6c, 0x1a, 0xb6, 0x52, 0x7f, 0xd8, 0xce, 0xe7, 0x29, 0x98, 0xc1, 0x69, 0x40, 0xb9, 0x2a, - 0xe7, 0xb4, 0xee, 0x04, 0x67, 0xf7, 0x54, 0xac, 0x94, 0x12, 0x5c, 0x67, 0xb4, 0x51, 0x9c, 0xf6, 0xfa, 0x9b, 0x10, 0xd3, - 0x7e, 0xce, 0x78, 0xd5, 0x88, 0x80, 0xd7, 0x88, 0xea, 0x16, 0x51, 0x0c, 0xc9, 0xf2, 0x55, 0xda, 0xbd, 0x22, 0x34, 0x1a, - 0x65, 0x8f, 0xd7, 0x52, 0x00, 0x98, 0xc3, 0x76, 0xff, 0x3e, 0xfc, 0x44, 0x4b, 0x7e, 0xc2, 0x40, 0x00, 0x94, 0xf3, 0xc6, - 0xd5, 0xa3, 0x0f, 0x95, 0x9a, 0x96, 0xbb, 0x50, 0xcd, 0xd0, 0x6f, 0x75, 0xd7, 0xcc, 0x89, 0xb4, 0xc2, 0x85, 0x7f, 0x5f, - 0x06, 0xc1, 0xdf, 0x3c, 0xdd, 0x32, 0xdb, 0x44, 0xae, 0x1e, 0xd8, 0x56, 0xde, 0x93, 0xb0, 0xbd, 0xed, 0x8c, 0xb6, 0xcc, - 0x15, 0xe7, 0x81, 0x98, 0x36, 0x36, 0xd6, 0x91, 0x61, 0xd8, 0x65, 0x57, 0x5d, 0xcd, 0xbf, 0xf1, 0x3b, 0x31, 0xb6, 0xdd, - 0x6e, 0xc6, 0xd3, 0x1b, 0xc9, 0x47, 0x8c, 0x09, 0x03, 0x81, 0x7d, 0xbd, 0x64, 0xa9, 0x09, 0x66, 0x81, 0x2d, 0x56, 0x43, - 0xe8, 0x3c, 0x3e, 0xaa, 0xf8, 0x28, 0x92, 0x13, 0xea, 0x1f, 0xc1, 0x81, 0x4f, 0xb1, 0x1e, 0x88, 0xd2, 0x47, 0xdb, 0xb4, - 0x7e, 0xcb, 0xac, 0xc4, 0xbc, 0x07, 0x68, 0x83, 0x7d, 0xd2, 0x90, 0x90, 0x01, 0xa7, 0x0b, 0xac, 0x60, 0x67, 0x0f, 0xf4, - 0x1b, 0x2c, 0x1e, 0x93, 0x93, 0x6a, 0x16, 0x63, 0x78, 0x36, 0x7d, 0xc5, 0xa5, 0x04, 0xf4, 0x96, 0x1d, 0xae, 0x1a, 0xdf, - 0x1d, 0xba, 0xfc, 0x00, 0x21, 0x07, 0x8c, 0xa7, 0x9d, 0x00, 0x60, 0xb7, 0xa4, 0x05, 0xdd, 0xcd, 0x05, 0xee, 0x70, 0x5e, - 0xc5, 0x79, 0x6c, 0xc1, 0x22, 0x57, 0xfb, 0x5a, 0x25, 0x3e, 0xb9, 0x37, 0x76, 0x61, 0xc2, 0x7d, 0x14, 0x3c, 0xd3, 0x3a, - 0x13, 0xb9, 0x33, 0x07, 0xf6, 0x53, 0xc9, 0x5b, 0xb9, 0x97, 0x03, 0xd0, 0x76, 0xb8, 0xd1, 0xf1, 0x43, 0x9d, 0x7f, 0x37, - 0x46, 0x1a, 0xda, 0xdf, 0xd7, 0x4a, 0xb7, 0x79, 0x84, 0x9e, 0x47, 0x73, 0xac, 0x26, 0xf7, 0xd7, 0x54, 0x16, 0xad, 0x49, - 0x5e, 0x5d, 0x77, 0x61, 0x79, 0xdd, 0x52, 0x13, 0x2f, 0x20, 0xce, 0x26, 0x35, 0xa3, 0x60, 0x28, 0x3f, 0xc5, 0x67, 0xce, - 0x43, 0xa0, 0x86, 0x28, 0xf7, 0xa6, 0xf9, 0x6a, 0xbf, 0x25, 0x41, 0xb7, 0x7d, 0xbc, 0x04, 0x02, 0xd1, 0xe5, 0xed, 0x74, - 0xf5, 0xf5, 0x39, 0xf5, 0x18, 0x42, 0x9f, 0xdc, 0xaf, 0x46, 0xb6, 0x55, 0x48, 0x72, 0xa6, 0x66, 0x94, 0xef, 0x4a, 0x45, - 0x92, 0xf8, 0x31, 0x7a, 0x19, 0x69, 0xcb, 0xcf, 0xf3, 0x10, 0x4a, 0x65, 0x53, 0x18, 0xf4, 0x7f, 0x47, 0xe8, 0xe5, 0x07, - 0xb1, 0x8b, 0x3c, 0x3b, 0xb1, 0x1f, 0xdb, 0xb8, 0x5d, 0x53, 0xcb, 0xad, 0xf7, 0x38, 0x91, 0x8a, 0x1e, 0xa6, 0x76, 0x05, - 0x48, 0x89, 0xcc, 0xff, 0x51, 0x59, 0x53, 0xe9, 0xd7, 0x6e, 0x1a, 0x6e, 0xad, 0xf2, 0xcb, 0xf5, 0xfd, 0x48, 0xbe, 0xa8, - 0x70, 0xae, 0x5e, 0xc1, 0x7e, 0x1e, 0x07, 0x8e, 0x64, 0x0d, 0x70, 0xb7, 0x92, 0xda, 0x6f, 0x45, 0xb0, 0xe3, 0x8a, 0x30, - 0xbc, 0x45, 0xd1, 0x65, 0xf2, 0xb7, 0xab, 0x4e, 0x16, 0x5c, 0xa2, 0xb2, 0x9a, 0x4d, 0x2f, 0x76, 0x26, 0x62, 0x92, 0x7a, - 0x3c, 0x47, 0xf6, 0x87, 0x04, 0x0f, 0x7b, 0xda, 0x4b, 0x02, 0x6b, 0xd6, 0x16, 0x79, 0xbd, 0x16, 0x24, 0x42, 0x7a, 0xf4, - 0x44, 0x58, 0xb4, 0x68, 0x71, 0xce, 0xb3, 0x28, 0xba, 0x84, 0x6c, 0x26, 0x82, 0x1e, 0xba, 0x19, 0x83, 0xb7, 0x75, 0x1b, - 0xde, 0x09, 0xf6, 0x1b, 0x4f, 0x31, 0x65, 0xae, 0xb6, 0x45, 0xc2, 0xa7, 0x35, 0x2d, 0x9f, 0x14, 0x10, 0xe0, 0x3e, 0x43, - 0xa7, 0x82, 0x01, 0x06, 0x95, 0x2c, 0x19, 0x43, 0x8c, 0x94, 0xd4, 0x8c, 0x85, 0x6d, 0x88, 0x33, 0xff, 0x19, 0x51, 0xd3, - 0x7c, 0xf2, 0xa7, 0x5b, 0x05, 0xd1, 0x2b, 0x56, 0x18, 0x5e, 0xa6, 0xb9, 0x66, 0x3c, 0xf7, 0x4d, 0xbd, 0xa9, 0x95, 0x75, - 0xa9, 0xa1, 0x87, 0x24, 0x87, 0xf0, 0x60, 0xbb, 0x39, 0xec, 0xd1, 0xe5, 0x67, 0x51, 0x76, 0x99, 0xbc, 0x64, 0x7b, 0x5a, - 0xd5, 0xa6, 0x54, 0x4f, 0x16, 0x10, 0xb2, 0xe9, 0x43, 0x1c, 0x3a, 0x4c, 0x88, 0x51, 0xf4, 0xc2, 0x95, 0x16, 0x8e, 0xbf, - 0x79, 0x19, 0x22, 0x95, 0xd1, 0x76, 0x99, 0xb8, 0x68, 0xf3, 0x6a, 0x1a, 0x4e, 0x43, 0xf8, 0x9c, 0x6b, 0x75, 0x8c, 0xa5, - 0xbd, 0x65, 0x3a, 0x83, 0x0b, 0x47, 0xcf, 0x08, 0xf7, 0x22, 0x86, 0xad, 0xd5, 0x89, 0xd0, 0x6f, 0x4e, 0xbe, 0x2a, 0x81, - 0x1d, 0x1c, 0xf1, 0xc8, 0xf3, 0x18, 0x44, 0x40, 0xf3, 0x99, 0xfd, 0x18, 0xe3, 0x1a, 0xc9, 0x7f, 0x3b, 0x93, 0x68, 0x84, - 0xe2, 0x49, 0xb9, 0xcf, 0x00, 0x5c, 0x76, 0xc4, 0xcc, 0x4b, 0x7e, 0x86, 0x7e, 0x3f, 0x4b, 0x23, 0x61, 0x92, 0x7c, 0xcb, - 0x0c, 0x0c, 0x3e, 0x97, 0x34, 0xcc, 0xfd, 0x34, 0xa9, 0xcc, 0xf0, 0x83, 0xb1, 0xbc, 0x50, 0x4c, 0x84, 0x6f, 0xba, 0x68, - 0x01, 0x4f, 0x71, 0x57, 0x05, 0x7f, 0x01, 0xe2, 0x18, 0x23, 0xe9, 0x44, 0xa8, 0x4d, 0x93, 0x11, 0xee, 0xc0, 0x79, 0x5a, - 0x94, 0x13, 0x81, 0xf4, 0x67, 0xa0, 0x50, 0x79, 0x83, 0xa1, 0x13, 0x5f, 0x0e, 0x82, 0x9a, 0x72, 0x90, 0xba, 0x43, 0x21, - 0x28, 0xa9, 0x65, 0x1c, 0x16, 0x97, 0x6f, 0xdb, 0xc3, 0x1e, 0x23, 0xc5, 0x4a, 0xdb, 0x3b, 0x3c, 0x42, 0x4a, 0xc4, 0xb5, - 0x7f, 0x6b, 0x5d, 0xfc, 0x09, 0x08, 0x43, 0x2f, 0xf8, 0x11, 0x27, 0x6f, 0x1d, 0xc0, 0x12, 0x59, 0x04, 0xa4, 0x5b, 0xe9, - 0x9f, 0x25, 0xd1, 0x58, 0x3a, 0x1f, 0xac, 0x05, 0x15, 0x18, 0xea, 0xbd, 0x4b, 0xd2, 0xba, 0x67, 0xf3, 0x1d, 0x89, 0x09, - 0x52, 0xe5, 0x0e, 0x15, 0xd6, 0x5b, 0x87, 0xf5, 0xc3, 0x3c, 0x98, 0xbc, 0x46, 0x4e, 0x19, 0x8d, 0xbb, 0x3e, 0xe0, 0xde, - 0x19, 0x59, 0x53, 0x32, 0x62, 0x31, 0x16, 0xd4, 0xea, 0x63, 0xda, 0xf4, 0xcc, 0x94, 0xd0, 0x18, 0x98, 0xbc, 0x00, 0xd3, - 0x6c, 0xe2, 0xa5, 0xac, 0x30, 0x08, 0x9d, 0x68, 0x82, 0x8e, 0xbb, 0xdf, 0x9a, 0xa1, 0x13, 0xa5, 0x98, 0x18, 0xa9, 0x11, - 0xde, 0x49, 0x18, 0x88, 0xab, 0xff, 0xc6, 0x2c, 0xa8, 0xe1, 0xf7, 0x49, 0xba, 0x17, 0x93, 0x1c, 0x6c, 0x7f, 0x2c, 0xa9, - 0x3a, 0xee, 0x77, 0x9d, 0x46, 0x0c, 0xf9, 0x1c, 0x24, 0x33, 0x6f, 0x9b, 0xf8, 0x47, 0x9d, 0xc9, 0x7f, 0x9c, 0x80, 0xa0, - 0x2c, 0x96, 0x63, 0xe1, 0x97, 0x75, 0x75, 0x1f, 0xb3, 0xc6, 0x0d, 0xa9, 0x49, 0x82, 0x66, 0x86, 0x13, 0xa4, 0x62, 0x4c, - 0x56, 0x89, 0x73, 0x03, 0x1b, 0x61, 0xff, 0xfa, 0x0f, 0xf4, 0x84, 0xe3, 0xad, 0x89, 0xc0, 0x8e, 0x03, 0x91, 0x1c, 0x99, - 0x9f, 0x99, 0x92, 0x7e, 0xb5, 0xd8, 0xe3, 0xee, 0x6c, 0x21, 0x27, 0x5d, 0xa2, 0xa5, 0x90, 0xf2, 0x67, 0xed, 0xf3, 0xca, - 0x51, 0x56, 0x28, 0x7d, 0xa9, 0xd0, 0x4a, 0x4b, 0x76, 0x2b, 0xa8, 0x95, 0x8a, 0x37, 0xb4, 0x72, 0x96, 0xb2, 0xa0, 0xbe, - 0x90, 0x4f, 0x4e, 0x37, 0xbb, 0x14, 0xf8, 0xd2, 0x76, 0x7c, 0x79, 0xf3, 0xd2, 0xbf, 0x35, 0xad, 0x64, 0xbc, 0x98, 0x73, - 0xe5, 0xb9, 0xb3, 0xa2, 0x9b, 0x54, 0x17, 0x9b, 0x99, 0xa1, 0xeb, 0xfd, 0xc2, 0x8b, 0xbd, 0xac, 0x6d, 0x14, 0x35, 0xc2, - 0x3b, 0xc9, 0x88, 0x57, 0x64, 0xaa, 0x52, 0x3d, 0xf1, 0x80, 0x9c, 0xb2, 0xfc, 0xe9, 0x53, 0x7c, 0x12, 0x81, 0xe6, 0x07, - 0xa1, 0x0b, 0x2b, 0xb3, 0x88, 0xa6, 0x07, 0xb8, 0x10, 0x7e, 0xc4, 0x55, 0x14, 0xa2, 0x66, 0xf1, 0xcc, 0xff, 0x49, 0x84, - 0xbc, 0x54, 0x15, 0x41, 0x26, 0x15, 0x44, 0xf1, 0xe4, 0x4e, 0x8a, 0xf4, 0x02, 0xb1, 0x87, 0x51, 0xa7, 0xa4, 0xe6, 0x4f, - 0xbb, 0xff, 0xfe, 0x94, 0x51, 0x54, 0x20, 0x7e, 0x16, 0x60, 0x23, 0xfe, 0x05, 0x8c, 0x1a, 0xe1, 0x12, 0x7c, 0xd4, 0xc0, - 0xae, 0x3a, 0x96, 0x13, 0x5d, 0x83, 0x89, 0x49, 0x99, 0x2c, 0x3e, 0x19, 0x8b, 0xa8, 0xf0, 0x0d, 0x65, 0x5d, 0x35, 0x37, - 0xa1, 0x2d, 0xdd, 0xe2, 0x6b, 0x0d, 0xa9, 0x47, 0x9e, 0xf0, 0x22, 0xb5, 0x8e, 0xab, 0xc1, 0x34, 0x93, 0x4c, 0xff, 0x89, - 0x9b, 0x24, 0xd4, 0x01, 0x24, 0xbc, 0xf5, 0x42, 0xd8, 0xee, 0xc2, 0xbc, 0x78, 0x03, 0xc1, 0x24, 0xa8, 0x88, 0xba, 0x3f, - 0x71, 0x58, 0x3d, 0xdd, 0xef, 0xa8, 0xf8, 0x15, 0x4c, 0xb0, 0x68, 0x7c, 0xbc, 0x41, 0x66, 0x72, 0xc4, 0x4d, 0x9f, 0xd0, - 0xdb, 0x9a, 0xd0, 0x65, 0xde, 0xf1, 0x25, 0x02, 0x35, 0xff, 0x49, 0x4a, 0xd8, 0xa4, 0x19, 0x49, 0xb4, 0x51, 0xda, 0x4b, - 0x75, 0x81, 0x17, 0xa7, 0x84, 0x80, 0x70, 0x3f, 0xc7, 0x0d, 0xb2, 0x79, 0x24, 0x25, 0x7c, 0xe2, 0x30, 0x67, 0x15, 0x00, - 0x80, 0x68, 0x1e, 0xde, 0xf0, 0x3e, 0xda, 0xc6, 0x31, 0x4d, 0xa7, 0xf0, 0x53, 0x0d, 0x88, 0x08, 0xe1, 0xd8, 0xe2, 0x8b, - 0x01, 0xdb, 0x9f, 0x5b, 0x7c, 0xd4, 0x68, 0x89, 0xb1, 0xeb, 0xdb, 0x4e, 0x6f, 0xac, 0x21, 0xad, 0xf2, 0xed, 0x6f, 0x61, - 0x4d, 0x1f, 0x2f, 0x64, 0x0b, 0xdb, 0x07, 0x54, 0x65, 0xd7, 0xf0, 0xf8, 0x40, 0xdb, 0xd9, 0x5e, 0x2d, 0xaf, 0x4f, 0x14, - 0x9f, 0x5b, 0x0b, 0x74, 0x4e, 0xad, 0x07, 0x60, 0xac, 0x24, 0x04, 0x5b, 0xc8, 0xf4, 0xc9, 0x6f, 0x28, 0xb0, 0x2b, 0xb3, - 0xd9, 0x43, 0xf1, 0x55, 0xc9, 0x25, 0x01, 0xb7, 0xab, 0x8f, 0xd8, 0x0f, 0x78, 0x6a, 0xbf, 0xa0, 0x4e, 0x80, 0x22, 0xc6, - 0x8a, 0x42, 0x37, 0x6d, 0x3a, 0xbd, 0xf3, 0x66, 0xbe, 0x84, 0x87, 0xf6, 0xa1, 0xa0, 0x99, 0x7f, 0x13, 0x66, 0x40, 0x39, - 0xce, 0x43, 0x8f, 0xe5, 0x83, 0x48, 0x94, 0xc6, 0x59, 0xc2, 0xce, 0x55, 0x35, 0x44, 0x74, 0xa6, 0x37, 0x0c, 0x3c, 0x69, - 0xdc, 0xdb, 0x2b, 0x3a, 0xd8, 0x32, 0x4d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x01, 0xae, 0x1a, 0x61, 0x75, 0xae, 0x23, 0xd9, 0x11, 0x5c, 0x28, 0x93, 0xa9, 0xe2, - 0x49, 0x5e, 0x74, 0x28, 0x4c, 0x08, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, - 0x00, 0x04, 0x14, 0x3d, 0xc6, 0xb0, 0x07, 0xf5, 0xd4, 0xa7, 0x42, 0x90, 0xa1, 0x2f, 0x4d, 0x1e, 0x43, 0x09, 0x7d, 0xd5, - 0xfe, 0x15, 0xb1, 0x04, 0x08, 0xdd, 0xee, 0x2c, 0x8a, 0x3d, 0x65, 0x41, 0x94, 0x02, 0x02, 0x08, 0x00 -}; +#include "si-cms-signing-identity-p12.h" unsigned char _V2_valid_message[] = { 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, @@ -1013,5 +760,4 @@ unsigned char _V2_valid_message[] = { 0xe0, 0xfd, 0xc4, 0x8e, 0x51, 0x2e, 0x2e, 0x45, 0x18, 0x5e, 0x87, 0x33, 0xbb, 0x26, 0x71, 0x3f, 0xad, 0x79, 0xc5, 0x60, 0x9c, 0xda, 0xc3, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - -#endif /* si_89_cms_hash_agility_h */ +size_t _V2_valid_message_size = sizeof(_V2_valid_message); diff --git a/OSX/sec/Security/Regressions/secitem/si-cms-hash-agility-data.h b/OSX/sec/Security/Regressions/secitem/si-cms-hash-agility-data.h new file mode 100644 index 00000000..c6bee7fa --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-cms-hash-agility-data.h @@ -0,0 +1,36 @@ +#ifndef si_cms_hash_agility_data_h +#define si_cms_hash_agility_data_h + +#include +#include + +/* Random data for content */ +extern unsigned char content[1024]; +extern size_t content_size; + +/* Random data for hash agility attribute */ +extern unsigned char attribute[32]; + +/* Random data for hash agility V2 attribute */ +extern unsigned char _attributev2[64]; + +/* Valid CMS message on content with hash agility attribute */ +extern uint8_t valid_message[]; +extern size_t valid_message_size; +/* + * Invalid CMS message on content with hash agility attribute. + * Only the hash agility attribute value has been changed from the valid message. + */ +extern uint8_t invalid_message[]; +extern size_t invalid_message_size; + +/* Valid CMS message with no hash agility attribute */ +extern unsigned char valid_no_attr[]; +extern size_t valid_no_attr_size; + +#include "si-cms-signing-identity-p12.h" + +extern unsigned char _V2_valid_message[]; +extern size_t _V2_valid_message_size; + +#endif /* si_cms_hash_agility_data_h */ diff --git a/OSX/sec/Security/Regressions/secitem/si-cms-signing-identity-p12.c b/OSX/sec/Security/Regressions/secitem/si-cms-signing-identity-p12.c new file mode 100644 index 00000000..6560a79a --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-cms-signing-identity-p12.c @@ -0,0 +1,234 @@ +#include "si-cms-signing-identity-p12.h" + +/* + * password: "password" + * localKeyID: 01 AE 1A 61 75 AE 23 D9 11 5C 28 93 A9 E2 49 5E 74 28 4C 08 + * subject=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer + * issuer=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer + */ +unsigned char signing_identity_p12[4477] = { + 0x30, 0x82, 0x11, 0x79, 0x02, 0x01, 0x03, 0x30, 0x82, 0x11, 0x3f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x07, 0x01, 0xa0, 0x82, 0x11, 0x30, 0x04, 0x82, 0x11, 0x2c, 0x30, 0x82, 0x11, 0x28, 0x30, 0x82, 0x07, 0x57, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x07, 0x48, 0x30, 0x82, 0x07, 0x44, 0x02, 0x01, 0x00, + 0x30, 0x82, 0x07, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xed, 0xd8, 0x65, 0x57, 0xbb, 0xca, 0x25, + 0x46, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x07, 0x10, 0xc0, 0x1d, 0x0d, 0x5c, 0x7f, 0x3b, 0xbe, 0x20, 0xd4, 0x9a, 0x0d, + 0xaf, 0xb6, 0x4b, 0xc7, 0x7f, 0xa8, 0xa8, 0x3f, 0x6c, 0x96, 0x1c, 0xea, 0x90, 0xd2, 0x79, 0x9f, 0x56, 0x3a, 0x5a, 0x29, + 0x93, 0xff, 0x72, 0x39, 0x9e, 0x41, 0xd9, 0x5a, 0xfc, 0xb5, 0x54, 0x2d, 0x89, 0x60, 0x18, 0xf2, 0xea, 0x8c, 0xeb, 0x7f, + 0xba, 0x87, 0xc6, 0x70, 0x42, 0x25, 0x55, 0x24, 0xc5, 0x4f, 0x26, 0x66, 0x8d, 0x78, 0x44, 0x47, 0x85, 0x36, 0x53, 0x86, + 0xc9, 0x18, 0x83, 0x33, 0x4b, 0x4b, 0x08, 0x2d, 0x7b, 0x68, 0x37, 0x29, 0x4c, 0x20, 0x74, 0xd4, 0x4f, 0xbb, 0x6e, 0x97, + 0x7a, 0xf4, 0xbf, 0xcb, 0x40, 0x26, 0x2d, 0xac, 0x95, 0x82, 0xe0, 0x88, 0xfe, 0x54, 0x80, 0xe9, 0xf5, 0xda, 0x8e, 0x6e, + 0x3a, 0x47, 0x2d, 0xc8, 0xd4, 0xe7, 0x2e, 0xff, 0xec, 0xfa, 0xa5, 0x70, 0xcd, 0x2e, 0x99, 0x26, 0x32, 0xc8, 0x1d, 0x53, + 0x60, 0x1e, 0x6f, 0x68, 0xcb, 0x49, 0xd0, 0xa2, 0xf8, 0x47, 0x70, 0x1b, 0x9e, 0x85, 0xbe, 0x4e, 0x56, 0xb5, 0x8b, 0x66, + 0x45, 0x57, 0xe3, 0xbd, 0x57, 0xed, 0x94, 0x53, 0xf6, 0x72, 0xd7, 0xb7, 0xc6, 0x9f, 0x05, 0xf5, 0x98, 0xb4, 0x13, 0x35, + 0x69, 0x24, 0x94, 0xd9, 0x3d, 0x80, 0xbc, 0xa8, 0xea, 0x78, 0x0c, 0xe0, 0xa2, 0xfe, 0x1b, 0xd2, 0x82, 0x3d, 0x83, 0x34, + 0x76, 0xb4, 0x45, 0xf8, 0x14, 0x09, 0x66, 0x02, 0x68, 0xc3, 0x1b, 0xcb, 0x6c, 0x91, 0x6b, 0x3e, 0xdc, 0x35, 0x68, 0xab, + 0x49, 0x47, 0x6c, 0x60, 0xea, 0xe3, 0xd5, 0x59, 0x82, 0x9c, 0x18, 0xb0, 0x6d, 0x45, 0xc0, 0x2f, 0x58, 0xf1, 0x44, 0x79, + 0xe3, 0xd2, 0xd6, 0x16, 0xbc, 0xde, 0x17, 0xae, 0xf7, 0xea, 0x3c, 0xe4, 0xb4, 0x7b, 0xdf, 0xba, 0x9b, 0xf1, 0xb8, 0xa8, + 0xb0, 0x51, 0xeb, 0xe8, 0xc3, 0xe9, 0x9c, 0x1b, 0x06, 0xdd, 0x89, 0x07, 0x98, 0xf8, 0x01, 0x7f, 0xde, 0x7e, 0x05, 0xa6, + 0x72, 0x0b, 0x3f, 0xf4, 0x7d, 0xca, 0x74, 0x7b, 0xc9, 0x87, 0x0d, 0x35, 0x8b, 0x05, 0x3a, 0x73, 0x04, 0x08, 0x7a, 0x51, + 0x34, 0x29, 0x5b, 0xd8, 0x90, 0x0f, 0xa7, 0xf0, 0x48, 0xfc, 0x9c, 0x74, 0xca, 0xe9, 0x34, 0x75, 0x1c, 0xd1, 0xa6, 0xd1, + 0xfb, 0x9f, 0xc7, 0x82, 0x40, 0x75, 0x87, 0xdd, 0xa2, 0x22, 0xeb, 0x91, 0xd7, 0x85, 0x1a, 0x2c, 0xa7, 0x3d, 0xd5, 0xe4, + 0xca, 0x85, 0x00, 0x33, 0x11, 0x6d, 0x62, 0xa8, 0xb7, 0xd3, 0x45, 0x46, 0xdc, 0xb4, 0xa3, 0xeb, 0xae, 0x5e, 0x8c, 0xc2, + 0x7a, 0x0b, 0x83, 0x98, 0x5a, 0x94, 0x0f, 0x68, 0x61, 0x36, 0x57, 0x6e, 0x94, 0xe0, 0x6d, 0x93, 0x76, 0xa0, 0x5d, 0x3f, + 0x25, 0x8b, 0x3b, 0x46, 0x1e, 0x0c, 0x15, 0x6b, 0x9f, 0x1d, 0xc3, 0x5f, 0x61, 0x42, 0xd5, 0xf8, 0x79, 0xcd, 0xd1, 0x0a, + 0x96, 0xce, 0x49, 0x8a, 0xff, 0x54, 0x46, 0x77, 0x65, 0x37, 0x70, 0xcd, 0x65, 0x6f, 0x3d, 0x49, 0xc1, 0x29, 0x8d, 0x16, + 0xbd, 0x36, 0x47, 0x54, 0xa5, 0x4d, 0x06, 0xfb, 0x33, 0x00, 0x29, 0xd8, 0x31, 0x09, 0x58, 0x12, 0x4c, 0xfe, 0xef, 0x8e, + 0xf9, 0x1e, 0x30, 0xf7, 0x05, 0xb2, 0xd8, 0xd4, 0x7d, 0xae, 0xab, 0x57, 0xb7, 0x46, 0x09, 0xff, 0xca, 0xc7, 0x7b, 0xca, + 0x73, 0xfa, 0xf9, 0x50, 0xa0, 0xb8, 0x09, 0xc2, 0x80, 0x43, 0x0d, 0x99, 0x7f, 0x4e, 0xdf, 0xd5, 0x6c, 0xc4, 0x42, 0x1a, + 0x05, 0xbd, 0x65, 0xf4, 0x57, 0x2a, 0xe5, 0xc4, 0xcb, 0x79, 0x3f, 0x8f, 0x74, 0x93, 0x66, 0x8d, 0x93, 0xda, 0xba, 0x23, + 0x77, 0x3f, 0xad, 0xd3, 0x8b, 0xae, 0xf5, 0xf1, 0x5c, 0xc1, 0xd2, 0x00, 0x3a, 0x60, 0x8e, 0xc3, 0x32, 0xd6, 0x8e, 0xce, + 0x95, 0x24, 0x03, 0x79, 0x03, 0xf2, 0xb8, 0x2a, 0x94, 0xeb, 0x15, 0x97, 0xdc, 0x18, 0x8d, 0xc7, 0xd9, 0xc2, 0x63, 0x69, + 0xfb, 0xf9, 0x8f, 0x05, 0xd3, 0x7c, 0x60, 0x5a, 0x57, 0xe4, 0xa5, 0xc1, 0xdf, 0x1d, 0x11, 0x84, 0x69, 0xba, 0x20, 0xd8, + 0x79, 0xc3, 0x34, 0x3a, 0xb1, 0x63, 0x4c, 0xd2, 0x91, 0x2d, 0x87, 0x1e, 0xec, 0x06, 0xea, 0x35, 0x97, 0x0e, 0x59, 0x54, + 0x83, 0x50, 0x3e, 0xac, 0xf2, 0xea, 0x6c, 0x0c, 0xa0, 0x57, 0xfb, 0xe8, 0x6b, 0xf9, 0xd1, 0x25, 0xc0, 0xa2, 0xb0, 0xa2, + 0xcd, 0xde, 0x2b, 0xa7, 0xb3, 0x40, 0x75, 0x36, 0xf7, 0x20, 0xbe, 0xd7, 0xd1, 0x2e, 0x66, 0xc5, 0x3c, 0xf8, 0x6e, 0xce, + 0xcb, 0x76, 0x7f, 0x1d, 0x32, 0x3b, 0x14, 0x27, 0x9c, 0x9e, 0xa3, 0xeb, 0x0c, 0x2f, 0x71, 0xba, 0x0d, 0xca, 0x27, 0x90, + 0x42, 0xfd, 0xd4, 0x34, 0xb9, 0x96, 0xae, 0xcb, 0xd8, 0xfe, 0x31, 0x62, 0xe8, 0x4c, 0x07, 0x71, 0xb9, 0x0c, 0x9f, 0xe2, + 0x8e, 0x66, 0xc2, 0x39, 0xc5, 0xc3, 0x1c, 0xfd, 0x5e, 0x18, 0x0b, 0xd4, 0x93, 0x3d, 0x98, 0x33, 0xaf, 0x6d, 0xb4, 0x6f, + 0xe6, 0x75, 0x67, 0x62, 0xe7, 0x42, 0xee, 0xc6, 0xf2, 0x2e, 0x21, 0xa9, 0x75, 0xde, 0x0a, 0x8c, 0x39, 0xb7, 0x4b, 0x54, + 0x01, 0xa7, 0xeb, 0x5a, 0x88, 0x79, 0xa8, 0xb3, 0x3f, 0x31, 0x8c, 0x47, 0x08, 0x94, 0x47, 0x52, 0xcf, 0x3c, 0xac, 0xd9, + 0x32, 0x57, 0x4a, 0x18, 0x55, 0x5b, 0x66, 0xdc, 0x89, 0xd2, 0xc6, 0xa1, 0x11, 0x40, 0x19, 0x9c, 0x46, 0x88, 0x21, 0x77, + 0xc1, 0x7f, 0x09, 0xc7, 0xfb, 0x52, 0x92, 0xec, 0x1a, 0xe0, 0xdd, 0x76, 0xb9, 0xfd, 0xa7, 0x8f, 0x61, 0xe3, 0xf0, 0x1b, + 0x4e, 0xdb, 0xa0, 0xde, 0x90, 0xd6, 0x49, 0xea, 0xe9, 0x86, 0xc6, 0x5d, 0xac, 0xd0, 0xc2, 0xc5, 0x01, 0xcb, 0x3f, 0xcb, + 0xf0, 0x62, 0x90, 0xa1, 0x17, 0x4b, 0x72, 0x5c, 0xc8, 0xe9, 0x24, 0x93, 0xda, 0x5c, 0x75, 0x24, 0x96, 0x35, 0x54, 0xf4, + 0xfa, 0xc8, 0x27, 0xe1, 0xdd, 0x32, 0xda, 0x2f, 0x2b, 0x7d, 0xf6, 0xd8, 0x0b, 0xf2, 0xca, 0xb5, 0xee, 0x8a, 0xcf, 0xb6, + 0x26, 0x71, 0x65, 0x85, 0xfe, 0x8c, 0x37, 0xf1, 0x17, 0x6b, 0x5e, 0x8a, 0xee, 0xb4, 0xc7, 0x0a, 0xff, 0xb2, 0x9a, 0x72, + 0xe5, 0x85, 0xf3, 0xc0, 0xf9, 0x84, 0xbc, 0xe0, 0x18, 0x3c, 0x12, 0x0c, 0xa1, 0xe9, 0x10, 0xd4, 0x3b, 0x1a, 0x21, 0x35, + 0xc6, 0x06, 0x93, 0xa0, 0xdf, 0x0d, 0x68, 0xa3, 0xf1, 0x06, 0xd9, 0xed, 0xb7, 0xa7, 0xba, 0xb0, 0x22, 0xc2, 0x0b, 0x6b, + 0x70, 0x50, 0xf5, 0x49, 0x9a, 0x4f, 0x99, 0xaa, 0x1e, 0x9c, 0xa6, 0xf3, 0x99, 0x3a, 0xfd, 0x3b, 0xd2, 0xeb, 0xce, 0x1e, + 0x72, 0x62, 0x99, 0xc0, 0x1e, 0x2b, 0x09, 0x75, 0x4a, 0xfb, 0xc8, 0x26, 0xcf, 0x76, 0xa2, 0x0e, 0xef, 0xf4, 0xa8, 0x70, + 0x31, 0xd8, 0xa1, 0x22, 0x62, 0xcc, 0x9f, 0xd5, 0xa3, 0x55, 0xc2, 0x78, 0xd7, 0x27, 0xfc, 0x3c, 0x53, 0xe8, 0xeb, 0x7e, + 0x7a, 0x27, 0xcf, 0x6d, 0x52, 0xb5, 0x9a, 0x2b, 0x49, 0x8d, 0x3f, 0x89, 0x80, 0x1a, 0x5c, 0x39, 0xe7, 0x53, 0xb3, 0xf3, + 0x33, 0x97, 0xcf, 0x7d, 0xfb, 0x8e, 0x19, 0xf4, 0x72, 0xeb, 0xe7, 0xdf, 0xb1, 0xe3, 0xc1, 0x6c, 0x7f, 0x17, 0x89, 0x34, + 0x4f, 0x45, 0x0f, 0xc5, 0xfc, 0x15, 0xb3, 0x3f, 0xc6, 0xdc, 0x25, 0xa6, 0xda, 0x28, 0x85, 0x5d, 0x25, 0x02, 0x78, 0x74, + 0xd9, 0x74, 0xb8, 0x65, 0x48, 0x3a, 0x8a, 0x2a, 0xd5, 0xa9, 0xb8, 0x7f, 0xaa, 0x9d, 0xe7, 0xaf, 0xbd, 0xdf, 0xfd, 0x00, + 0x67, 0xab, 0x39, 0xe1, 0x2c, 0x3d, 0xd1, 0x5c, 0x9b, 0x61, 0x2b, 0x51, 0xdc, 0x87, 0x19, 0x6c, 0xa0, 0x12, 0xd4, 0x60, + 0xed, 0x94, 0xe9, 0xeb, 0x4e, 0x51, 0xd8, 0x50, 0xcb, 0x97, 0x8a, 0x20, 0x21, 0xdf, 0xe9, 0x2c, 0xd2, 0xe2, 0x04, 0x14, + 0xaf, 0x7b, 0x7e, 0xd6, 0xeb, 0x1d, 0x25, 0x09, 0x98, 0x8e, 0x9e, 0x56, 0xf8, 0x7d, 0xfc, 0x0f, 0xbf, 0xd2, 0x6b, 0xbc, + 0xab, 0xed, 0xca, 0x43, 0x6d, 0x28, 0xbe, 0xd5, 0x20, 0x44, 0xcb, 0x6b, 0xbc, 0x80, 0x5a, 0x82, 0x13, 0x50, 0xbd, 0xda, + 0x18, 0x10, 0xac, 0xae, 0x56, 0xb9, 0x46, 0xc5, 0xa2, 0xca, 0xb2, 0x03, 0xf0, 0x57, 0xfe, 0xcd, 0x9a, 0x1b, 0x81, 0x6a, + 0x10, 0x51, 0x2e, 0x88, 0x30, 0x57, 0x3c, 0xfe, 0x7c, 0x56, 0x0c, 0x00, 0x89, 0x5c, 0x21, 0x57, 0x19, 0x96, 0x85, 0x98, + 0xeb, 0x43, 0x71, 0x0d, 0x8a, 0x35, 0xc3, 0xae, 0x36, 0x59, 0x72, 0x97, 0x12, 0x6d, 0xcd, 0x28, 0x64, 0x17, 0x9e, 0xe7, + 0x2c, 0x28, 0xfd, 0x32, 0xa8, 0x10, 0x67, 0x4e, 0xc0, 0x14, 0x21, 0x7c, 0x36, 0x20, 0xe9, 0x46, 0x68, 0x62, 0xc1, 0xff, + 0xb0, 0xdf, 0xaa, 0x87, 0xff, 0x94, 0xa4, 0xf3, 0xb3, 0xc8, 0x53, 0x57, 0x18, 0x92, 0x15, 0xc7, 0x78, 0x2d, 0x91, 0xba, + 0xb3, 0x1f, 0x06, 0x13, 0x79, 0x21, 0x86, 0x1d, 0xa2, 0x38, 0x2c, 0xda, 0x35, 0x31, 0xbb, 0x04, 0x65, 0xa3, 0x01, 0xa6, + 0x63, 0xa4, 0x4a, 0xa2, 0xc1, 0xad, 0x04, 0xc1, 0xfa, 0x78, 0xe1, 0xb6, 0x50, 0x46, 0xab, 0xad, 0x1c, 0xcf, 0xf4, 0xe5, + 0xba, 0xa5, 0xe2, 0x91, 0x29, 0x4b, 0xa1, 0xc6, 0x4b, 0x30, 0xa5, 0x31, 0x02, 0xe9, 0xd0, 0x50, 0x72, 0x2c, 0x8e, 0xbd, + 0xb2, 0x12, 0xd9, 0x4f, 0x7c, 0x87, 0x4b, 0xa0, 0x45, 0x71, 0x0c, 0x23, 0x37, 0x6b, 0x60, 0xd7, 0x9f, 0x19, 0xe8, 0x0b, + 0x85, 0x57, 0x72, 0xb6, 0xbb, 0x20, 0x23, 0xd3, 0x7d, 0x9a, 0x9b, 0x9a, 0x05, 0x46, 0x5c, 0xf5, 0x02, 0xf1, 0x56, 0x00, + 0xc2, 0x05, 0x85, 0x48, 0xd3, 0x8d, 0x8e, 0xe1, 0xcb, 0xc5, 0x83, 0x1f, 0x78, 0xd0, 0xc5, 0xb1, 0xdf, 0x80, 0x9d, 0x04, + 0xe7, 0xac, 0xd1, 0x68, 0x1a, 0x19, 0x18, 0x16, 0xfa, 0x3a, 0xe2, 0xd2, 0x30, 0x08, 0x17, 0x4d, 0x50, 0x2b, 0xd4, 0xa3, + 0xbe, 0x98, 0x5f, 0xe0, 0xcf, 0xed, 0x7d, 0x74, 0x94, 0xd1, 0xb2, 0x77, 0xbc, 0x72, 0xbc, 0xf5, 0xc7, 0x82, 0x26, 0x53, + 0x14, 0xcc, 0xf9, 0xf7, 0x71, 0xea, 0x97, 0xaa, 0xbf, 0x21, 0x46, 0x59, 0x2c, 0x9a, 0xc4, 0xeb, 0xa3, 0x4a, 0x97, 0x91, + 0x11, 0xf1, 0x01, 0x19, 0x7e, 0xb1, 0xb2, 0x63, 0x0d, 0xf0, 0x5d, 0xaf, 0x53, 0xdf, 0x4d, 0xa1, 0x90, 0xe5, 0x12, 0x82, + 0x33, 0x6f, 0x1d, 0x73, 0xdf, 0xdb, 0x1f, 0x18, 0xa0, 0x72, 0xc1, 0xd6, 0xa7, 0x4d, 0xb2, 0x3e, 0x24, 0xb7, 0xa7, 0x76, + 0x15, 0x46, 0x22, 0x48, 0x49, 0x55, 0xd1, 0xfb, 0x66, 0x32, 0x02, 0xa9, 0xfc, 0xbe, 0x7e, 0x16, 0xcf, 0xac, 0x32, 0xbc, + 0xdb, 0xd5, 0xd8, 0xa3, 0x23, 0x6a, 0x10, 0xa6, 0x37, 0x03, 0xf6, 0x2a, 0xde, 0xba, 0xde, 0x2d, 0x7d, 0xef, 0x1d, 0xb9, + 0xf3, 0x93, 0xd4, 0xf2, 0x13, 0xf4, 0x9c, 0x5a, 0x32, 0xba, 0x5f, 0xef, 0x7b, 0xd0, 0x6b, 0xd7, 0x91, 0x6d, 0x7b, 0xe1, + 0x4d, 0xf2, 0x8c, 0xe7, 0xf1, 0x66, 0xb9, 0xad, 0xc6, 0x30, 0x08, 0x9e, 0x51, 0xd4, 0x39, 0x87, 0x09, 0xfa, 0x6b, 0x7a, + 0xa7, 0x5f, 0x1a, 0x9c, 0x98, 0xc5, 0x76, 0xb0, 0x71, 0x76, 0xf5, 0xfc, 0x56, 0x88, 0x1c, 0xca, 0xee, 0x76, 0xd4, 0x2c, + 0xa6, 0x64, 0x80, 0x59, 0x12, 0x8c, 0x08, 0xce, 0x83, 0xb3, 0xd9, 0x68, 0x59, 0xc1, 0x26, 0x86, 0xa7, 0x80, 0x10, 0xbc, + 0x41, 0x28, 0x6c, 0x45, 0xd4, 0x6d, 0x15, 0xd0, 0x76, 0x44, 0x0e, 0xcf, 0xc1, 0xde, 0xef, 0x7a, 0x97, 0x36, 0x8f, 0x0d, + 0x8a, 0xf5, 0x45, 0xde, 0xae, 0x61, 0xd0, 0x55, 0xe9, 0x8d, 0x62, 0xfd, 0xa3, 0x0d, 0x44, 0x0f, 0x49, 0xb6, 0x5a, 0xa4, + 0xaa, 0x03, 0x4e, 0x60, 0x35, 0x53, 0x86, 0x9e, 0xec, 0x75, 0xd9, 0x0a, 0xca, 0x14, 0xe3, 0x1b, 0x06, 0x05, 0xd6, 0x8f, + 0x4f, 0x11, 0xb3, 0x13, 0xdd, 0x26, 0x35, 0xbd, 0x56, 0x55, 0xf1, 0x43, 0x89, 0x5e, 0x5b, 0x25, 0x4d, 0xa8, 0x09, 0xdd, + 0xf2, 0x6d, 0x9e, 0x8c, 0xcd, 0xa2, 0xde, 0x84, 0x00, 0x6a, 0x0a, 0xc6, 0x92, 0x30, 0x82, 0xcf, 0xa4, 0x31, 0x67, 0xbd, + 0xd4, 0x36, 0x6a, 0x8b, 0xc6, 0x33, 0xdf, 0x8b, 0xde, 0x33, 0x01, 0x7b, 0x9d, 0xbf, 0xe9, 0x12, 0x35, 0x8a, 0x97, 0x07, + 0x72, 0x0b, 0x6b, 0x60, 0xe6, 0x1e, 0x7d, 0x78, 0x22, 0x9f, 0xbf, 0x66, 0x8e, 0x02, 0xf4, 0xdc, 0xa1, 0xb0, 0x42, 0x73, + 0x86, 0xca, 0x34, 0xf0, 0xa7, 0x2e, 0x15, 0x84, 0xa4, 0x60, 0xa8, 0x47, 0x05, 0x80, 0x03, 0x27, 0xa8, 0x04, 0x03, 0xfe, + 0x47, 0xd4, 0xeb, 0x33, 0x27, 0xbf, 0x89, 0xff, 0x4c, 0xd9, 0x27, 0x0e, 0xd0, 0xa9, 0x41, 0x8b, 0xd5, 0x7c, 0xc4, 0x14, + 0x7a, 0x9c, 0xb3, 0xaa, 0x13, 0x32, 0xa4, 0x67, 0xd5, 0x95, 0xdc, 0x4a, 0x3d, 0xf2, 0x54, 0xd7, 0x02, 0xf8, 0x06, 0x7b, + 0x1d, 0x9a, 0xa4, 0x53, 0xa0, 0x9c, 0x76, 0x7d, 0xf4, 0x01, 0xa3, 0x4b, 0xb2, 0x8b, 0x44, 0x85, 0xf6, 0x80, 0x99, 0x2f, + 0x77, 0x08, 0x20, 0xea, 0x08, 0xf8, 0x14, 0x76, 0xfe, 0xa0, 0x5a, 0xf9, 0x1f, 0x87, 0x03, 0xff, 0x8d, 0x1f, 0x5d, 0x02, + 0x64, 0x8a, 0xf4, 0xa5, 0x8c, 0xb7, 0x0a, 0x34, 0x68, 0xaa, 0xca, 0xc8, 0xe1, 0x78, 0x9b, 0xd3, 0x6c, 0x5c, 0x07, 0x99, + 0xc1, 0x10, 0x3f, 0x77, 0x0c, 0x45, 0xa2, 0xda, 0xda, 0xab, 0x7c, 0xf0, 0x90, 0x12, 0xa2, 0x7c, 0x84, 0x30, 0x82, 0x09, + 0xc9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x09, 0xba, 0x04, 0x82, 0x09, 0xb6, + 0x30, 0x82, 0x09, 0xb2, 0x30, 0x82, 0x09, 0xae, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, + 0x02, 0xa0, 0x82, 0x09, 0x76, 0x30, 0x82, 0x09, 0x72, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0xd3, 0x5d, 0xa8, 0x14, 0xbc, 0x7a, 0xaa, 0x5f, 0x02, 0x02, 0x08, 0x00, 0x04, + 0x82, 0x09, 0x50, 0xaf, 0xe9, 0x63, 0xb6, 0x05, 0x8b, 0x48, 0xe1, 0x11, 0xd0, 0x37, 0x1d, 0x48, 0x71, 0x22, 0x70, 0xdc, + 0xbd, 0xca, 0x98, 0x5d, 0x72, 0xca, 0x38, 0xdc, 0x2e, 0x4f, 0xd4, 0x71, 0xd3, 0xac, 0xf3, 0x0c, 0xcf, 0x78, 0x4e, 0x5c, + 0x63, 0x35, 0xaa, 0xac, 0x5a, 0xf0, 0xef, 0x6c, 0xc0, 0x89, 0x28, 0xc4, 0x64, 0xec, 0x5c, 0x92, 0x72, 0xbc, 0xe5, 0x30, + 0xe9, 0x5c, 0x35, 0xff, 0xe0, 0xb1, 0x1f, 0xc6, 0x37, 0x50, 0xb7, 0x3d, 0x94, 0x28, 0xbd, 0x3b, 0xf0, 0xd9, 0x5c, 0xb1, + 0x45, 0x93, 0xde, 0x41, 0x5b, 0x12, 0xba, 0xfa, 0x27, 0x49, 0x6b, 0xb7, 0x9a, 0xa6, 0x46, 0x8e, 0xe3, 0x15, 0x1b, 0x7f, + 0x2c, 0x91, 0x2e, 0x33, 0xf3, 0xef, 0x7a, 0x9b, 0x9d, 0xa8, 0x82, 0x95, 0xa0, 0x7e, 0x43, 0xd6, 0x9d, 0xe2, 0xfb, 0xb1, + 0xb0, 0xcf, 0xbd, 0xb6, 0x9b, 0x55, 0x4c, 0xc8, 0x4a, 0xc7, 0x82, 0xeb, 0x3d, 0x09, 0x8d, 0x85, 0x6f, 0x8c, 0x42, 0x6d, + 0x10, 0x7d, 0x77, 0x57, 0x29, 0x00, 0xe2, 0xd8, 0x2f, 0xed, 0x7c, 0x10, 0x5b, 0x03, 0xfa, 0x60, 0x34, 0xc9, 0x63, 0x25, + 0x4d, 0x02, 0x77, 0x8f, 0x7f, 0x4b, 0x53, 0xe4, 0x8d, 0x1e, 0x4e, 0x2c, 0x0c, 0x7f, 0x0e, 0x48, 0x4b, 0xcd, 0xc8, 0x6a, + 0xfa, 0xd3, 0x9f, 0x6f, 0x20, 0x4e, 0x2c, 0x77, 0x2a, 0x84, 0x5e, 0x6c, 0xc3, 0x57, 0xba, 0x97, 0xa7, 0xa8, 0xcb, 0x6f, + 0x22, 0xc1, 0xa7, 0x61, 0xf7, 0x7e, 0x7a, 0xae, 0xda, 0xbd, 0x3a, 0xea, 0xb3, 0x46, 0x54, 0x8d, 0x46, 0x48, 0x1f, 0xf3, + 0x5c, 0xaa, 0x2e, 0x44, 0xe1, 0x83, 0x69, 0x45, 0x30, 0x02, 0x49, 0x63, 0xa6, 0xdd, 0xf0, 0x25, 0xce, 0x81, 0xab, 0x66, + 0x20, 0x04, 0x12, 0x2f, 0x94, 0x2f, 0x8f, 0xf9, 0x88, 0xea, 0x5b, 0xba, 0x87, 0xd7, 0xbe, 0x63, 0x2e, 0xb4, 0xa4, 0x15, + 0xe8, 0x56, 0x9e, 0xb5, 0x7b, 0x27, 0xf8, 0x06, 0xfd, 0xf5, 0x21, 0x93, 0x2b, 0x64, 0xb0, 0xe2, 0x31, 0xb3, 0x19, 0xe0, + 0x6b, 0x10, 0x8c, 0xa5, 0xa5, 0x38, 0x27, 0x78, 0xc9, 0x9c, 0x01, 0xa7, 0x42, 0x22, 0x3d, 0xf8, 0x8c, 0x23, 0x46, 0xc5, + 0x4e, 0x47, 0xa5, 0x9e, 0xd7, 0xa5, 0x50, 0x24, 0x02, 0x30, 0xe9, 0x15, 0x3e, 0x17, 0xba, 0x2c, 0xf2, 0x5e, 0xc7, 0x01, + 0x25, 0x9a, 0x74, 0x73, 0x5c, 0x5e, 0xca, 0x01, 0xe2, 0x58, 0x96, 0x47, 0x3e, 0x4c, 0xb9, 0x0f, 0x95, 0xbf, 0xf3, 0xc4, + 0x24, 0x98, 0x6c, 0xc5, 0x40, 0xd2, 0xf3, 0x88, 0x62, 0xb0, 0x25, 0x54, 0xb5, 0xf6, 0x2b, 0xfd, 0xf5, 0x6a, 0x6d, 0x15, + 0xb2, 0x18, 0x7d, 0xef, 0x3e, 0x66, 0x7d, 0x38, 0x4c, 0xda, 0xc9, 0x1a, 0xcd, 0x40, 0x2a, 0xc6, 0x7b, 0x2e, 0x8a, 0x15, + 0xa7, 0xae, 0x99, 0xf5, 0x93, 0x39, 0x20, 0xd2, 0xd8, 0xfd, 0x1f, 0x87, 0x2e, 0xa0, 0xcd, 0x95, 0xa2, 0xd7, 0xd0, 0x48, + 0xf7, 0x6e, 0x81, 0x91, 0x1c, 0x37, 0x8a, 0x28, 0x6f, 0x22, 0x7b, 0x37, 0x69, 0x30, 0x3a, 0x64, 0x6e, 0x4a, 0x5f, 0x0a, + 0xa6, 0xd7, 0x53, 0xce, 0x1d, 0x60, 0x88, 0xa5, 0x0b, 0xde, 0xf5, 0x01, 0x3a, 0x20, 0xfa, 0xd6, 0x08, 0xdf, 0x83, 0x39, + 0x2e, 0xb8, 0x3a, 0x91, 0xec, 0x39, 0x47, 0xaa, 0x66, 0x8a, 0xb4, 0x35, 0x70, 0xaf, 0x88, 0x24, 0xb2, 0xc3, 0xdc, 0x7c, + 0xd0, 0x8f, 0x93, 0x0d, 0xa4, 0x53, 0xf1, 0x55, 0x92, 0xae, 0xd9, 0xeb, 0x31, 0xa0, 0x68, 0x29, 0xf5, 0xdb, 0x2f, 0xd1, + 0xa3, 0xfe, 0x34, 0x2f, 0xcd, 0x64, 0x0c, 0x11, 0x13, 0x14, 0x50, 0xeb, 0x27, 0x56, 0xda, 0xc0, 0x30, 0x3a, 0x8c, 0x92, + 0xb3, 0xb8, 0xc8, 0xb7, 0x19, 0xea, 0x4c, 0x74, 0xb9, 0x95, 0x46, 0x9f, 0xc0, 0x63, 0xfd, 0x72, 0x35, 0x0b, 0xb9, 0x1d, + 0x1e, 0x85, 0xf8, 0xf9, 0x23, 0xf7, 0x42, 0xe2, 0xf4, 0x67, 0xbf, 0x3d, 0x30, 0x4b, 0x6a, 0xf2, 0x44, 0x2f, 0xcb, 0x6f, + 0xe9, 0x73, 0x4b, 0x8f, 0x09, 0x29, 0x69, 0xcd, 0x8d, 0xcd, 0xc7, 0xd4, 0xa2, 0x0c, 0x6a, 0xc4, 0x9a, 0x33, 0xe2, 0x64, + 0x5f, 0x07, 0xf2, 0xb6, 0xf8, 0x86, 0x7f, 0x05, 0x04, 0xf1, 0x1d, 0x9d, 0xd1, 0xc8, 0x3c, 0x16, 0x6e, 0x18, 0x96, 0x15, + 0x33, 0xda, 0x84, 0xb6, 0xfd, 0x13, 0x29, 0x2f, 0x5e, 0xa0, 0x0e, 0xaa, 0xf6, 0x24, 0xb4, 0xa5, 0x48, 0x01, 0x02, 0x07, + 0x31, 0x98, 0x0d, 0x9c, 0x65, 0x59, 0x68, 0x61, 0x22, 0xdb, 0x64, 0x16, 0x05, 0xae, 0xd8, 0x64, 0x5f, 0xba, 0x51, 0xab, + 0x5e, 0xe0, 0xbe, 0x3d, 0x29, 0x67, 0x20, 0x94, 0x63, 0xfe, 0xc7, 0x90, 0x30, 0xc9, 0x43, 0xf1, 0xce, 0x9c, 0x53, 0x01, + 0x2c, 0x64, 0x56, 0x85, 0xb7, 0x3b, 0xa4, 0x05, 0x5d, 0x88, 0xdf, 0x44, 0xda, 0x18, 0xf3, 0x8c, 0xdb, 0xae, 0xd2, 0x9f, + 0xee, 0x4e, 0x08, 0x17, 0xf9, 0xd8, 0xe0, 0xc9, 0x7d, 0xa5, 0xad, 0x79, 0x06, 0x1b, 0x8c, 0x92, 0xe7, 0x53, 0xdf, 0xde, + 0xa3, 0xa5, 0x84, 0x1d, 0xd8, 0x75, 0x35, 0x78, 0x32, 0x55, 0x6f, 0x4f, 0x29, 0x34, 0x4e, 0x6f, 0x32, 0x16, 0xe4, 0xfd, + 0xbc, 0xf5, 0x76, 0x99, 0xf3, 0x48, 0x5b, 0xa0, 0x65, 0xb2, 0xef, 0xeb, 0x58, 0x6c, 0xf4, 0x1e, 0x97, 0x34, 0xee, 0xf9, + 0x74, 0xe2, 0x94, 0xc0, 0xf2, 0xf5, 0x0b, 0x97, 0x40, 0xce, 0x25, 0xd6, 0xe5, 0xdf, 0x0b, 0x3b, 0x6b, 0xf3, 0x38, 0x28, + 0xc3, 0xa6, 0x30, 0xa5, 0x22, 0x3c, 0xb0, 0xbd, 0x4d, 0xd5, 0x79, 0x25, 0xb9, 0xb2, 0xb4, 0xc4, 0x31, 0x62, 0x0b, 0xe7, + 0x73, 0x4e, 0xf9, 0xa7, 0x57, 0xdf, 0x33, 0x0e, 0xf0, 0xb9, 0x3b, 0x6d, 0xff, 0x6b, 0x11, 0xb0, 0x90, 0x10, 0x2a, 0x7b, + 0xb5, 0x0b, 0x41, 0x17, 0x0b, 0x12, 0xc7, 0x61, 0xef, 0xb1, 0x9b, 0x57, 0x3a, 0x01, 0x55, 0x91, 0xe3, 0xd5, 0xc8, 0xd5, + 0xeb, 0x26, 0x90, 0x2b, 0x67, 0x5b, 0xc2, 0x0b, 0xad, 0x6f, 0x26, 0x3a, 0xf5, 0x45, 0xb2, 0xd7, 0x6a, 0x78, 0xaa, 0x43, + 0xd0, 0xdb, 0x53, 0x6f, 0x1a, 0x7a, 0x5c, 0x92, 0xe1, 0xb7, 0xe5, 0xad, 0xda, 0xac, 0x3b, 0x5a, 0x20, 0x06, 0xe1, 0x56, + 0xf0, 0x55, 0x66, 0x64, 0x42, 0xd4, 0xe4, 0x77, 0x3b, 0xa5, 0x60, 0x8d, 0x5b, 0x24, 0x7a, 0x2a, 0xb9, 0xe2, 0x2f, 0xc6, + 0x02, 0xd1, 0x21, 0xf3, 0x08, 0xbd, 0x7b, 0xf4, 0x44, 0x47, 0x00, 0xd2, 0xca, 0x3c, 0x80, 0x37, 0xb0, 0xf2, 0x3d, 0x07, + 0x87, 0xbd, 0xe8, 0x59, 0x01, 0x17, 0x7b, 0xb3, 0x1b, 0xc3, 0xce, 0x45, 0x77, 0x3c, 0x0e, 0xdd, 0xac, 0x38, 0xf1, 0x5e, + 0xde, 0x5e, 0xdd, 0xad, 0xf2, 0xc9, 0x0f, 0xed, 0xec, 0xe5, 0x00, 0x8b, 0x61, 0xf4, 0x62, 0xd5, 0x58, 0x37, 0xec, 0xbf, + 0x36, 0xcf, 0x7a, 0x6a, 0x55, 0x1f, 0x25, 0x53, 0xba, 0xcd, 0x76, 0xc3, 0x07, 0x5e, 0x12, 0xf0, 0xc3, 0x82, 0x52, 0x5f, + 0xc6, 0x24, 0x54, 0x76, 0x49, 0xa3, 0xf1, 0xdd, 0x67, 0x29, 0x81, 0x19, 0x5f, 0x7b, 0xcd, 0xc6, 0x60, 0x3e, 0x80, 0x02, + 0xb3, 0xd9, 0xb6, 0x9d, 0x29, 0x59, 0xdc, 0x79, 0x90, 0xab, 0x53, 0xf4, 0xe6, 0x23, 0xb4, 0x77, 0x0f, 0xc8, 0xf2, 0x88, + 0xb3, 0x1c, 0x70, 0xb4, 0xeb, 0xa8, 0xdf, 0x25, 0x5b, 0x94, 0xa6, 0xce, 0x80, 0xbd, 0x46, 0xe6, 0x26, 0x8c, 0x4f, 0xee, + 0x37, 0x81, 0x84, 0xc6, 0xff, 0x0a, 0x37, 0x2e, 0xa4, 0xcb, 0xdf, 0x62, 0x81, 0x79, 0x3b, 0xa2, 0xdb, 0x07, 0x14, 0x0c, + 0xf7, 0x44, 0x1e, 0xda, 0xe0, 0x6c, 0x1a, 0xb6, 0x52, 0x7f, 0xd8, 0xce, 0xe7, 0x29, 0x98, 0xc1, 0x69, 0x40, 0xb9, 0x2a, + 0xe7, 0xb4, 0xee, 0x04, 0x67, 0xf7, 0x54, 0xac, 0x94, 0x12, 0x5c, 0x67, 0xb4, 0x51, 0x9c, 0xf6, 0xfa, 0x9b, 0x10, 0xd3, + 0x7e, 0xce, 0x78, 0xd5, 0x88, 0x80, 0xd7, 0x88, 0xea, 0x16, 0x51, 0x0c, 0xc9, 0xf2, 0x55, 0xda, 0xbd, 0x22, 0x34, 0x1a, + 0x65, 0x8f, 0xd7, 0x52, 0x00, 0x98, 0xc3, 0x76, 0xff, 0x3e, 0xfc, 0x44, 0x4b, 0x7e, 0xc2, 0x40, 0x00, 0x94, 0xf3, 0xc6, + 0xd5, 0xa3, 0x0f, 0x95, 0x9a, 0x96, 0xbb, 0x50, 0xcd, 0xd0, 0x6f, 0x75, 0xd7, 0xcc, 0x89, 0xb4, 0xc2, 0x85, 0x7f, 0x5f, + 0x06, 0xc1, 0xdf, 0x3c, 0xdd, 0x32, 0xdb, 0x44, 0xae, 0x1e, 0xd8, 0x56, 0xde, 0x93, 0xb0, 0xbd, 0xed, 0x8c, 0xb6, 0xcc, + 0x15, 0xe7, 0x81, 0x98, 0x36, 0x36, 0xd6, 0x91, 0x61, 0xd8, 0x65, 0x57, 0x5d, 0xcd, 0xbf, 0xf1, 0x3b, 0x31, 0xb6, 0xdd, + 0x6e, 0xc6, 0xd3, 0x1b, 0xc9, 0x47, 0x8c, 0x09, 0x03, 0x81, 0x7d, 0xbd, 0x64, 0xa9, 0x09, 0x66, 0x81, 0x2d, 0x56, 0x43, + 0xe8, 0x3c, 0x3e, 0xaa, 0xf8, 0x28, 0x92, 0x13, 0xea, 0x1f, 0xc1, 0x81, 0x4f, 0xb1, 0x1e, 0x88, 0xd2, 0x47, 0xdb, 0xb4, + 0x7e, 0xcb, 0xac, 0xc4, 0xbc, 0x07, 0x68, 0x83, 0x7d, 0xd2, 0x90, 0x90, 0x01, 0xa7, 0x0b, 0xac, 0x60, 0x67, 0x0f, 0xf4, + 0x1b, 0x2c, 0x1e, 0x93, 0x93, 0x6a, 0x16, 0x63, 0x78, 0x36, 0x7d, 0xc5, 0xa5, 0x04, 0xf4, 0x96, 0x1d, 0xae, 0x1a, 0xdf, + 0x1d, 0xba, 0xfc, 0x00, 0x21, 0x07, 0x8c, 0xa7, 0x9d, 0x00, 0x60, 0xb7, 0xa4, 0x05, 0xdd, 0xcd, 0x05, 0xee, 0x70, 0x5e, + 0xc5, 0x79, 0x6c, 0xc1, 0x22, 0x57, 0xfb, 0x5a, 0x25, 0x3e, 0xb9, 0x37, 0x76, 0x61, 0xc2, 0x7d, 0x14, 0x3c, 0xd3, 0x3a, + 0x13, 0xb9, 0x33, 0x07, 0xf6, 0x53, 0xc9, 0x5b, 0xb9, 0x97, 0x03, 0xd0, 0x76, 0xb8, 0xd1, 0xf1, 0x43, 0x9d, 0x7f, 0x37, + 0x46, 0x1a, 0xda, 0xdf, 0xd7, 0x4a, 0xb7, 0x79, 0x84, 0x9e, 0x47, 0x73, 0xac, 0x26, 0xf7, 0xd7, 0x54, 0x16, 0xad, 0x49, + 0x5e, 0x5d, 0x77, 0x61, 0x79, 0xdd, 0x52, 0x13, 0x2f, 0x20, 0xce, 0x26, 0x35, 0xa3, 0x60, 0x28, 0x3f, 0xc5, 0x67, 0xce, + 0x43, 0xa0, 0x86, 0x28, 0xf7, 0xa6, 0xf9, 0x6a, 0xbf, 0x25, 0x41, 0xb7, 0x7d, 0xbc, 0x04, 0x02, 0xd1, 0xe5, 0xed, 0x74, + 0xf5, 0xf5, 0x39, 0xf5, 0x18, 0x42, 0x9f, 0xdc, 0xaf, 0x46, 0xb6, 0x55, 0x48, 0x72, 0xa6, 0x66, 0x94, 0xef, 0x4a, 0x45, + 0x92, 0xf8, 0x31, 0x7a, 0x19, 0x69, 0xcb, 0xcf, 0xf3, 0x10, 0x4a, 0x65, 0x53, 0x18, 0xf4, 0x7f, 0x47, 0xe8, 0xe5, 0x07, + 0xb1, 0x8b, 0x3c, 0x3b, 0xb1, 0x1f, 0xdb, 0xb8, 0x5d, 0x53, 0xcb, 0xad, 0xf7, 0x38, 0x91, 0x8a, 0x1e, 0xa6, 0x76, 0x05, + 0x48, 0x89, 0xcc, 0xff, 0x51, 0x59, 0x53, 0xe9, 0xd7, 0x6e, 0x1a, 0x6e, 0xad, 0xf2, 0xcb, 0xf5, 0xfd, 0x48, 0xbe, 0xa8, + 0x70, 0xae, 0x5e, 0xc1, 0x7e, 0x1e, 0x07, 0x8e, 0x64, 0x0d, 0x70, 0xb7, 0x92, 0xda, 0x6f, 0x45, 0xb0, 0xe3, 0x8a, 0x30, + 0xbc, 0x45, 0xd1, 0x65, 0xf2, 0xb7, 0xab, 0x4e, 0x16, 0x5c, 0xa2, 0xb2, 0x9a, 0x4d, 0x2f, 0x76, 0x26, 0x62, 0x92, 0x7a, + 0x3c, 0x47, 0xf6, 0x87, 0x04, 0x0f, 0x7b, 0xda, 0x4b, 0x02, 0x6b, 0xd6, 0x16, 0x79, 0xbd, 0x16, 0x24, 0x42, 0x7a, 0xf4, + 0x44, 0x58, 0xb4, 0x68, 0x71, 0xce, 0xb3, 0x28, 0xba, 0x84, 0x6c, 0x26, 0x82, 0x1e, 0xba, 0x19, 0x83, 0xb7, 0x75, 0x1b, + 0xde, 0x09, 0xf6, 0x1b, 0x4f, 0x31, 0x65, 0xae, 0xb6, 0x45, 0xc2, 0xa7, 0x35, 0x2d, 0x9f, 0x14, 0x10, 0xe0, 0x3e, 0x43, + 0xa7, 0x82, 0x01, 0x06, 0x95, 0x2c, 0x19, 0x43, 0x8c, 0x94, 0xd4, 0x8c, 0x85, 0x6d, 0x88, 0x33, 0xff, 0x19, 0x51, 0xd3, + 0x7c, 0xf2, 0xa7, 0x5b, 0x05, 0xd1, 0x2b, 0x56, 0x18, 0x5e, 0xa6, 0xb9, 0x66, 0x3c, 0xf7, 0x4d, 0xbd, 0xa9, 0x95, 0x75, + 0xa9, 0xa1, 0x87, 0x24, 0x87, 0xf0, 0x60, 0xbb, 0x39, 0xec, 0xd1, 0xe5, 0x67, 0x51, 0x76, 0x99, 0xbc, 0x64, 0x7b, 0x5a, + 0xd5, 0xa6, 0x54, 0x4f, 0x16, 0x10, 0xb2, 0xe9, 0x43, 0x1c, 0x3a, 0x4c, 0x88, 0x51, 0xf4, 0xc2, 0x95, 0x16, 0x8e, 0xbf, + 0x79, 0x19, 0x22, 0x95, 0xd1, 0x76, 0x99, 0xb8, 0x68, 0xf3, 0x6a, 0x1a, 0x4e, 0x43, 0xf8, 0x9c, 0x6b, 0x75, 0x8c, 0xa5, + 0xbd, 0x65, 0x3a, 0x83, 0x0b, 0x47, 0xcf, 0x08, 0xf7, 0x22, 0x86, 0xad, 0xd5, 0x89, 0xd0, 0x6f, 0x4e, 0xbe, 0x2a, 0x81, + 0x1d, 0x1c, 0xf1, 0xc8, 0xf3, 0x18, 0x44, 0x40, 0xf3, 0x99, 0xfd, 0x18, 0xe3, 0x1a, 0xc9, 0x7f, 0x3b, 0x93, 0x68, 0x84, + 0xe2, 0x49, 0xb9, 0xcf, 0x00, 0x5c, 0x76, 0xc4, 0xcc, 0x4b, 0x7e, 0x86, 0x7e, 0x3f, 0x4b, 0x23, 0x61, 0x92, 0x7c, 0xcb, + 0x0c, 0x0c, 0x3e, 0x97, 0x34, 0xcc, 0xfd, 0x34, 0xa9, 0xcc, 0xf0, 0x83, 0xb1, 0xbc, 0x50, 0x4c, 0x84, 0x6f, 0xba, 0x68, + 0x01, 0x4f, 0x71, 0x57, 0x05, 0x7f, 0x01, 0xe2, 0x18, 0x23, 0xe9, 0x44, 0xa8, 0x4d, 0x93, 0x11, 0xee, 0xc0, 0x79, 0x5a, + 0x94, 0x13, 0x81, 0xf4, 0x67, 0xa0, 0x50, 0x79, 0x83, 0xa1, 0x13, 0x5f, 0x0e, 0x82, 0x9a, 0x72, 0x90, 0xba, 0x43, 0x21, + 0x28, 0xa9, 0x65, 0x1c, 0x16, 0x97, 0x6f, 0xdb, 0xc3, 0x1e, 0x23, 0xc5, 0x4a, 0xdb, 0x3b, 0x3c, 0x42, 0x4a, 0xc4, 0xb5, + 0x7f, 0x6b, 0x5d, 0xfc, 0x09, 0x08, 0x43, 0x2f, 0xf8, 0x11, 0x27, 0x6f, 0x1d, 0xc0, 0x12, 0x59, 0x04, 0xa4, 0x5b, 0xe9, + 0x9f, 0x25, 0xd1, 0x58, 0x3a, 0x1f, 0xac, 0x05, 0x15, 0x18, 0xea, 0xbd, 0x4b, 0xd2, 0xba, 0x67, 0xf3, 0x1d, 0x89, 0x09, + 0x52, 0xe5, 0x0e, 0x15, 0xd6, 0x5b, 0x87, 0xf5, 0xc3, 0x3c, 0x98, 0xbc, 0x46, 0x4e, 0x19, 0x8d, 0xbb, 0x3e, 0xe0, 0xde, + 0x19, 0x59, 0x53, 0x32, 0x62, 0x31, 0x16, 0xd4, 0xea, 0x63, 0xda, 0xf4, 0xcc, 0x94, 0xd0, 0x18, 0x98, 0xbc, 0x00, 0xd3, + 0x6c, 0xe2, 0xa5, 0xac, 0x30, 0x08, 0x9d, 0x68, 0x82, 0x8e, 0xbb, 0xdf, 0x9a, 0xa1, 0x13, 0xa5, 0x98, 0x18, 0xa9, 0x11, + 0xde, 0x49, 0x18, 0x88, 0xab, 0xff, 0xc6, 0x2c, 0xa8, 0xe1, 0xf7, 0x49, 0xba, 0x17, 0x93, 0x1c, 0x6c, 0x7f, 0x2c, 0xa9, + 0x3a, 0xee, 0x77, 0x9d, 0x46, 0x0c, 0xf9, 0x1c, 0x24, 0x33, 0x6f, 0x9b, 0xf8, 0x47, 0x9d, 0xc9, 0x7f, 0x9c, 0x80, 0xa0, + 0x2c, 0x96, 0x63, 0xe1, 0x97, 0x75, 0x75, 0x1f, 0xb3, 0xc6, 0x0d, 0xa9, 0x49, 0x82, 0x66, 0x86, 0x13, 0xa4, 0x62, 0x4c, + 0x56, 0x89, 0x73, 0x03, 0x1b, 0x61, 0xff, 0xfa, 0x0f, 0xf4, 0x84, 0xe3, 0xad, 0x89, 0xc0, 0x8e, 0x03, 0x91, 0x1c, 0x99, + 0x9f, 0x99, 0x92, 0x7e, 0xb5, 0xd8, 0xe3, 0xee, 0x6c, 0x21, 0x27, 0x5d, 0xa2, 0xa5, 0x90, 0xf2, 0x67, 0xed, 0xf3, 0xca, + 0x51, 0x56, 0x28, 0x7d, 0xa9, 0xd0, 0x4a, 0x4b, 0x76, 0x2b, 0xa8, 0x95, 0x8a, 0x37, 0xb4, 0x72, 0x96, 0xb2, 0xa0, 0xbe, + 0x90, 0x4f, 0x4e, 0x37, 0xbb, 0x14, 0xf8, 0xd2, 0x76, 0x7c, 0x79, 0xf3, 0xd2, 0xbf, 0x35, 0xad, 0x64, 0xbc, 0x98, 0x73, + 0xe5, 0xb9, 0xb3, 0xa2, 0x9b, 0x54, 0x17, 0x9b, 0x99, 0xa1, 0xeb, 0xfd, 0xc2, 0x8b, 0xbd, 0xac, 0x6d, 0x14, 0x35, 0xc2, + 0x3b, 0xc9, 0x88, 0x57, 0x64, 0xaa, 0x52, 0x3d, 0xf1, 0x80, 0x9c, 0xb2, 0xfc, 0xe9, 0x53, 0x7c, 0x12, 0x81, 0xe6, 0x07, + 0xa1, 0x0b, 0x2b, 0xb3, 0x88, 0xa6, 0x07, 0xb8, 0x10, 0x7e, 0xc4, 0x55, 0x14, 0xa2, 0x66, 0xf1, 0xcc, 0xff, 0x49, 0x84, + 0xbc, 0x54, 0x15, 0x41, 0x26, 0x15, 0x44, 0xf1, 0xe4, 0x4e, 0x8a, 0xf4, 0x02, 0xb1, 0x87, 0x51, 0xa7, 0xa4, 0xe6, 0x4f, + 0xbb, 0xff, 0xfe, 0x94, 0x51, 0x54, 0x20, 0x7e, 0x16, 0x60, 0x23, 0xfe, 0x05, 0x8c, 0x1a, 0xe1, 0x12, 0x7c, 0xd4, 0xc0, + 0xae, 0x3a, 0x96, 0x13, 0x5d, 0x83, 0x89, 0x49, 0x99, 0x2c, 0x3e, 0x19, 0x8b, 0xa8, 0xf0, 0x0d, 0x65, 0x5d, 0x35, 0x37, + 0xa1, 0x2d, 0xdd, 0xe2, 0x6b, 0x0d, 0xa9, 0x47, 0x9e, 0xf0, 0x22, 0xb5, 0x8e, 0xab, 0xc1, 0x34, 0x93, 0x4c, 0xff, 0x89, + 0x9b, 0x24, 0xd4, 0x01, 0x24, 0xbc, 0xf5, 0x42, 0xd8, 0xee, 0xc2, 0xbc, 0x78, 0x03, 0xc1, 0x24, 0xa8, 0x88, 0xba, 0x3f, + 0x71, 0x58, 0x3d, 0xdd, 0xef, 0xa8, 0xf8, 0x15, 0x4c, 0xb0, 0x68, 0x7c, 0xbc, 0x41, 0x66, 0x72, 0xc4, 0x4d, 0x9f, 0xd0, + 0xdb, 0x9a, 0xd0, 0x65, 0xde, 0xf1, 0x25, 0x02, 0x35, 0xff, 0x49, 0x4a, 0xd8, 0xa4, 0x19, 0x49, 0xb4, 0x51, 0xda, 0x4b, + 0x75, 0x81, 0x17, 0xa7, 0x84, 0x80, 0x70, 0x3f, 0xc7, 0x0d, 0xb2, 0x79, 0x24, 0x25, 0x7c, 0xe2, 0x30, 0x67, 0x15, 0x00, + 0x80, 0x68, 0x1e, 0xde, 0xf0, 0x3e, 0xda, 0xc6, 0x31, 0x4d, 0xa7, 0xf0, 0x53, 0x0d, 0x88, 0x08, 0xe1, 0xd8, 0xe2, 0x8b, + 0x01, 0xdb, 0x9f, 0x5b, 0x7c, 0xd4, 0x68, 0x89, 0xb1, 0xeb, 0xdb, 0x4e, 0x6f, 0xac, 0x21, 0xad, 0xf2, 0xed, 0x6f, 0x61, + 0x4d, 0x1f, 0x2f, 0x64, 0x0b, 0xdb, 0x07, 0x54, 0x65, 0xd7, 0xf0, 0xf8, 0x40, 0xdb, 0xd9, 0x5e, 0x2d, 0xaf, 0x4f, 0x14, + 0x9f, 0x5b, 0x0b, 0x74, 0x4e, 0xad, 0x07, 0x60, 0xac, 0x24, 0x04, 0x5b, 0xc8, 0xf4, 0xc9, 0x6f, 0x28, 0xb0, 0x2b, 0xb3, + 0xd9, 0x43, 0xf1, 0x55, 0xc9, 0x25, 0x01, 0xb7, 0xab, 0x8f, 0xd8, 0x0f, 0x78, 0x6a, 0xbf, 0xa0, 0x4e, 0x80, 0x22, 0xc6, + 0x8a, 0x42, 0x37, 0x6d, 0x3a, 0xbd, 0xf3, 0x66, 0xbe, 0x84, 0x87, 0xf6, 0xa1, 0xa0, 0x99, 0x7f, 0x13, 0x66, 0x40, 0x39, + 0xce, 0x43, 0x8f, 0xe5, 0x83, 0x48, 0x94, 0xc6, 0x59, 0xc2, 0xce, 0x55, 0x35, 0x44, 0x74, 0xa6, 0x37, 0x0c, 0x3c, 0x69, + 0xdc, 0xdb, 0x2b, 0x3a, 0xd8, 0x32, 0x4d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x01, 0xae, 0x1a, 0x61, 0x75, 0xae, 0x23, 0xd9, 0x11, 0x5c, 0x28, 0x93, 0xa9, 0xe2, + 0x49, 0x5e, 0x74, 0x28, 0x4c, 0x08, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, + 0x00, 0x04, 0x14, 0x3d, 0xc6, 0xb0, 0x07, 0xf5, 0xd4, 0xa7, 0x42, 0x90, 0xa1, 0x2f, 0x4d, 0x1e, 0x43, 0x09, 0x7d, 0xd5, + 0xfe, 0x15, 0xb1, 0x04, 0x08, 0xdd, 0xee, 0x2c, 0x8a, 0x3d, 0x65, 0x41, 0x94, 0x02, 0x02, 0x08, 0x00 +}; diff --git a/OSX/sec/Security/Regressions/secitem/si-cms-signing-identity-p12.h b/OSX/sec/Security/Regressions/secitem/si-cms-signing-identity-p12.h new file mode 100644 index 00000000..128777de --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-cms-signing-identity-p12.h @@ -0,0 +1,12 @@ +#ifndef si_cms_signing_identity_p12_h +#define si_cms_signing_identity_p12_h + +/* + * password: "password" + * localKeyID: 01 AE 1A 61 75 AE 23 D9 11 5C 28 93 A9 E2 49 5E 74 28 4C 08 + * subject=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer + * issuer=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer + */ +extern unsigned char signing_identity_p12[4477]; + +#endif /* si_cms_signing_identity_p12_h */ diff --git a/OSX/sec/Security/SecBackupKeybagEntry.m b/OSX/sec/Security/SecBackupKeybagEntry.m index ba8bede5..8c77c759 100644 --- a/OSX/sec/Security/SecBackupKeybagEntry.m +++ b/OSX/sec/Security/SecBackupKeybagEntry.m @@ -90,12 +90,12 @@ return @[@"publickey", @"publickeyHash", @"musr"]; } -- (NSDictionary*) whereClauseToFindSelf { +- (NSDictionary*) whereClauseToFindSelf { return @{@"publickeyHash": self.publickeyHash}; } // used by saveToDatabaseWithConnection to write to db -- (NSDictionary*) sqlValues { +- (NSDictionary*) sqlValues { return @{ @"publickey": self.publickey, @"publickeyHash": self.publickeyHash, diff --git a/OSX/sec/Security/SecBase.c b/OSX/sec/Security/SecBase.c new file mode 100644 index 00000000..9f929cc4 --- /dev/null +++ b/OSX/sec/Security/SecBase.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2006-2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * SecBase.c + */ + +#ifdef STANDALONE +/* Allows us to build genanchors against the BaseSDK. */ +#undef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ +#undef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +#endif + +#include +#include "SecFramework.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !TARGET_OS_OSX + +static CFStringRef copyErrorMessageFromBundle(OSStatus status, CFStringRef tableName); + +// caller MUST release the string, since it is gotten with "CFCopyLocalizedStringFromTableInBundle" +// intended use of reserved param is to pass in CFStringRef with name of the Table for lookup +// Will look by default in "SecErrorMessages.strings" in the resources of Security.framework. + +CFStringRef +SecCopyErrorMessageString(OSStatus status, void *reserved) +{ + CFStringRef result = copyErrorMessageFromBundle(status, CFSTR("SecErrorMessages")); + if (!result) + result = copyErrorMessageFromBundle(status, CFSTR("SecDebugErrorMessages")); + + if (!result) + { + // no error message found, so format a faked-up error message from the status + result = CFStringCreateWithFormat(NULL, NULL, CFSTR("OSStatus %d"), (int)status); + } + + return result; +} + +CFStringRef +copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName) +{ + + CFStringRef errorString = nil; + CFStringRef keyString = nil; + CFBundleRef secBundle = NULL; + + // Make a bundle instance using the URLRef. + secBundle = CFBundleGetBundleWithIdentifier(kSecFrameworkBundleID); + if (!secBundle) + goto exit; + + // Convert status to Int32 string representation, e.g. "-25924" + keyString = CFStringCreateWithFormat (kCFAllocatorDefault, NULL, CFSTR("%d"), (int)status); + if (!keyString) + goto exit; + + errorString = CFCopyLocalizedStringFromTableInBundle(keyString, tableName, secBundle, NULL); + if (CFStringCompare(errorString, keyString, 0) == kCFCompareEqualTo) // no real error message + { + if (errorString) + CFRelease(errorString); + errorString = nil; + } +exit: + if (keyString) + CFRelease(keyString); + + return errorString; +} + +const SecRandomRef kSecRandomDefault = NULL; + +int SecRandomCopyBytes(__unused SecRandomRef rnd, size_t count, void *bytes) { + return CCRandomCopyBytes(kCCRandomDefault, bytes, count); +} + +#endif // TARGET_OS_OSX diff --git a/OSX/sec/Security/SecCMS.c b/OSX/sec/Security/SecCMS.c index f9bc72ed..ba1ee699 100644 --- a/OSX/sec/Security/SecCMS.c +++ b/OSX/sec/Security/SecCMS.c @@ -78,6 +78,7 @@ CFTypeRef kSecCMSSignDate = CFSTR("kSecCMSSignDate"); CFTypeRef kSecCMSAllCerts = CFSTR("kSecCMSAllCerts"); CFTypeRef kSecCMSHashAgility = CFSTR("kSecCMSHashAgility"); CFTypeRef kSecCMSHashAgilityV2 = CFSTR("kSecCMSHashAgilityV2"); +CFTypeRef kSecCMSExpirationDate = CFSTR("kSecCMSExpirationDate"); CFTypeRef kSecCMSBulkEncryptionAlgorithm = CFSTR("kSecCMSBulkEncryptionAlgorithm"); CFTypeRef kSecCMSEncryptionAlgorithmDESCBC = CFSTR("kSecCMSEncryptionAlgorithmDESCBC"); @@ -520,6 +521,15 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det } } + CFAbsoluteTime expiration_time; + if (errSecSuccess == SecCmsSignerInfoGetAppleExpirationTime(sigd->signerInfos[0], &expiration_time)) { + CFDateRef expiration_date = CFDateCreate(NULL, expiration_time); + if (expiration_date) { + CFDictionarySetValue(attrs, kSecCMSExpirationDate, expiration_date); + CFReleaseSafe(expiration_date); + } + } + *signed_attributes = attrs; CFReleaseSafe(certs); } @@ -565,6 +575,10 @@ CFArrayRef SecCMSCertificatesOnlyMessageCopyCertificates(CFDataRef message) { SecCmsSignedDataRef sigd = NULL; CFMutableArrayRef certs = NULL; + if (!message) { + return NULL; + } + SecAsn1Item encoded_message = { CFDataGetLength(message), (uint8_t*)CFDataGetBytePtr(message) }; require_noerr_quiet(SecCmsMessageDecode(&encoded_message, NULL, NULL, NULL, NULL, NULL, NULL, &cmsg), out); /* expected to be a signed data message at the top level */ @@ -589,8 +603,10 @@ CFArrayRef SecCMSCertificatesOnlyMessageCopyCertificates(CFDataRef message) { } out: - if (cmsg) - SecCmsMessageDestroy(cmsg); + if (cmsg) { SecCmsMessageDestroy(cmsg); } + if (certs && CFArrayGetCount(certs) < 1) { + CFReleaseNull(certs); + } return certs; } diff --git a/OSX/sec/Security/SecCMS.h b/OSX/sec/Security/SecCMS.h index 268100ca..6ee94941 100644 --- a/OSX/sec/Security/SecCMS.h +++ b/OSX/sec/Security/SecCMS.h @@ -46,6 +46,7 @@ extern const void * kSecCMSSignDate; extern const void * kSecCMSAllCerts; extern const void * kSecCMSHashAgility; extern const void * kSecCMSHashAgilityV2; +extern const void * kSecCMSExpirationDate; extern const void * kSecCMSEncryptionAlgorithmDESCBC; extern const void * kSecCMSEncryptionAlgorithmAESCBC; diff --git a/OSX/sec/Security/SecCTKKey.c b/OSX/sec/Security/SecCTKKey.m similarity index 88% rename from OSX/sec/Security/SecCTKKey.c rename to OSX/sec/Security/SecCTKKey.m index 819d1364..fc35e4cc 100644 --- a/OSX/sec/Security/SecCTKKey.c +++ b/OSX/sec/Security/SecCTKKey.m @@ -21,6 +21,8 @@ * @APPLE_LICENSE_HEADER_END@ */ +#import + #include #include #include @@ -99,7 +101,7 @@ static TKTokenRef SecCTKKeyCreateToken(SecKeyRef key, CFDictionaryRef auth_param if (kd->params && CFDictionaryGetCount(kd->params) > 0) { CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attributes), CFSTR(kTKTokenCreateAttributeAuxParams), kd->params); } - require_quiet(token = SecTokenCreate(kd->token_id, attributes.dictionary, error), out); + require_quiet(token = SecTokenCreate(kd->token_id, &attributes, error), out); if (last_params != NULL) { CFAssignRetained(*last_params, auth_params ? CFDictionaryCreateCopy(NULL, auth_params) : NULL); } @@ -247,7 +249,7 @@ static CFDictionaryRef SecCTKKeyCopyAttributeDictionary(SecKeyRef key) { require_quiet(publicData = TKTokenCopyPublicKeyData(token, kd->object_id, &error), out); // Calculate the digest of the public key. - require(digest = SecSHA1DigestCreate(NULL, CFDataGetBytePtr(publicData), CFDataGetLength(publicData)), out); + require_quiet(digest = SecSHA1DigestCreate(NULL, CFDataGetBytePtr(publicData), CFDataGetLength(publicData)), out); attrs = CFDictionaryCreateMutableForCFTypes(CFGetAllocator(key)); CFDictionarySetValue(attrs, kSecAttrApplicationLabel, digest); @@ -481,17 +483,32 @@ SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef CFDataRef object_id = NULL; SecKeyRef key = NULL; - require_action_quiet(keyType == kSecKeyAttestationKeyTypeSIK || keyType == kSecKeyAttestationKeyTypeGID, out, - SecError(errSecParam, error, CFSTR("unexpected attestation key type %u"), (unsigned)keyType)); - // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.sik" dataUsingEncoding:NSUTF8StringEncoding]].data static const uint8_t sikObjectIDBytes[] = { 0x04, 21, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 's', 'i', 'k' }; // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.gid" dataUsingEncoding:NSUTF8StringEncoding]].data static const uint8_t gidObjectIDBytes[] = { 0x04, 21, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 'g', 'i', 'd' }; - - object_id = (keyType == kSecKeyAttestationKeyTypeSIK ? - CFDataCreate(kCFAllocatorDefault, sikObjectIDBytes, sizeof(sikObjectIDBytes)) : - CFDataCreate(kCFAllocatorDefault, gidObjectIDBytes, sizeof(gidObjectIDBytes))); + // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.uikc" dataUsingEncoding:NSUTF8StringEncoding]].data + static const uint8_t uikCommittedObjectIDBytes[] = { 0x04, 22, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 'u', 'i', 'k', 'c' }; + // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.uikp" dataUsingEncoding:NSUTF8StringEncoding]].data + static const uint8_t uikProposedObjectIDBytes[] = { 0x04, 22, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 'u', 'i', 'k', 'p' }; + + switch (keyType) { + case kSecKeyAttestationKeyTypeSIK: + object_id = CFDataCreate(kCFAllocatorDefault, sikObjectIDBytes, sizeof(sikObjectIDBytes)); + break; + case kSecKeyAttestationKeyTypeGID: + object_id = CFDataCreate(kCFAllocatorDefault, gidObjectIDBytes, sizeof(gidObjectIDBytes)); + break; + case kSecKeyAttestationKeyTypeUIKCommitted: + object_id = CFDataCreate(kCFAllocatorDefault, uikCommittedObjectIDBytes, sizeof(uikCommittedObjectIDBytes)); + break; + case kSecKeyAttestationKeyTypeUIKProposed: + object_id = CFDataCreate(kCFAllocatorDefault, uikProposedObjectIDBytes, sizeof(uikProposedObjectIDBytes)); + break; + default: + SecError(errSecParam, error, CFSTR("unexpected attestation key type %d"), (int)keyType); + goto out; + } attributes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kSecAttrTokenOID, object_id, @@ -552,3 +569,39 @@ out: CFReleaseSafe(token); 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; + if (error == NULL) { + error = (void *)&localError; + } + + SecCTKKeyData *keyData = key->key; + NSDictionary *attributes = @{ + @kTKTokenControlAttribLifetimeControlKey: (__bridge NSData *)keyData->object_id, + @kTKTokenControlAttribLifetimeType: @(type), + }; + + if (key->key_class != &kSecCTKKeyDescriptor) { + return SecError(errSecUnsupportedOperation, error, CFSTR("lifetimecontrol not supported for key %@"), key); + } + + __block SecCFDictionaryCOW auth_params = { keyData->auth_params.dictionary }; + return SecItemAuthDo(&auth_params, error, ^SecItemAuthResult(CFArrayRef *ac_pairs, CFErrorRef *error) { + if (auth_params.mutable_dictionary != NULL || token == NULL) { + token = CFBridgingRelease(SecCTKKeyCopyToken(key, error)); + if (token == nil) { + return kSecItemAuthResultError; + } + } + + NSDictionary *outputAttributes = CFBridgingRelease(TKTokenControl((__bridge TKTokenRef)token, (__bridge CFDictionaryRef)attributes, error)); + return outputAttributes ? kSecItemAuthResultOK : kSecItemAuthResultError; + }, NULL); +} diff --git a/OSX/sec/Security/SecCertificate.c b/OSX/sec/Security/SecCertificate.c index 85686e09..1b466635 100644 --- a/OSX/sec/Security/SecCertificate.c +++ b/OSX/sec/Security/SecCertificate.c @@ -2560,11 +2560,7 @@ static void appendPublicKeyProperty(CFMutableArrayRef parent, CFStringRef label, &certificate->_algId, localized); /* Public Key Size */ -#if TARGET_OS_IPHONE - SecKeyRef publicKey = SecCertificateCopyPublicKey(certificate); -#else - SecKeyRef publicKey = SecCertificateCopyPublicKey_ios(certificate); -#endif + SecKeyRef publicKey = SecCertificateCopyKey(certificate); if (publicKey) { size_t sizeInBytes = SecKeyGetBlockSize(publicKey); CFStringRef sizeInBitsString = CFStringCreateWithFormat(allocator, NULL, @@ -4360,14 +4356,7 @@ CFDataRef SecCertificateCopySerialNumberData( return certificate->_serialNumber; } -#if TARGET_OS_OSX -/* On OS X, the SecCertificateCopySerialNumber API takes two arguments. */ -CFDataRef SecCertificateCopySerialNumber( - SecCertificateRef certificate, - CFErrorRef *error) { - return SecCertificateCopySerialNumberData(certificate, error); -} -#else +#if !TARGET_OS_OSX /* On iOS, the SecCertificateCopySerialNumber API takes one argument. */ CFDataRef SecCertificateCopySerialNumber( SecCertificateRef certificate) { @@ -4735,7 +4724,7 @@ CFArrayRef SecCertificateCopyDNSNames(SecCertificateRef certificate) { CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); OSStatus status = parseX501NameContent(&certificate->_subject, dnsNames, - appendDNSNamesFromX501Name, true); + appendDNSNamesFromX501Name, true); if (status || CFArrayGetCount(dnsNames) == 0) { CFReleaseNull(dnsNames); } @@ -5216,6 +5205,10 @@ __nullable SecKeyRef SecCertificateCopyPublicKey_ios(SecCertificateRef certifica __nullable SecKeyRef SecCertificateCopyPublicKey(SecCertificateRef certificate) #endif { + return SecCertificateCopyKey(certificate); +} + +SecKeyRef SecCertificateCopyKey(SecCertificateRef certificate) { if (certificate->_pubKey == NULL) { const DERAlgorithmId *algId = SecCertificateGetPublicKeyAlgorithm(certificate); @@ -5246,11 +5239,7 @@ static CFIndex SecCertificateGetPublicKeyAlgorithmIdAndSize(SecCertificateRef ce SecKeyRef pubKey = NULL; require_quiet(certificate, out); -#if TARGET_OS_OSX - require_quiet(pubKey = SecCertificateCopyPublicKey_ios(certificate), out); -#else - require_quiet(pubKey = SecCertificateCopyPublicKey(certificate) ,out); -#endif + require_quiet(pubKey = SecCertificateCopyKey(certificate) ,out); size = SecKeyGetBlockSize(pubKey); keyAlgID = SecKeyGetAlgorithmId(pubKey); @@ -5606,11 +5595,7 @@ static bool _SecCertificateIsSelfSigned(SecCertificateRef certificate) { certificate->_isSelfSigned = kSecSelfSignedFalse; SecKeyRef publicKey = NULL; require(certificate && (CFGetTypeID(certificate) == SecCertificateGetTypeID()), out); -#if TARGET_OS_OSX - require(publicKey = SecCertificateCopyPublicKey_ios(certificate), out); -#else - require(publicKey = SecCertificateCopyPublicKey(certificate), out); -#endif + require(publicKey = SecCertificateCopyKey(certificate), out); CFDataRef normalizedIssuer = SecCertificateGetNormalizedIssuerContent(certificate); CFDataRef normalizedSubject = @@ -6148,6 +6133,40 @@ out: return kSeciAuthInvalid; } +static CFStringRef SecCertificateiAPSWAuthCapabilitiesTypeToOID(SeciAPSWAuthCapabilitiesType type) { + CFStringRef extensionOID = NULL; + /* Get the oid for the type */ + if (type == kSeciAPSWAuthGeneralCapabilities) { + extensionOID = CFSTR("1.2.840.113635.100.6.59.1"); + } else if (type == kSeciAPSWAuthAirPlayCapabilities) { + extensionOID = CFSTR("1.2.840.113635.100.6.59.2"); + } else if (type == kSeciAPSWAuthHomeKitCapabilities) { + extensionOID = CFSTR("1.2.840.113635.100.6.59.3"); + } + return extensionOID; +} + +CFDataRef SecCertificateCopyiAPSWAuthCapabilities(SecCertificateRef certificate, SeciAPSWAuthCapabilitiesType type) { + if (!certificate) { + return NULL; + } + CFDataRef extensionData = NULL; + DERItem *extensionValue = NULL; + CFStringRef extensionOID = SecCertificateiAPSWAuthCapabilitiesTypeToOID(type); + require_quiet(extensionOID, out); + extensionValue = SecCertificateGetExtensionValue(certificate, extensionOID); + require_quiet(extensionValue, out); + /* The extension is a octet string containing the DER-encoded variable-length octet string */ + DERDecodedInfo decodedValue; + require_noerr_quiet(DERDecodeItem(extensionValue, &decodedValue), out); + if (decodedValue.tag == ASN1_OCTET_STRING) { + extensionData = CFDataCreate(NULL, decodedValue.content.data, + decodedValue.content.length); + } +out: + return extensionData; +} + SecCertificateRef SecCertificateCreateWithPEM(CFAllocatorRef allocator, CFDataRef pem_certificate) { diff --git a/OSX/sec/Security/SecCertificateInternal.h b/OSX/sec/Security/SecCertificateInternal.h index 96472c93..51d9c7d4 100644 --- a/OSX/sec/Security/SecCertificateInternal.h +++ b/OSX/sec/Security/SecCertificateInternal.h @@ -95,6 +95,12 @@ CFDictionaryRef SecCertificateCopyAttributeDictionary( SecCertificateRef SecCertificateCreateFromAttributeDictionary( CFDictionaryRef refAttributes); +/* Return a SecKeyRef for the public key embedded in the cert. */ +#if TARGET_OS_OSX +SecKeyRef SecCertificateCopyPublicKey_ios(SecCertificateRef certificate) + __OSX_DEPRECATED(__MAC_10_12, __MAC_10_14, "Use SecCertificateCopyKey instead."); +#endif + /* Return the SecCEBasicConstraints extension for this certificate if it has one. */ const SecCEBasicConstraints * diff --git a/OSX/sec/Security/SecCertificateRequest.c b/OSX/sec/Security/SecCertificateRequest.c index 47f853ea..13ed4781 100644 --- a/OSX/sec/Security/SecCertificateRequest.c +++ b/OSX/sec/Security/SecCertificateRequest.c @@ -784,7 +784,7 @@ static CF_RETURNS_RETAINED CFDataRef make_signature (void *data_pointer, size_t } CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, - CFDictionaryRef parameters, SecKeyRef __unused publicKey, SecKeyRef privateKey) + CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey) { if (subject == NULL || *subject == NULL) { return NULL; @@ -820,10 +820,10 @@ CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, } const unsigned min1atv_num = atv_num > 0 ? atv_num : 1; const unsigned min1num = num > 0 ? num : 1; - NSS_ATV atvs[min1atv_num]; - NSS_ATV *atvps[min1atv_num]; - NSS_RDN rdns[min1num]; - NSS_RDN *rdnps[num+1]; + NSS_ATV *atvs = (NSS_ATV *)malloc(sizeof(NSS_ATV) * min1atv_num); + NSS_ATV **atvps = (NSS_ATV **)malloc(sizeof(NSS_ATV *) * min1atv_num); + NSS_RDN *rdns = (NSS_RDN *)malloc(sizeof(NSS_RDN) * min1num); + NSS_RDN **rdnps = (NSS_RDN **)malloc(sizeof(NSS_RDN *) * (num + 1)); atv_num = 0; unsigned rdn_num = 0; for (one_rdn = subject; *one_rdn; one_rdn++) { @@ -844,6 +844,11 @@ CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, /* public key info */ realPublicKey = SecKeyCopyPublicKey(privateKey); + if (!realPublicKey) { + /* If we can't get the public key from the private key, + * fall back to the public key provided by the caller. */ + realPublicKey = CFRetainSafe(publicKey); + } require_quiet(realPublicKey, out); publicKeyData = make_public_key(realPublicKey, &certReq.reqInfo.subjectPublicKeyInfo, &allocated_parameters); require_quiet(publicKeyData, out); @@ -880,11 +885,15 @@ out: CFReleaseSafe(realPublicKey); CFReleaseSafe(publicKeyData); CFReleaseSafe(signature); + free(atvs); + free(atvps); + free(rdns); + free(rdnps); return csr; } CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, - CFDictionaryRef parameters, SecKeyRef __unused publicKey, SecKeyRef privateKey) + CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey) { CFDataRef csr = NULL; PRArenaPool *poolp = PORT_NewArena(1024); @@ -909,6 +918,11 @@ CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, /* public key info */ realPublicKey = SecKeyCopyPublicKey(privateKey); + if (!realPublicKey) { + /* If we can't get the public key from the private key, + * fall back to the public key provided by the caller. */ + realPublicKey = CFRetainSafe(publicKey); + } require_quiet(realPublicKey, out); publicKeyData = make_public_key(realPublicKey, &certReq.reqInfo.subjectPublicKeyInfo, &allocated_parameters); require_quiet(publicKeyData, out); diff --git a/OSX/sec/Security/SecECKey.h b/OSX/sec/Security/SecECKey.h index a5da19eb..4a4fb429 100644 --- a/OSX/sec/Security/SecECKey.h +++ b/OSX/sec/Security/SecECKey.h @@ -44,10 +44,6 @@ typedef struct SecECPublicKeyParams { CFIndex exponentLength; } SecECPublicKeyParams; -enum { - kSecPaddingECIES_SHA2_AES128GCM_MAC128 = 0x9000, /* EC Key Using IESGCM to encrypt */ -}; - /* Given an EC public key in encoded form return a SecKeyRef representing that key. Supported encodings are kSecKeyEncodingPkcs1. */ SecKeyRef SecKeyCreateECPublicKey(CFAllocatorRef allocator, @@ -60,24 +56,6 @@ SecKeyRef SecKeyCreateECPrivateKey(CFAllocatorRef allocator, const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding); -#if SEC_OS_IPHONE_INCLUDES -/* These are the named curves we support. These values come from RFC 4492 - section 5.1.1, with the exception of SSL_Curve_None which means - "ECDSA not negotiated". */ -typedef enum -{ - kSecECCurveNone = -1, - kSecECCurveSecp256r1 = 23, - kSecECCurveSecp384r1 = 24, - kSecECCurveSecp521r1 = 25 -} SecECNamedCurve; - -/* Return a named curve enum for ecPrivateKey. */ -SecECNamedCurve SecECKeyGetNamedCurve(SecKeyRef ecPrivateKey); -CFDataRef SecECKeyCopyPublicBits(SecKeyRef key); -#endif - - __END_DECLS #endif /* !_SECURITY_SECECKEY_H_ */ diff --git a/OSX/sec/Security/SecECKey.c b/OSX/sec/Security/SecECKey.m similarity index 95% rename from OSX/sec/Security/SecECKey.c rename to OSX/sec/Security/SecECKey.m index 8436aca7..c95f7917 100644 --- a/OSX/sec/Security/SecECKey.c +++ b/OSX/sec/Security/SecECKey.m @@ -22,21 +22,20 @@ */ /* - * SecECKey.c - CoreFoundation based rsa key object + * SecECKey.m - CoreFoundation based ECDSA key object */ #include "SecECKey.h" #include "SecECKeyPriv.h" +#import + #include #include #include #include #include /* For error codes. */ #include /* For error codes. */ -#include -#include -#include #include #include #include @@ -274,36 +273,24 @@ getCurveName(SecKeyRef key) static CFStringRef SecECPublicKeyCopyKeyDescription(SecKeyRef key) { - CFStringRef keyDescription = NULL; - CFMutableStringRef strings[2] = { NULL, }; + NSMutableString *strings[2]; const char* curve = getCurveName(key); ccec_pub_ctx_t ecPubkey = key->key; size_t len = ccec_ctx_size(ecPubkey); - uint8_t buffer[len]; + NSMutableData *buffer = [NSMutableData dataWithLength:len]; for (int i = 0; i < 2; ++i) { - ccn_write_uint(ccec_ctx_n(ecPubkey), (i == 0) ? ccec_ctx_x(ecPubkey) : ccec_ctx_y(ecPubkey), len, buffer); - require_quiet(strings[i] = CFStringCreateMutable(kCFAllocatorDefault, len * 2), fail); + ccn_write_uint(ccec_ctx_n(ecPubkey), (i == 0) ? ccec_ctx_x(ecPubkey) : ccec_ctx_y(ecPubkey), len, buffer.mutableBytes); + strings[i] = [NSMutableString stringWithCapacity:len * 2]; for (size_t byteIndex = 0; byteIndex < len; ++byteIndex) { - CFStringAppendFormat(strings[i], NULL, CFSTR("%02X"), buffer[byteIndex]); + [strings[i] appendFormat:@"%02X", ((const uint8_t *)buffer.bytes)[byteIndex]]; } } - keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR( ""), - curve, (long)SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version, - 8 * SecKeyGetBlockSize(key), strings[1], strings[0], key); - -fail: - CFReleaseSafe(strings[0]); - CFReleaseSafe(strings[1]); - if(!keyDescription) - keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR(""), - curve,(long)SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version, - 8 * SecKeyGetBlockSize(key), key); - - return keyDescription; + NSString *description = [NSString stringWithFormat:@"", + curve, (long)SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version, + 8 * SecKeyGetBlockSize(key), strings[1], strings[0], key]; + return CFBridgingRetain(description); } static const struct ccec_rfc6637_curve * get_rfc6637_curve(SecKeyRef key) @@ -477,7 +464,7 @@ static OSStatus SecECPrivateKeyInit(SecKeyRef key, ccec_ctx_init(cp, fullkey); size_t pubSize = ccec_export_pub_size(ccec_ctx_pub(fullkey)); - require(pubSize < (size_t) keyDataLength, abort); + require_quiet(pubSize < (size_t) keyDataLength, abort); require_noerr_action_quiet(ccec_import_pub(cp, pubSize, keyData, ccec_ctx_pub(fullkey)), abort, err = errSecDecode); @@ -759,13 +746,13 @@ OSStatus SecECKeyGeneratePair(CFDictionaryRef parameters, SecKeyRef privKey = SecKeyCreate(allocator, &kSecECPrivateKeyDescriptor, (const void*) parameters, 0, kSecGenerateKey); - require(privKey, errOut); + require_quiet(privKey, errOut); /* Create SecKeyRef's from the pkcs1 encoded keys. */ pubKey = SecKeyCreate(allocator, &kSecECPublicKeyDescriptor, privKey->key, 0, kSecExtractPublicFromPrivate); - require(pubKey, errOut); + require_quiet(pubKey, errOut); if (publicKey) { *publicKey = pubKey; diff --git a/OSX/sec/Security/SecEMCS.m b/OSX/sec/Security/SecEMCS.m index 6facd618..daa5b0a3 100644 --- a/OSX/sec/Security/SecEMCS.m +++ b/OSX/sec/Security/SecEMCS.m @@ -123,17 +123,8 @@ CreateDerivedKey(CFDataRef salt, long iterations, NSString *managedCredential) * Assume users use the same normalization rules always */ - CFIndex strLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength((__bridge CFStringRef)managedCredential), kCFStringEncodingUTF8); - strLength += 1; - char buffer[strLength]; - if (!CFStringGetCString((__bridge CFStringRef)managedCredential, buffer, strLength, kCFStringEncodingUTF8)) { - return NULL; - } - - CFMutableDataRef key = CFDataCreateMutable(SecCFAllocatorZeroize(), KEY_LENGTH); if (key == NULL) { - memset_s(buffer, strLength, 0, strLength); return NULL; } @@ -141,11 +132,10 @@ CreateDerivedKey(CFDataRef salt, long iterations, NSString *managedCredential) int ret; ret = ccpbkdf2_hmac(ccsha256_di(), - strlen(buffer), buffer, + strlen(managedCredential.UTF8String), managedCredential.UTF8String, CFDataGetLength(salt), CFDataGetBytePtr(salt), iterations, KEY_LENGTH, CFDataGetMutableBytePtr(key)); - memset_s(buffer, strLength, 0, strLength); if (ret) { CFRelease(key); return NULL; diff --git a/OSX/sec/Security/SecExports.exp-in b/OSX/sec/Security/SecExports.exp-in index 0cae30c6..20fa2fd8 100644 --- a/OSX/sec/Security/SecExports.exp-in +++ b/OSX/sec/Security/SecExports.exp-in @@ -137,6 +137,7 @@ _SecPolicyCheckCertSubjectCountry _SecPolicyCopyProperties _SecPolicyCreate +_SecPolicyCreateiAPSWAuthWithExpiration _SecPolicyCreateWithProperties _SecPolicyGetName _SecPolicyGetOidString @@ -227,6 +228,7 @@ _SecTrustCreateWithCertificates _SecTrustDeserialize _SecTrustEvaluate _SecTrustEvaluateAsync +_SecTrustEvaluateFastAsync _SecTrustEvaluateLeafOnly _SecTrustEvaluateWithError _SecTrustFlushResponseCache @@ -351,12 +353,14 @@ _SecCertificateCopyEscrowRoots _SecCertificateCopyExtendedKeyUsage _SecCertificateCopyExtensionValue _SecCertificateCopyiAPAuthCapabilities +_SecCertificateCopyiAPSWAuthCapabilities _SecCertificateCopyIPAddresses _SecCertificateCopyIPAddressesFromSubject _SecCertificateCopyiPhoneDeviceCAChain _SecCertificateCopyIssuerSHA1Digest _SecCertificateCopyIssuerSequence _SecCertificateCopyIssuerSummary +_SecCertificateCopyKey _SecCertificateCopyKeychainItem _SecCertificateCopyLegacyProperties _SecCertificateCopyNormalizedIssuerSequence @@ -654,6 +658,7 @@ _gTrustd _kSecXPCKeyPeerInfoArray _kSecXPCKeyPeerInfo +_kSecXPCKeySignInAnalytics _kSecXPCKeyOperation _kSecXPCKeyResult _kSecXPCKeyEndpoint @@ -708,6 +713,7 @@ _CMSEncoderAddSignedAttributes _CMSEncoderSetSigningTime _CMSEncoderSetAppleCodesigningHashAgility _CMSEncoderSetAppleCodesigningHashAgilityV2 +_CMSEncoderSetAppleExpirationTime _CMSEncoderSetCertificateChainMode _CMSEncoderGetCertificateChainMode _CMSEncoderUpdateContent @@ -731,6 +737,7 @@ _CMSDecoderCopySignerCert _CMSDecoderCopySignerSigningTime _CMSDecoderCopySignerAppleCodesigningHashAgility _CMSDecoderCopySignerAppleCodesigningHashAgilityV2 +_CMSDecoderCopySignerAppleExpirationTime _SecCMSCertificatesOnlyMessageCopyCertificates _SecCMSCreateCertificatesOnlyMessage _SecCMSCreateCertificatesOnlyMessageIAP @@ -814,6 +821,7 @@ _SecCmsSignedDataVerifyCertsOnly _SecCmsSignedDataVerifySignerInfo _SecCmsSignerInfoAddAppleCodesigningHashAgility _SecCmsSignerInfoAddAppleCodesigningHashAgilityV2 +_SecCmsSignerInfoAddAppleExpirationTime _SecCmsSignerInfoAddCounterSignature _SecCmsSignerInfoAddMSSMIMEEncKeyPrefs _SecCmsSignerInfoAddSMIMECaps @@ -823,6 +831,7 @@ _SecCmsSignerInfoCreate _SecCmsSignerInfoCreateWithSubjKeyID _SecCmsSignerInfoGetAppleCodesigningHashAgility _SecCmsSignerInfoGetAppleCodesigningHashAgilityV2 +_SecCmsSignerInfoGetAppleExpirationTime _SecCmsSignerInfoGetCertList _SecCmsSignerInfoGetDigestAlg _SecCmsSignerInfoGetDigestAlgTag @@ -842,6 +851,7 @@ _kSecCMSCertChainMode _kSecCMSCertChainModeNone _kSecCMSEncryptionAlgorithmAESCBC _kSecCMSEncryptionAlgorithmDESCBC +_kSecCMSExpirationDate _kSecCMSHashAgility _kSecCMSHashAgilityV2 _kSecCMSHashingAlgorithmMD5 @@ -950,6 +960,7 @@ _SecCmsSignedDataVerifyCertsOnly _SecCmsSignedDataVerifySignerInfo _SecCmsSignerInfoAddAppleCodesigningHashAgility _SecCmsSignerInfoAddAppleCodesigningHashAgilityV2 +_SecCmsSignerInfoAddAppleExpirationTime _SecCmsSignerInfoAddCounterSignature _SecCmsSignerInfoAddMSSMIMEEncKeyPrefs _SecCmsSignerInfoAddSMIMECaps @@ -961,6 +972,7 @@ _SecCmsSignerInfoCreateWithSubjKeyID _SecCmsSignerInfoDestroy _SecCmsSignerInfoGetAppleCodesigningHashAgility _SecCmsSignerInfoGetAppleCodesigningHashAgilityV2 +_SecCmsSignerInfoGetAppleExpirationTime _SecCmsSignerInfoGetCertList _SecCmsSignerInfoGetDigestAlg _SecCmsSignerInfoGetDigestAlgTag @@ -988,6 +1000,7 @@ _kSecCMSBulkEncryptionAlgorithm _kSecCMSCertChainMode _kSecCMSEncryptionAlgorithmAESCBC _kSecCMSEncryptionAlgorithmDESCBC +_kSecCMSExpirationDate _kSecCMSHashAgility _kSecCMSHashAgilityV2 _kSecCMSHashingAlgorithmSHA1 @@ -1027,21 +1040,18 @@ _SecKeyFromPassphraseDataHMACSHA256 // Key // _CreatePrivateKeyMatchingQuery -#if TARGET_OS_IPHONE _SecECDoWithFullKey _SecECDoWithPubKey -#endif _SecECKeyCopyPublicBits _SecECKeyGetNamedCurve +_SecKeyControlLifetime _SecKeyCopyAttestationKey -#if TARGET_OS_IPHONE _SecKeyCopyAttributeDictionary _SecKeyCreatePublicFromDER _SecKeyGeneratePrivateAttributeDictionary _SecKeyGeneratePublicAttributeDictionary -#endif /* TARGET_OS_IPHONE */ _SecKeyCopyAttributes _SecKeyCopyExponent _SecKeyCopyExternalRepresentation @@ -1074,13 +1084,9 @@ _SecKeyCreatePair #endif /* TARGET_OS_OSX */ _SecKeyCreatePersistentRefToMatchingPrivateKey _SecKeyCreatePublicFromPrivate -#if TARGET_OS_IPHONE _SecKeyCreateRSAPrivateKey -#endif /* TARGET_OS_IPHONE */ _SecKeyCreateRSAPublicKey -#if TARGET_OS_IPHONE _SecKeyCreateRSAPublicKey_ios -#endif /* TARGET_OS_IPHONE */ _SecKeyCreateRandomKey _SecKeyCreateSignature #if TARGET_OS_OSX @@ -1091,17 +1097,13 @@ _SecKeyDecrypt #if TARGET_OS_OSX _SecKeyDeriveFromPassword #endif -#if TARGET_OS_IPHONE _SecKeyDigestAndSign -#endif /* TARGET_OS_IPHONE */ _SecKeyDigestAndVerify _SecKeyEncrypt #if TARGET_OS_OSX _SecKeyGenerate #endif -#if TARGET_OS_IPHONE _SecKeyFindWithPersistentRef -#endif /* TARGET_OS_IPHONE */ _SecKeyGeneratePair #if TARGET_OS_OSX _SecKeyGeneratePairAsync @@ -1109,9 +1111,6 @@ _SecKeyGenerateSymmetric #endif /* TARGET_OS_OSX */ _SecKeyGetAlgorithmID _SecKeyGetAlgorithmId -#if TARGET_OS_IPHONE -_SecKeyGetAlgorithmIdentifier -#endif /* TARGET_OS_IPHONE */ _SecKeyGetBlockSize #if TARGET_OS_OSX _SecKeyGetCSPHandle @@ -1144,7 +1143,6 @@ _SecKeyVerifySignature #if TARGET_OS_OSX _SecKeyWrapSymmetric #endif -#if TARGET_OS_IPHONE __SecKeyCopyUnwrapKey __SecKeyCopyWrapKey __kSecKeyWrapPGPFingerprint @@ -1153,7 +1151,6 @@ __kSecKeyWrapPGPWrapAlg __kSecKeyWrapRFC6637Flags __kSecKeyWrapRFC6637WrapDigestSHA256KekAES128 __kSecKeyWrapRFC6637WrapDigestSHA512KekAES256 -#endif /* TARGET_OS_IPHONE */ _kSecKeyAlgorithmECDHKeyExchangeCofactor _kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1 _kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224 @@ -1241,10 +1238,10 @@ _kSecKeyAttributeName _kSecKeyKeyExchangeParameterRequestedSize _kSecKeyKeyExchangeParameterSharedInfo _kSecKeyParameterSETokenAttestationNonce -#if TARGET_OS_IPHONE _kSecPrivateKeyAttrs _kSecPublicKeyAttrs -#endif /* TARGET_OS_IPHONE */ + +.objc_class_name_SecKeyProxy // // Keychain/SecItem @@ -1580,6 +1577,7 @@ _kSecReturnAttributes _kSecReturnData _kSecReturnPersistentRef _kSecReturnRef +_kSecUseCertificatesWithMatchIssuers _SecItemAdd _SecItemCertificateExists _SecItemCopyDisplayNames @@ -1588,8 +1586,8 @@ _SecItemCopyParentCertificates_ios _SecItemDelete #if TARGET_OS_IPHONE _SecItemDeleteAll -_SecItemUpdateWithError #endif +_SecItemUpdateWithError _SecItemUpdate __SecItemAddAndNotifyOnSync _SecItemSetCurrentItemAcrossAllDevices @@ -1640,6 +1638,7 @@ _SecItemDeleteAllWithAccessGroups _SecTokenItemValueCopy __SecSecuritydCopyCKKSEndpoint +__SecSecuritydCopySFKeychainEndpoint __SecSecuritydCopyKeychainControlEndpoint #if TARGET_OS_IPHONE @@ -1655,9 +1654,6 @@ _kSecXPCPublicPeerId _kSecXPCOTRSession _kSecXPCData _kSecXPCOTRReady -_kSecXPCKeyDeviceID -_kSecXPCKeyIDSMessage -_kSecXPCKeySendIDSMessage #endif _SecCertificateXPCArrayCopyArray @@ -1735,3 +1731,80 @@ _kSecCFErrorResourceMissing // Custom CFAllocators // _SecCFAllocatorZeroize + + +// +// SecProtocol +// +_sec_array_create +_sec_array_append +_sec_array_get_count +_sec_array_apply +_sec_certificate_copy_ref +_sec_certificate_create +_sec_identity_copy_ref +_sec_identity_copy_certificates_ref +_sec_identity_create +_sec_identity_create_with_certificates +_sec_tls_extension_create +_sec_tls_extension_copy_add_block +_sec_tls_extension_copy_free_block +_sec_tls_extension_copy_parse_block +_sec_tls_extension_get_type +_sec_protocol_metadata_create_secret +_sec_protocol_metadata_create_secret_with_context +_sec_protocol_metadata_access_distinguished_names +_sec_protocol_metadata_access_ocsp_response +_sec_protocol_metadata_access_peer_certificate_chain +_sec_protocol_metadata_copy_peer_public_key +_sec_protocol_metadata_access_supported_signature_algorithms +_sec_protocol_metadata_get_negotiated_ciphersuite +_sec_protocol_metadata_get_negotiated_protocol +_sec_protocol_metadata_get_negotiated_protocol_version +_sec_protocol_metadata_get_early_data_accepted +_sec_protocol_metadata_peers_are_equal +_sec_protocol_metadata_challenge_parameters_are_equal +_sec_protocol_metadata_get_session_renewed +_sec_protocol_metadata_get_session_resumed +_sec_protocol_metadata_get_ticket_offered +_sec_protocol_metadata_get_ticket_received +_sec_protocol_metadata_get_tls_false_start_used +_sec_protocol_options_add_tls_application_protocol +_sec_protocol_options_add_tls_ciphersuite +_sec_protocol_options_add_tls_ciphersuite_group +_sec_protocol_options_add_pre_shared_key +_sec_protocol_options_set_challenge_block +_sec_protocol_options_set_key_update_block +_sec_protocol_options_set_local_identity +_sec_protocol_options_set_tls_early_data_enabled +_sec_protocol_options_set_tls_false_start_enabled +_sec_protocol_options_set_tls_max_version +_sec_protocol_options_set_tls_min_version +_sec_protocol_options_set_tls_ocsp_enabled +_sec_protocol_options_set_tls_renegotiation_enabled +_sec_protocol_options_set_tls_resumption_enabled +_sec_protocol_options_set_tls_sct_enabled +_sec_protocol_options_set_tls_server_name +_sec_protocol_options_set_tls_sni_disabled +_sec_protocol_options_set_enforce_ev +_sec_protocol_options_set_tls_tickets_enabled +_sec_protocol_options_set_tls_is_fallback_attempt +_sec_protocol_options_set_verify_block +_sec_protocol_options_set_tls_diffie_hellman_parameters +_sec_protocol_options_set_peer_authentication_required +_sec_protocol_options_add_tls_extension +_sec_release +_sec_retain +_sec_trust_copy_ref +_sec_trust_create + +// +// SecureTransport +// +_SSLCiphersuiteGroupToCiphersuiteList +_SSLCiphersuiteMaximumTLSVersion +_SSLCiphersuiteMinimumTLSVersion + +#if __OBJC2__ && (TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__)) +_OBJC_CLASS_$_SFSignInAnalytics +#endif //__OBJC2__ && IPHONE || OSX diff --git a/OSX/sec/Security/SecFramework.c b/OSX/sec/Security/SecFramework.c index 25e219d1..826d1836 100644 --- a/OSX/sec/Security/SecFramework.c +++ b/OSX/sec/Security/SecFramework.c @@ -45,19 +45,11 @@ #include #include -#if !(TARGET_IPHONE_SIMULATOR && defined(IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED) && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090) -#include -#define USE_GUARDED_OPEN 1 -#else -#define USE_GUARDED_OPEN 0 -#endif - - /* Security.framework's bundle id. */ #if TARGET_OS_IPHONE -static CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.Security"); +CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.Security"); #else -static CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.security"); +CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.security"); #endif CFGiblisGetSingleton(CFBundleRef, SecFrameworkGetBundle, bundle, ^{ @@ -105,67 +97,3 @@ CFDataRef SecFrameworkCopyResourceContents(CFStringRef resourceName, return data; } - -static CFStringRef copyErrorMessageFromBundle(OSStatus status, CFStringRef tableName); - -// caller MUST release the string, since it is gotten with "CFCopyLocalizedStringFromTableInBundle" -// intended use of reserved param is to pass in CFStringRef with name of the Table for lookup -// Will look by default in "SecErrorMessages.strings" in the resources of Security.framework. - - -CFStringRef -SecCopyErrorMessageString(OSStatus status, void *reserved) -{ - CFStringRef result = copyErrorMessageFromBundle(status, CFSTR("SecErrorMessages")); - if (!result) - result = copyErrorMessageFromBundle(status, CFSTR("SecDebugErrorMessages")); - - if (!result) - { - // no error message found, so format a faked-up error message from the status - result = CFStringCreateWithFormat(NULL, NULL, CFSTR("OSStatus %d"), (int)status); - } - - return result; -} - -CFStringRef -copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName) -{ - - CFStringRef errorString = nil; - CFStringRef keyString = nil; - CFBundleRef secBundle = NULL; - - // Make a bundle instance using the URLRef. - secBundle = CFBundleGetBundleWithIdentifier(kSecFrameworkBundleID); - if (!secBundle) - goto exit; - - // Convert status to Int32 string representation, e.g. "-25924" - keyString = CFStringCreateWithFormat (kCFAllocatorDefault, NULL, CFSTR("%d"), (int)status); - if (!keyString) - goto exit; - - errorString = CFCopyLocalizedStringFromTableInBundle(keyString, tableName, secBundle, NULL); - if (CFStringCompare(errorString, keyString, 0) == kCFCompareEqualTo) // no real error message - { - if (errorString) - CFRelease(errorString); - errorString = nil; - } -exit: - if (keyString) - CFRelease(keyString); - - return errorString; -} - - -const SecRandomRef kSecRandomDefault = NULL; - -int SecRandomCopyBytes(SecRandomRef rnd, size_t count, void *bytes) { - if (rnd != kSecRandomDefault) - return errSecParam; - return CCRandomCopyBytes(kCCRandomDefault, bytes, count); -} diff --git a/OSX/sec/Security/SecFramework.h b/OSX/sec/Security/SecFramework.h index a0ef0442..57585fed 100644 --- a/OSX/sec/Security/SecFramework.h +++ b/OSX/sec/Security/SecFramework.h @@ -68,6 +68,8 @@ CFDataRef SecDigestCreate(CFAllocatorRef allocator, // Wrapper to provide a CFErrorRef for legacy API. OSStatus SecOSStatusWith(bool (^perform)(CFErrorRef *error)); +extern CFStringRef kSecFrameworkBundleID; + __END_DECLS #endif /* !_SECURITY_SECFRAMEWORK_H_ */ diff --git a/OSX/sec/Security/SecFrameworkStrings.h b/OSX/sec/Security/SecFrameworkStrings.h index 9d0cabc0..774afb92 100644 --- a/OSX/sec/Security/SecFrameworkStrings.h +++ b/OSX/sec/Security/SecFrameworkStrings.h @@ -239,16 +239,18 @@ __BEGIN_DECLS #define SEC_CK_REMINDER_BUTTON_OK SecStringWithDefaultValue("OK", "CloudKeychain", 0, "OK", "Button label to acknowledge/dismiss reminder alert without further action") /* Trust errors */ -#define SEC_INVALID_LINKAGE_KEY SecStringWithDefaultValue("Invalid certificate chain linkage.", "Certificate", 0, "Invalid certificate chain linkage.", "") -#define SEC_BAD_CRIT_EXTN_KEY SecStringWithDefaultValue("One or more unsupported critical extensions found.", "Certificate", 0, "One or more unsupported critical extensions found.", "") -#define SEC_ROOT_UNTRUSTED_KEY SecStringWithDefaultValue("Root certificate is not trusted.", "Certificate", 0, "Root certificate is not trusted.", "") -#define SEC_HOSTNAME_MISMATCH_KEY SecStringWithDefaultValue("Hostname mismatch.", "Certificate", 0, "Hostname mismatch.", "") -#define SEC_POLICY__REQ_NOT_MET_KEY SecStringWithDefaultValue("Policy requirements not met.", "Certificate", 0, "Policy requirements not met.", "") -#define SEC_CHAIN_VALIDITY_ERR_KEY SecStringWithDefaultValue("One or more certificates have expired or are not valid yet.", "Certificate", 0, "One or more certificates have expired or are not valid yet.", "") -#define SEC_WEAK_KEY_ERR_KEY SecStringWithDefaultValue("One or more certificates is using a weak key size.", "Certificate", 0, "One or more certificates is using a weak key size.", "") +#define SEC_INVALID_LINKAGE_KEY SecStringWithDefaultValue("Invalid certificate chain linkage.", "Certificate", 0, "Invalid certificate chain linkage.", "") +#define SEC_BAD_CRIT_EXTN_KEY SecStringWithDefaultValue("One or more unsupported critical extensions found.", "Certificate", 0, "One or more unsupported critical extensions found.", "") +#define SEC_ROOT_UNTRUSTED_KEY SecStringWithDefaultValue("Root certificate is not trusted.", "Certificate", 0, "Root certificate is not trusted.", "") +#define SEC_HOSTNAME_MISMATCH_KEY SecStringWithDefaultValue("Hostname mismatch.", "Certificate", 0, "Hostname mismatch.", "") +#define SEC_POLICY__REQ_NOT_MET_KEY SecStringWithDefaultValue("Policy requirements not met.", "Certificate", 0, "Policy requirements not met.", "") +#define SEC_CHAIN_VALIDITY_ERR_KEY SecStringWithDefaultValue("One or more certificates have expired or are not valid yet.", "Certificate", 0, "One or more certificates have expired or are not valid yet.", "") +#define SEC_WEAK_KEY_ERR_KEY SecStringWithDefaultValue("One or more certificates is using a weak key size.", "Certificate", 0, "One or more certificates is using a weak key size.", "") +#define SEC_MISSING_INTERMEDIATE_KEY SecStringWithDefaultValue("Unable to build chain to root certificate.", "Certificate", 0, "Unable to build chain to root certificate.", "") #define SEC_TRUST_CERTIFICATE_ERROR SecStringWithDefaultValue("Certificate %ld “%@” has errors: ", "Trust", 0, "Certificate %ld “%@” has errors: ", "Preface for per-certificate errors") +#define SEC_TRUST_ERROR_SUBTYPE_BLOCKED SecStringWithDefaultValue("“%@” certificate is blocked", "Trust", 0, "“%@” certificate is blocked", "Error for blocked certificates") #define SEC_TRUST_ERROR_SUBTYPE_REVOKED SecStringWithDefaultValue("“%@” certificate is revoked", "Trust", 0, "“%@” certificate is revoked", "Error for revoked certificates") #define SEC_TRUST_ERROR_SUBTYPE_KEYSIZE SecStringWithDefaultValue("“%@” certificate is using a broken key size", "Trust", 0, "“%@” certificate is using a broken key size", "Error for certificates with weak key sizes") #define SEC_TRUST_ERROR_SUBTYPE_WEAKHASH SecStringWithDefaultValue("“%@” certificate is using a broken signature algorithm", "Trust", 0, "“%@” certificate is using a broken signature algorithm", "Error for certificates with weak signature algorithms") diff --git a/OSX/sec/Security/SecItem.c b/OSX/sec/Security/SecItem.c index 41a9f732..6d3b595c 100644 --- a/OSX/sec/Security/SecItem.c +++ b/OSX/sec/Security/SecItem.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include "SOSInternal.h" @@ -188,24 +189,6 @@ static OSStatus osstatus_for_der_error(CFIndex derError) { } } -static OSStatus osstatus_for_ids_error(CFIndex idsError) { - switch (idsError) - { - case kSecIDSErrorNoDeviceID: - return errSecDeviceIDNeeded; - case kSecIDSErrorNotRegistered: - return errSecIDSNotRegistered; - case kSecIDSErrorFailedToSend: - return errSecFailedToSendIDSMessage; - case kSecIDSErrorCouldNotFindMatchingAuthToken: - return errSecDeviceIDNoMatch; - case kSecIDSErrorNoPeersAvailable: - return errSecPeersNotAvailable; - default: - return errSecInternal; - } -} - static OSStatus osstatus_for_localauthentication_error(CFIndex laError) { // Wrap LA error in Sec error. switch (laError) { @@ -258,8 +241,6 @@ OSStatus SecErrorGetOSStatus(CFErrorRef error) { status = osstatus_for_xpc_error(CFErrorGetCode(error)); } else if (CFEqual(sSecDERErrorDomain, domain)) { status = osstatus_for_der_error(CFErrorGetCode(error)); - }else if (CFEqual(kSecIDSErrorDomain, domain)) { - status = osstatus_for_ids_error(CFErrorGetCode(error)); } else if (CFEqual(CFSTR(kLAErrorDomain), domain)) { status = osstatus_for_localauthentication_error(CFErrorGetCode(error)); } else if (CFEqual(CFSTR(kTKErrorDomain), domain)) { @@ -452,12 +433,14 @@ SecItemCreateFromAttributeDictionary(CFDictionaryRef refAttributes) { return ref; } +#if !TARGET_OS_OSX OSStatus SecItemCopyDisplayNames(CFArrayRef items, CFArrayRef *displayNames) { // @@@ TBI return -1 /* errSecUnimplemented */; } +#endif // TARGET_OS_OSX typedef OSStatus (*secitem_operation)(CFDictionaryRef attributes, CFTypeRef *result); @@ -828,11 +811,46 @@ out: return plist; } -TKTokenRef SecTokenCreate(CFStringRef token_id, CFDictionaryRef auth_params, CFErrorRef *error) { +TKTokenRef SecTokenCreate(CFStringRef token_id, SecCFDictionaryCOW *auth_params, CFErrorRef *error) { CFMutableDictionaryRef token_attrs = NULL; TKTokenRef token = NULL; - token_attrs = (auth_params != NULL) ? - CFDictionaryCreateMutableCopy(NULL, 0, auth_params) : + + static CFMutableDictionaryRef sharedLAContexts = NULL; + static dispatch_once_t onceToken; + static os_unfair_lock lock = OS_UNFAIR_LOCK_INIT; + if ((auth_params->dictionary == NULL || CFDictionaryGetValue(auth_params->dictionary, kSecUseCredentialReference) == NULL) && !CFStringHasPrefix(token_id, kSecAttrTokenIDSecureEnclave)) { + dispatch_once(&onceToken, ^{ + sharedLAContexts = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + }); + + os_unfair_lock_lock(&lock); + CFTypeRef ctx = CFDictionaryGetValue(sharedLAContexts, token_id); + if (ctx == nil) { + ctx = LACreateNewContextWithACMContext(NULL, error); + if (!ctx) { + secerror("Failed to create authentication context %@", *error); + return token; + } + CFDictionarySetValue(sharedLAContexts, token_id, ctx); + CFRelease(ctx); + ctx = CFDictionaryGetValue(sharedLAContexts, token_id); + } + + CFDataRef credRef = NULL; + if (ctx != nil) { + credRef = LACopyACMContext(ctx, NULL); + } + + if (credRef) { + CFDictionarySetValue(SecCFDictionaryCOWGetMutable(auth_params), kSecUseAuthenticationContext, ctx); + CFDictionarySetValue(SecCFDictionaryCOWGetMutable(auth_params), kSecUseCredentialReference, credRef); + CFRelease(credRef); + } + os_unfair_lock_unlock(&lock); + } + + token_attrs = (auth_params->dictionary != NULL) ? + CFDictionaryCreateMutableCopy(NULL, 0, auth_params->dictionary) : CFDictionaryCreateMutableForCFTypes(NULL); CFDictionarySetValue(token_attrs, kSecAttrTokenID, token_id); @@ -843,18 +861,19 @@ TKTokenRef SecTokenCreate(CFStringRef token_id, CFDictionaryRef auth_params, CFE return token; } -static bool SecTokenItemCreateFromAttributes(CFDictionaryRef attributes, CFDictionaryRef auth_params, +static bool SecTokenItemCreateFromAttributes(CFDictionaryRef attributes, CFDictionaryRef auth_params_dict, TKTokenRef token, CFDataRef object_id, CFTypeRef *ref, CFErrorRef *error) { bool ok = false; + SecCFDictionaryCOW auth_params = { auth_params_dict }; CFMutableDictionaryRef attrs = CFDictionaryCreateMutableCopy(NULL, 0, attributes); CFTypeRef token_id = CFDictionaryGetValue(attributes, kSecAttrTokenID); if (token_id != NULL && object_id != NULL) { if (CFRetainSafe(token) == NULL) { - require_quiet(token = SecTokenCreate(token_id, auth_params, error), out); + require_quiet(token = SecTokenCreate(token_id, &auth_params, error), out); } - if (auth_params != NULL) { - CFDictionaryForEach(auth_params, ^(const void *key, const void *value) { + if (auth_params.dictionary != NULL) { + CFDictionaryForEach(auth_params.dictionary, ^(const void *key, const void *value) { CFDictionaryAddValue(attrs, key, value); }); } @@ -867,6 +886,7 @@ static bool SecTokenItemCreateFromAttributes(CFDictionaryRef attributes, CFDicti out: CFReleaseSafe(attrs); + CFReleaseSafe(auth_params.mutable_dictionary); return ok; } @@ -874,7 +894,7 @@ out: /* Turn the returned single value or dictionary that contains all the attributes to create a ref into the exact result the client asked for */ static bool SecItemResultCopyPrepared(CFTypeRef raw_result, TKTokenRef token, - CFDictionaryRef query, CFDictionaryRef auth_params, + CFDictionaryRef query, CFDictionaryRef auth_params_dict, CFTypeRef *result, CFErrorRef *error) { bool ok = false; CFDataRef ac_data = NULL; @@ -887,6 +907,7 @@ static bool SecItemResultCopyPrepared(CFTypeRef raw_result, TKTokenRef token, CFDataRef cert_data = NULL; CFDataRef cert_object_id = NULL; TKTokenRef cert_token = NULL; + SecCFDictionaryCOW auth_params = { auth_params_dict }; bool wants_ref = cf_bool_value(CFDictionaryGetValue(query, kSecReturnRef)); bool wants_data = cf_bool_value(CFDictionaryGetValue(query, kSecReturnData)); @@ -934,7 +955,7 @@ static bool SecItemResultCopyPrepared(CFTypeRef raw_result, TKTokenRef token, if ((wants_data || wants_ref) && object_value == NULL) { // Retrieve value directly from the token. if (token == NULL) { - require_quiet(token = SecTokenCreate(token_id, auth_params, error), out); + require_quiet(token = SecTokenCreate(token_id, &auth_params, error), out); } require_quiet(object_value = TKTokenCopyObjectData(token, object_id, error), out); if (CFEqual(object_value, kCFNull)) @@ -1002,7 +1023,7 @@ static bool SecItemResultCopyPrepared(CFTypeRef raw_result, TKTokenRef token, if (cert_data == NULL) { // Retrieve value directly from the token. if (cert_token == NULL) { - require_quiet(cert_token = SecTokenCreate(cert_token_id, auth_params, error), out); + require_quiet(cert_token = SecTokenCreate(cert_token_id, &auth_params, error), out); } require_quiet(cert_data = TKTokenCopyObjectData(cert_token, cert_object_id, error), out); if (CFEqual(cert_data, kCFNull)) @@ -1032,7 +1053,7 @@ static bool SecItemResultCopyPrepared(CFTypeRef raw_result, TKTokenRef token, if (wants_ref) { CFTypeRef ref; - require_quiet(SecTokenItemCreateFromAttributes(output, auth_params, token, object_id, &ref, error), out); + require_quiet(SecTokenItemCreateFromAttributes(output, auth_params.dictionary, token, object_id, &ref, error), out); if (!(wants_attributes || wants_data || wants_persistent_ref)) { CFAssignRetained(*result, ref); } else if (ref != NULL) { @@ -1058,6 +1079,7 @@ out: CFReleaseSafe(attrs); CFReleaseSafe(token); CFReleaseSafe(cert_token); + CFReleaseSafe(auth_params.mutable_dictionary); return ok; } @@ -1224,31 +1246,10 @@ static bool SecItemAuthMaxAttemptsReached(CFArrayRef ac_pairs, CFErrorRef *error } bool SecItemAuthDo(SecCFDictionaryCOW *auth_params, CFErrorRef *error, SecItemAuthResult (^perform)(CFArrayRef *ac_pairs, CFErrorRef *error), - void (^newCredentialRefAdded)()) { + void (^newCredentialRefAdded)(void)) { bool ok = false; CFArrayRef ac_pairs = NULL; SecCFDictionaryCOW auth_options = { NULL }; - // We need to create shared LAContext for Mail to reduce popups with Auth UI. - // This app-hack will be removed by: - // Similar workaround is for Safari, will be removed by fixing - static CFTypeRef sharedLAContext = NULL; - static CFDataRef sharedACMContext = NULL; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - CFBundleRef bundle = CFBundleGetMainBundle(); - CFStringRef bundleName = (bundle != NULL) ? CFBundleGetIdentifier(bundle) : NULL; - if (CFEqualSafe(bundleName, CFSTR("com.apple.mail")) || - CFEqualSafe(bundleName, CFSTR("com.apple.WebKit.Networking"))) { - sharedLAContext = LACreateNewContextWithACMContext(NULL, error); - sharedACMContext = (sharedLAContext != NULL) ? LACopyACMContext(sharedLAContext, error) : NULL; - } - }); - if (sharedLAContext && sharedACMContext && - (auth_params->dictionary == NULL || (CFDictionaryGetValue(auth_params->dictionary, kSecUseAuthenticationContext) == NULL && - CFDictionaryGetValue(auth_params->dictionary, kSecUseCredentialReference) == NULL))) { - CFDictionarySetValue(SecCFDictionaryCOWGetMutable(auth_params), kSecUseAuthenticationContext, sharedLAContext); - CFDictionarySetValue(SecCFDictionaryCOWGetMutable(auth_params), kSecUseCredentialReference, sharedACMContext); - } for (uint32_t i = 0;; ++i) { // If the operation succeeded or failed with other than auth-needed error, just leave. @@ -1444,7 +1445,7 @@ bool SecItemAuthDoQuery(SecCFDictionaryCOW *query, SecCFDictionaryCOW *attribute // Prepare connection to target token if it is present. CFStringRef token_id = CFDictionaryGetValue(query->dictionary, kSecAttrTokenID); if (secItemOperation != SecItemCopyMatching && token_id != NULL) { - require_quiet(CFAssignRetained(token, SecTokenCreate(token_id, auth_params.dictionary, error)), out); + require_quiet(CFAssignRetained(token, SecTokenCreate(token_id, &auth_params, error)), out); } CFDictionaryRef attrs = (attributes != NULL) ? attributes->dictionary : NULL; @@ -2027,20 +2028,6 @@ CFArrayRef _SecKeychainSyncUpdateMessage(CFDictionaryRef updates, CFErrorRef *er return result; } -#ifndef SECITEM_SHIM_OSX -OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement); - -OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement) -{ - return -1; /* this is only on OS X currently */ -} - -#else - -extern OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement); - -#endif - #define do_if_registered(sdp, ...) if (gSecurityd && gSecurityd->sdp) { return gSecurityd->sdp(__VA_ARGS__); } bool _SecKeychainRollKeys(bool force, CFErrorRef *error) diff --git a/OSX/sec/Security/SecItemConstants.c b/OSX/sec/Security/SecItemConstants.c index 799e0c9d..0c1822a8 100644 --- a/OSX/sec/Security/SecItemConstants.c +++ b/OSX/sec/Security/SecItemConstants.c @@ -26,7 +26,7 @@ /* String constant declarations */ -#define SEC_CONST_DECL(k,v) const CFTypeRef k = CFSTR(v); +#define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v); /* Class Key Constant */ SEC_CONST_DECL (kSecClass, "class"); @@ -160,6 +160,7 @@ SEC_CONST_DECL (kSecUseSystemKeychain, "u_SystemKeychain"); SEC_CONST_DECL (kSecUseSyncBubbleKeychain, "u_SyncBubbleKeychain"); SEC_CONST_DECL (kSecUseCallerName, "u_CallerName"); SEC_CONST_DECL (kSecUseTokenRawItems, "u_TokenRawItems"); +SEC_CONST_DECL (kSecUseCertificatesWithMatchIssuers, "u_CertWithIssuers"); /* kSecAttrAccessible Value Constants. */ SEC_CONST_DECL (kSecAttrAccessibleWhenUnlocked, "ak"); diff --git a/OSX/sec/Security/SecItemInternal.h b/OSX/sec/Security/SecItemInternal.h index b4b0ac8e..e94c6d4e 100644 --- a/OSX/sec/Security/SecItemInternal.h +++ b/OSX/sec/Security/SecItemInternal.h @@ -90,14 +90,14 @@ typedef enum { } SecItemAuthResult; bool SecItemAuthDo(SecCFDictionaryCOW *auth_params, CFErrorRef *error, SecItemAuthResult (^perform)(CFArrayRef *ac_pairs, CFErrorRef *error), - void (^newCredentialRefAdded)()); + void (^newCredentialRefAdded)(void)); bool SecItemAuthDoQuery(SecCFDictionaryCOW *query, SecCFDictionaryCOW *attributes, const void *secItemOperation, CFErrorRef *error, bool (^perform)(TKTokenRef token, CFDictionaryRef query, CFDictionaryRef attributes, CFDictionaryRef auth_params, CFErrorRef *error)); void SecItemAuthCopyParams(SecCFDictionaryCOW *auth_params, SecCFDictionaryCOW *query); -TKTokenRef SecTokenCreate(CFStringRef token_id, CFDictionaryRef auth_params, CFErrorRef *error); +TKTokenRef SecTokenCreate(CFStringRef token_id, SecCFDictionaryCOW *auth_params, CFErrorRef *error); CFDictionaryRef SecTokenItemValueCopy(CFDataRef db_value, CFErrorRef *error); diff --git a/OSX/sec/Security/SecKey.c b/OSX/sec/Security/SecKey.c index bf3569fc..3a49b7c4 100644 --- a/OSX/sec/Security/SecKey.c +++ b/OSX/sec/Security/SecKey.c @@ -37,14 +37,15 @@ #include #include +#include "SecKeyPriv.h" #include "SecRSAKeyPriv.h" #include "SecECKeyPriv.h" #include "SecCTKKeyPriv.h" #include "SecBasePriv.h" -#include #include #include +#include #include #include #include @@ -165,7 +166,7 @@ static CFStringRef SecKeyCopyDescription(CFTypeRef cf) { static void SecKeyDestroy(CFTypeRef cf) { SecKeyRef key = (SecKeyRef)cf; -#if !TARGET_OS_IPHONE +#if TARGET_OS_OSX CFReleaseNull(key->cdsaKey); #endif if (key->key_class->destroy) @@ -257,7 +258,7 @@ static CF_RETURNS_RETAINED CFMutableDictionaryRef merge_params(CFDictionaryRef d return result; } -CFIndex SecKeyGetAlgorithmIdentifier(SecKeyRef key) { +CFIndex SecKeyGetAlgorithmId(SecKeyRef key) { if (!key || !key->key_class) { // TBD: somehow, a key can be created with a NULL key_class in the // SecCertificateCopyPublicKey -> SecKeyCreatePublicFromDER code path @@ -498,10 +499,10 @@ CFDataRef SecKeyCopySubjectPublicKeyInfo(SecKeyRef key) memset(&spki, 0, sizeof(spki)); /* encode the public key. */ - require_noerr(SecKeyCopyPublicBytes(key, &publicKey), errOut); + require_noerr_quiet(SecKeyCopyPublicBytes(key, &publicKey), errOut); require_quiet(publicKey, errOut); - require(CFDataGetLength(publicKey) != 0, errOut); + require_quiet(CFDataGetLength(publicKey) != 0, errOut); // Add prefix 00 is needed to avoid creating negative bit strings if (((uint8_t *)CFDataGetBytePtr(publicKey))[0] & 0x80) @@ -521,7 +522,7 @@ CFDataRef SecKeyCopySubjectPublicKeyInfo(SecKeyRef key) spki.pubKey.length = CFDataGetLength(publicKey); // Encode algId according to algorithm used. - CFIndex algorithm = SecKeyGetAlgorithmIdentifier(key); + CFIndex algorithm = SecKeyGetAlgorithmId(key); if (algorithm == kSecRSAAlgorithmID) { spki.algId.data = (DERByte *)oidRSA; spki.algId.length = sizeof(oidRSA); @@ -556,7 +557,7 @@ CFDataRef SecKeyCopySubjectPublicKeyInfo(SecKeyRef key) DERNumSubjPubKeyInfoItemSpecs, DERSubjPubKeyInfoItemSpecs, CFDataGetMutableBytePtr(data), &size); - require(drtn == DR_Success, errOut); + require_quiet(drtn == DR_Success, errOut); CFDataSetLength(data, size); dataret = CFRetain(data); @@ -597,41 +598,53 @@ SecKeyRef SecKeyCreate(CFAllocatorRef allocator, } static SecKeyAlgorithm SecKeyGetSignatureAlgorithmForPadding(SecKeyRef key, SecPadding padding) { - switch (SecKeyGetAlgorithmIdentifier(key)) { - case kSecRSAAlgorithmID: - switch (padding) { - case kSecPaddingNone: - return kSecKeyAlgorithmRSASignatureRaw; - case kSecPaddingPKCS1: - return kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw; -#if TARGET_OS_IPHONE - case kSecPaddingPKCS1SHA1: - return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1; - case kSecPaddingPKCS1SHA224: - return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224; - case kSecPaddingPKCS1SHA256: - return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256; - case kSecPaddingPKCS1SHA384: - return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384; - case kSecPaddingPKCS1SHA512: - return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512; -#else - // On CSSM-based implementation, these functions actually did hash its input, - // so keep doing that for backward compatibility. - case kSecPaddingPKCS1SHA1: - return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1; - case kSecPaddingPKCS1SHA224: - return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224; - case kSecPaddingPKCS1SHA256: - return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256; - case kSecPaddingPKCS1SHA384: - return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384; - case kSecPaddingPKCS1SHA512: - return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512; + switch (SecKeyGetAlgorithmId(key)) { + case kSecRSAAlgorithmID: { +#if TARGET_OS_OSX + if (!_CFMZEnabled()) { + // On CSSM-based implementation, these functions actually did hash its input, + // so keep doing that for backward compatibility. + switch (padding) { + case kSecPaddingNone: + return kSecKeyAlgorithmRSASignatureRaw; + case kSecPaddingPKCS1: + return kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw; + case kSecPaddingPKCS1SHA1: + return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1; + case kSecPaddingPKCS1SHA224: + return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224; + case kSecPaddingPKCS1SHA256: + return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256; + case kSecPaddingPKCS1SHA384: + return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384; + case kSecPaddingPKCS1SHA512: + return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512; + default: + return NULL; + } + } else #endif - default: - return NULL; + { + switch (padding) { + case kSecPaddingNone: + return kSecKeyAlgorithmRSASignatureRaw; + case kSecPaddingPKCS1: + return kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw; + case kSecPaddingPKCS1SHA1: + return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1; + case kSecPaddingPKCS1SHA224: + return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224; + case kSecPaddingPKCS1SHA256: + return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256; + case kSecPaddingPKCS1SHA384: + return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384; + case kSecPaddingPKCS1SHA512: + return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512; + default: + return NULL; + } } + } case kSecECDSAAlgorithmID: switch (padding) { case kSecPaddingSigRaw: @@ -723,7 +736,7 @@ OSStatus SecKeyRawVerify( } static SecKeyAlgorithm SecKeyGetEncryptionAlgorithmForPadding(SecKeyRef key, SecPadding padding) { - switch (SecKeyGetAlgorithmIdentifier(key)) { + switch (SecKeyGetAlgorithmId(key)) { case kSecRSAAlgorithmID: switch (padding) { case kSecPaddingNone: @@ -841,6 +854,10 @@ static SecKeyAlgorithm SecKeyGetAlgorithmForSecAsn1AlgId(SecKeyRef key, const Se [false] = &kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5, [true] = &kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5, } }, + { &CSSMOID_MD5WithRSA, NULL, { + [false] = &kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5, + [true] = &kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5, + } }, { NULL }, }, translationTableECDSA[] = { { &CSSMOID_ECDSA_WithSHA1, &CSSMOID_SHA1, { @@ -867,7 +884,7 @@ static SecKeyAlgorithm SecKeyGetAlgorithmForSecAsn1AlgId(SecKeyRef key, const Se }; const struct TableItem *table; - switch (SecKeyGetAlgorithmIdentifier(key)) { + switch (SecKeyGetAlgorithmId(key)) { case kSecRSAAlgorithmID: table = translationTableRSA; break; @@ -962,18 +979,17 @@ OSStatus SecKeySignDigest( }); } -CFIndex SecKeyGetAlgorithmId(SecKeyRef key) { - return SecKeyGetAlgorithmIdentifier(key); -} - -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)) +#if TARGET_OS_OSX /* On OS X, SecKeyGetAlgorithmID has a different function signature (two arguments, with output in the second argument). Therefore, avoid implementing this function here if compiling for OS X. */ #else +// Export original SecKeyGetAlgorithmID symbol for backward binary compatibility. +#undef SecKeyGetAlgorithmID +CFIndex SecKeyGetAlgorithmID(SecKeyRef key); CFIndex SecKeyGetAlgorithmID(SecKeyRef key) { - return SecKeyGetAlgorithmIdentifier(key); + return SecKeyGetAlgorithmId(key); } #endif @@ -1011,7 +1027,13 @@ size_t SecKeyGetSize(SecKeyRef key, SecKeySize whichSize) { size_t result = SecKeyGetBlockSize(key); - if (kSecECDSAAlgorithmID == SecKeyGetAlgorithmIdentifier(key)) { + if (whichSize == 0 || whichSize == 10) { + // kSecKeyKeySizeInBits is declared as 0 on iOS (SPI) and 10 on macOS (API). Unified implementation + // here deals with both values. + whichSize = kSecKeyKeySizeInBits; + } + + if (kSecECDSAAlgorithmID == SecKeyGetAlgorithmId(key)) { switch (whichSize) { case kSecKeyEncryptedDataSize: result = 0; @@ -1292,7 +1314,7 @@ CFDictionaryRef SecKeyCopyAttributes(SecKeyRef key) { CFRelease(blockSizeRef); } - switch (SecKeyGetAlgorithmIdentifier(key)) { + switch (SecKeyGetAlgorithmId(key)) { case kSecRSAAlgorithmID: CFDictionarySetValue(dict, kSecAttrKeyType, kSecAttrKeyTypeRSA); break; @@ -1325,7 +1347,7 @@ SecKeyRef SecKeyCopyPublicKey(SecKeyRef key) { require_noerr_quiet(SecKeyCopyPublicBytes(key, &serializedPublic), fail); require_quiet(serializedPublic, fail); - result = SecKeyCreateFromPublicData(kCFAllocatorDefault, SecKeyGetAlgorithmIdentifier(key), serializedPublic); + result = SecKeyCreateFromPublicData(kCFAllocatorDefault, SecKeyGetAlgorithmId(key), serializedPublic); fail: CFReleaseSafe(serializedPublic); @@ -1393,7 +1415,7 @@ static CFTypeRef SecKeyCopyBackendOperationResult(SecKeyOperationContext *contex { &kSecKeyAlgorithmRSAEncryptionOAEPSHA1, kSecRSAAlgorithmID, kSecPaddingOAEP }, }; SecPadding padding = (SecPadding)-1; - CFIndex keyAlg = SecKeyGetAlgorithmIdentifier(context->key); + CFIndex keyAlg = SecKeyGetAlgorithmId(context->key); for (size_t i = 0; i < array_size(paddingMap); ++i) { if (keyAlg == paddingMap[i].keyAlg && CFEqual(algorithm, *paddingMap[i].algorithm)) { padding = paddingMap[i].padding; diff --git a/OSX/sec/Security/SecKeyAdaptors.c b/OSX/sec/Security/SecKeyAdaptors.m similarity index 99% rename from OSX/sec/Security/SecKeyAdaptors.c rename to OSX/sec/Security/SecKeyAdaptors.m index 8a7861f5..4c369591 100644 --- a/OSX/sec/Security/SecKeyAdaptors.c +++ b/OSX/sec/Security/SecKeyAdaptors.m @@ -22,12 +22,14 @@ */ /* - * SecKeyAdaptors.c - Implementation of assorted algorithm adaptors for SecKey. + * SecKeyAdaptors.m - Implementation of assorted algorithm adaptors for SecKey. * Algorithm adaptor is able to perform some transformation on provided input and calculated results and invoke * underlying operation with different algorithm. Typical adaptors are message->digest or unpadded->padded. * To invoke underlying operation, add algorithm to the context algorithm array and invoke SecKeyRunAlgorithmAndCopyResult(). */ +#import + #include #include #include @@ -310,20 +312,22 @@ static CFTypeRef SecKeyRSACopyEMSASignature(SecKeyOperationContext *context, return NULL; } PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) { - uint8_t s[size]; + NSMutableData *s = [NSMutableData dataWithLength:size]; + require_action_quiet(s != nil, out, SecError(errSecAllocate, error, CFSTR("out of memory"))); if (pss) { - uint8_t salt[di->output_size]; - int err = ccrng_generate(ccrng_seckey, di->output_size, salt); + NSMutableData *salt = [NSMutableData dataWithLength:di->output_size]; + require_action_quiet(salt != nil, out, SecError(errSecAllocate, error, CFSTR("out of memory"))); + int err = ccrng_generate(ccrng_seckey, di->output_size, salt.mutableBytes); require_noerr_action_quiet(err, out, SecError(errSecInternal, error, CFSTR("PSS salt gen fail (%zu bytes), err %d"), di->output_size, err)); - err = ccrsa_emsa_pss_encode(di, di, di->output_size, salt, - CFDataGetLength(in1), CFDataGetBytePtr(in1), size * 8 - 1, s); + err = ccrsa_emsa_pss_encode(di, di, di->output_size, salt.bytes, + CFDataGetLength(in1), CFDataGetBytePtr(in1), size * 8 - 1, s.mutableBytes); require_noerr_action_quiet(err, out, SecError(errSecParam, error, CFSTR("RSASSA-PSS incompatible algorithm for key size"))); } else { - int err = ccrsa_emsa_pkcs1v15_encode(size, s, CFDataGetLength(in1), CFDataGetBytePtr(in1), di ? di->oid : NULL); + int err = ccrsa_emsa_pkcs1v15_encode(size, s.mutableBytes, CFDataGetLength(in1), CFDataGetBytePtr(in1), di ? di->oid : NULL); require_noerr_action_quiet(err, out, SecError(errSecParam, error, CFSTR("RSAsign wrong input data length"))); } - ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, size, s); + ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, size, s.bytes); require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, data, NULL, error), out); CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key))); out:; diff --git a/OSX/sec/Security/SecKeyInternal.h b/OSX/sec/Security/SecKeyInternal.h index 9266ecec..3f62f920 100644 --- a/OSX/sec/Security/SecKeyInternal.h +++ b/OSX/sec/Security/SecKeyInternal.h @@ -36,7 +36,6 @@ __BEGIN_DECLS extern struct ccrng_state *ccrng_seckey; -CFIndex SecKeyGetAlgorithmIdentifier(SecKeyRef key); enum { // Keep in sync with SecKeyOperationType enum in SecKey.h diff --git a/OSX/sec/Security/SecKeyProxy.m b/OSX/sec/Security/SecKeyProxy.m new file mode 100644 index 00000000..94855948 --- /dev/null +++ b/OSX/sec/Security/SecKeyProxy.m @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2006-2015 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@ + */ + +/* + * SecKeyProxy.m - Remote access to SecKey instance + */ + +#import +#import + +#include +#include +#include +#include +#include + +#include + +// MARK: XPC-level protocol for communication between server and client. +@protocol SecKeyProxyProtocol +- (void)initializeWithReply:(void (^)(NSData * _Nullable certificate))reply; +- (void)getBlockSizeWithReply:(void (^)(size_t blockSize))reply; +- (void)getAttributesWithReply:(void (^)(NSDictionary *attributes))reply; +- (void)getExternalRepresentationWithReply:(void (^)(NSData *data, NSError *error))reply; +- (void)getDescriptionWithReply:(void (^)(NSString *description))reply; +- (void)getAlgorithmIDWithReply:(void (^)(NSInteger algorithmID))reply; +- (void)getPublicKey:(void (^)(NSXPCListenerEndpoint *endpoint))reply; +- (void)performOperation:(SecKeyOperationType)operation algorithm:(NSString *)algorithm parameters:(NSArray *)parameters reply:(void (^)(NSArray *result, NSError *error))reply; +@end + +// MARK: XPC target object for SecKeyProxy side +// Logically could be embedded in SecKeyProxy, but that would cause ownership cycles, since target object is always owned by its associated XPC connection. +@interface SecKeyProxyTarget : NSObject { + id _key; + NSData *_certificate; + SecKeyProxy *_publicKeyProxy; +} +- (instancetype)initWithKey:(id)key certificate:(nullable NSData *)certificate; +@property (readonly, nonatomic) SecKeyRef key; +@end + +@implementation SecKeyProxyTarget +- (instancetype)initWithKey:(id)key certificate:(nullable NSData *)certificate { + if (self = [super init]) { + _key = key; + _certificate = certificate; + } + return self; +} + +- (SecKeyRef)key { + return (__bridge SecKeyRef)_key; +} + +- (void)initializeWithReply:(void (^)(NSData *_Nullable))reply { + return reply(_certificate); +} + +- (void)getBlockSizeWithReply:(void (^)(size_t))reply { + return reply(SecKeyGetBlockSize(self.key)); +} + +- (void)getAttributesWithReply:(void (^)(NSDictionary *))reply { + return reply(CFBridgingRelease(SecKeyCopyAttributes(self.key))); +} + +- (void)getExternalRepresentationWithReply:(void (^)(NSData *, NSError *))reply { + NSError *error; + NSData *data = CFBridgingRelease(SecKeyCopyExternalRepresentation(self.key, (void *)&error)); + return reply(data, error); +} + +- (void)getDescriptionWithReply:(void (^)(NSString *))reply { + NSString *description = CFBridgingRelease(CFCopyDescription(self.key)); + + // Strip wrapping "" if present. + if ([description hasPrefix:@""]) { + description = [description substringWithRange:NSMakeRange(11, description.length - 12)]; + } else if ([description hasPrefix:@""]) { + description = [description substringWithRange:NSMakeRange(12, description.length - 13)]; + } + + return reply(description); +} + +- (void)getAlgorithmIDWithReply:(void (^)(NSInteger))reply { + return reply(SecKeyGetAlgorithmId(self.key)); +} + +- (void)getPublicKey:(void (^)(NSXPCListenerEndpoint *endpoint))reply { + if (_publicKeyProxy == nil) { + id publicKey = CFBridgingRelease(SecKeyCopyPublicKey(self.key)); + if (publicKey == nil) { + return reply(nil); + } + _publicKeyProxy = [[SecKeyProxy alloc] initWithKey:(__bridge SecKeyRef)publicKey]; + } + return reply(_publicKeyProxy.endpoint); +} + +- (void)performOperation:(SecKeyOperationType)operation algorithm:(NSString *)algorithm parameters:(NSArray *)parameters reply:(void (^)(NSArray *, NSError *))reply { + NSMutableArray *algorithms = @[algorithm].mutableCopy; + CFTypeRef in1 = (__bridge CFTypeRef)(parameters.count > 0 ? parameters[0] : nil); + CFTypeRef in2 = (__bridge CFTypeRef)(parameters.count > 1 ? parameters[1] : nil); + NSError *error; + SecKeyOperationContext context = { self.key, operation, (__bridge CFMutableArrayRef)algorithms }; + id result = CFBridgingRelease(SecKeyRunAlgorithmAndCopyResult(&context, in1, in2, (void *)&error)); + return reply(result ? @[result] : @[], error); +} +@end + +// MARK: SecKeyProxy implementation +@interface SecKeyProxy() +@end + +@implementation SecKeyProxy +- (instancetype)initWithKey:(SecKeyRef)key certificate:(nullable NSData *)certificate { + if (self = [super init]) { + _key = CFBridgingRelease(CFRetain(key)); + _certificate = certificate; + _listener = [NSXPCListener anonymousListener]; + _listener.delegate = self; + + // All connections created to this proxy instance are serialized to this single queue. + [_listener _setQueue: dispatch_queue_create("SecKeyProxy", NULL)]; + [_listener resume]; + } + + return self; +} + +- (instancetype)initWithKey:(SecKeyRef)key { + return [self initWithKey:key certificate:nil]; +} + +- (instancetype)initWithIdentity:(SecIdentityRef)identity { + id key; + id certificate; + SecIdentityCopyPrivateKey(identity, (void *)&key); + SecIdentityCopyCertificate(identity, (void *)&certificate); + if (key == nil && certificate == nil) { + return nil; + } + + // Extract data from the certificate. + NSData *certificateData = CFBridgingRelease(SecCertificateCopyData((SecCertificateRef)certificate)); + if (certificateData == nil) { + return nil; + } + + return [self initWithKey:(__bridge SecKeyRef)key certificate:certificateData]; +} + +- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { + newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SecKeyProxyProtocol)]; + newConnection.exportedObject = [[SecKeyProxyTarget alloc] initWithKey:_key certificate:_certificate]; + [newConnection _setQueue:[_listener _queue]]; + [newConnection resume]; + return YES; +} + +- (void)invalidate { + [_listener invalidate]; +} + +- (void)dealloc { + [self invalidate]; +} + +- (NSXPCListenerEndpoint *)endpoint { + return _listener.endpoint; +} + +// MARK: Client side: remote-connected SecKey instance. +static OSStatus SecRemoteKeyInit(SecKeyRef key, const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) { + // keyData and key->key are both actually type-punned NSXPCConnection owning pointers. + key->key = (void *)keyData; + return errSecSuccess; +} + +static void SecRemoteKeyDestroy(SecKeyRef key) { + NSXPCConnection *conn = CFBridgingRelease(key->key); + [conn invalidate]; +} + ++ (id)targetForKey:(SecKeyRef)key error:(CFErrorRef *)error { + NSXPCConnection *connection = (__bridge NSXPCConnection *)key->key; + id result = [connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull _error) { + if (error != NULL) { + *error = (__bridge_retained CFErrorRef)_error; + } + }]; + return result; +} + +static size_t SecRemoteKeyBlockSize(SecKeyRef key) { + __block size_t localBlockSize = 0; + [[SecKeyProxy targetForKey:key error:NULL] getBlockSizeWithReply:^(size_t blockSize) { + localBlockSize = blockSize; + }]; + return localBlockSize; +} + +static CFDictionaryRef SecRemoteKeyCopyAttributeDictionary(SecKeyRef key) { + __block NSDictionary *localAttributes; + [[SecKeyProxy targetForKey:key error:NULL] getAttributesWithReply:^(NSDictionary *attributes) { + localAttributes = attributes; + }]; + return CFBridgingRetain(localAttributes); +} + +static CFDataRef SecRemoteKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error) { + __block NSData *localData; + __block NSError *localError; + [[SecKeyProxy targetForKey:key error:error] getExternalRepresentationWithReply:^(NSData *data, NSError *error) { + localData = data; + localError = error; + }]; + if (localData == nil && error != NULL) { + *error = (__bridge_retained CFErrorRef)localError; + } + return CFBridgingRetain(localData); +} + +static CFStringRef SecRemoteKeyCopyDescription(SecKeyRef key) { + __block NSString *localDescription; + [[SecKeyProxy targetForKey:key error:NULL] getDescriptionWithReply:^(NSString *description) { + localDescription = [NSString stringWithFormat:@"", description]; + }]; + return CFBridgingRetain(localDescription); +} + +static CFIndex SecRemoteKeyGetAlgorithmID(SecKeyRef key) { + __block CFIndex localAlgorithmID = kSecNullAlgorithmID; + [[SecKeyProxy targetForKey:key error:NULL] getAlgorithmIDWithReply:^(NSInteger algorithmID) { + localAlgorithmID = algorithmID; + }]; + return localAlgorithmID; +} + +static SecKeyRef SecRemoteKeyCopyPublicKey(SecKeyRef key) { + __block id publicKey; + [[SecKeyProxy targetForKey:key error:NULL] getPublicKey:^(NSXPCListenerEndpoint *endpoint) { + if (endpoint != nil) { + publicKey = CFBridgingRelease([SecKeyProxy createKeyFromEndpoint:endpoint error:nil]); + } + }]; + return (__bridge_retained SecKeyRef)publicKey; +} + +static CFTypeRef SecRemoteKeyCopyOperationResult(SecKeyRef key, SecKeyOperationType operation, SecKeyAlgorithm algorithm, CFArrayRef algorithms, SecKeyOperationMode mode, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { + NSMutableArray *parameters = @[].mutableCopy; + if (in1 != NULL) { + [parameters addObject:(__bridge id)in1]; + if (in2 != NULL) { + [parameters addObject:(__bridge id)in2]; + } + } + __block id localResult; + [[SecKeyProxy targetForKey:key error:error] performOperation:operation algorithm:(__bridge NSString *)algorithm parameters:parameters reply:^(NSArray *result, NSError *_error) { + if (result.count > 0) { + localResult = result[0]; + } + else if (error != NULL) { + *error = (__bridge_retained CFErrorRef)_error; + } + }]; + return CFBridgingRetain(localResult); +} + +static const SecKeyDescriptor SecRemoteKeyDescriptor = { + .version = kSecKeyDescriptorVersion, + .name = "RemoteKey", + .init = SecRemoteKeyInit, + .destroy = SecRemoteKeyDestroy, + .blockSize = SecRemoteKeyBlockSize, + .copyDictionary = SecRemoteKeyCopyAttributeDictionary, + .copyExternalRepresentation = SecRemoteKeyCopyExternalRepresentation, + .describe = SecRemoteKeyCopyDescription, + .getAlgorithmID = SecRemoteKeyGetAlgorithmID, + .copyPublicKey = SecRemoteKeyCopyPublicKey, + .copyOperationResult = SecRemoteKeyCopyOperationResult, +}; + ++ (SecKeyRef)createItemFromEndpoint:(NSXPCListenerEndpoint *)endpoint certificate:(NSData **)certificate error:(NSError * _Nullable __autoreleasing *)error { + // Connect to the server proxy object. + NSXPCConnection *connection = [[NSXPCConnection alloc] initWithListenerEndpoint:endpoint]; + connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SecKeyProxyProtocol)]; + [connection resume]; + + // Initialize remote object. + __block NSError *localError; + __block NSData *localCertificate; + [[connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + localError = [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecItemNotFound userInfo:@{NSUnderlyingErrorKey: error}]; + }] initializeWithReply:^(NSData *_Nullable _certificate){ + localCertificate = _certificate; + }]; + if (localError == nil) { + if (certificate != nil) { + *certificate = localCertificate; + } + } else { + [connection invalidate]; + if (error != NULL) { + *error = localError; + } + return NULL; + } + + // Wrap returned connection in SecKeyRef instance. + return SecKeyCreate(kCFAllocatorDefault, &SecRemoteKeyDescriptor, CFBridgingRetain(connection), 0, kSecKeyEncodingRaw); +} + ++ (SecKeyRef)createKeyFromEndpoint:(NSXPCListenerEndpoint *)endpoint error:(NSError * _Nullable __autoreleasing *)error { + return [self createItemFromEndpoint:endpoint certificate:nil error:error]; +} + ++ (SecIdentityRef)createIdentityFromEndpoint:(NSXPCListenerEndpoint *)endpoint error:(NSError * _Nullable __autoreleasing *)error { + NSData *certificateData; + id key = CFBridgingRelease([self createItemFromEndpoint:endpoint certificate:&certificateData error:error]); + if (key == nil) { + return NULL; + } + if (certificateData == nil) { + if (error != NULL) { + *error = [NSError errorWithDomain:(NSString *)kSecErrorDomain code:errSecParam userInfo:@{(id)NSLocalizedDescriptionKey: @"Attempt to create remote identity from key-only proxy"}]; + } + return NULL; + } + + id certificate = CFBridgingRelease(SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certificateData)); + return SecIdentityCreate(kCFAllocatorDefault, (__bridge SecCertificateRef)certificate, (__bridge SecKeyRef)key); +} +@end diff --git a/OSX/sec/Security/SecOTRDHKey.c b/OSX/sec/Security/SecOTRDHKey.c index b4440141..221274d7 100644 --- a/OSX/sec/Security/SecOTRDHKey.c +++ b/OSX/sec/Security/SecOTRDHKey.c @@ -36,15 +36,22 @@ #define kECKeySize 256 -static void GenerateHashForKey(ccec_pub_ctx_t public_key, void *output) +static OSStatus GenerateHashForKey(ccec_pub_ctx_t public_key, void *output) { size_t size = ccec_export_pub_size(public_key); - uint8_t pub_key_bytes_buffer[size]; + uint8_t *pub_key_bytes_buffer = malloc(size); + if (pub_key_bytes_buffer == NULL) { + return errSecMemoryError; + } ccec_export_pub(public_key, pub_key_bytes_buffer); ccdigest(ccsha1_di(), size, pub_key_bytes_buffer, output); + + free(pub_key_bytes_buffer); + + return errSecSuccess; } @@ -128,9 +135,9 @@ static void SecOTRFullDHKeyDestroy(CFTypeRef cf) bzero(fullKey->_key, sizeof(fullKey->_key)); } -static inline void SecOTRFDHKUpdateHash(SecOTRFullDHKeyRef fullKey) +static inline OSStatus SecOTRFDHKUpdateHash(SecOTRFullDHKeyRef fullKey) { - GenerateHashForKey(ccec_ctx_pub(fullKey->_key), fullKey->keyHash); + return GenerateHashForKey(ccec_ctx_pub(fullKey->_key), fullKey->keyHash); } SecOTRFullDHKeyRef SecOTRFullDHKCreate(CFAllocatorRef allocator) @@ -159,7 +166,7 @@ SecOTRFullDHKeyRef SecOTRFullDHKCreateFromBytes(CFAllocatorRef allocator, const require_noerr(ReadMPI(bytes, size, ccec_ctx_n(newFDHK->_key), ccec_ctx_k(newFDHK->_key)), fail); - SecOTRFDHKUpdateHash(newFDHK); + require_noerr(SecOTRFDHKUpdateHash(newFDHK), fail); return newFDHK; @@ -168,7 +175,7 @@ fail: return NULL; } -void SecFDHKNewKey(SecOTRFullDHKeyRef fullKey) +OSStatus SecFDHKNewKey(SecOTRFullDHKeyRef fullKey) { struct ccrng_state *rng=ccDRBGGetRngState(); @@ -176,10 +183,12 @@ void SecFDHKNewKey(SecOTRFullDHKeyRef fullKey) // ccecdh_generate_key or ccechd_generate_compact_key, but for now ecdh are fine for compact use IFF we don't // use the non-compact pub part. - ccec_compact_generate_key(ccec_cp_256(), rng, fullKey->_key); + // ccec_cmp() assumes public keys are 65 bytes or shorter. + // If we ever generate different DHKeys, we will need to make a change there too. - SecOTRFDHKUpdateHash(fullKey); + ccec_compact_generate_key(ccec_cp_256(), rng, fullKey->_key); + return SecOTRFDHKUpdateHash(fullKey); } void SecFDHKAppendSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo) @@ -247,9 +256,9 @@ static void SecOTRPublicDHKeyDestroy(CFTypeRef cf) { (void) pubKey; } -static inline void SecOTRPDHKUpdateHash(SecOTRPublicDHKeyRef pubKey) +static inline OSStatus SecOTRPDHKUpdateHash(SecOTRPublicDHKeyRef pubKey) { - GenerateHashForKey(pubKey->_key, pubKey->keyHash); + return GenerateHashForKey(pubKey->_key, pubKey->keyHash); } static void ccec_copy_public(ccec_pub_ctx_t source, ccec_pub_ctx_t dest) @@ -299,7 +308,7 @@ SecOTRPublicDHKeyRef SecOTRPublicDHKCreateFromCompactSerialization(CFAllocatorRe *size -= publicKeySize; *bytes += publicKeySize; - SecOTRPDHKUpdateHash(newPDHK); + require_noerr(SecOTRPDHKUpdateHash(newPDHK), fail); return newPDHK; fail: @@ -317,7 +326,7 @@ SecOTRPublicDHKeyRef SecOTRPublicDHKCreateFromBytes(CFAllocatorRef allocator, co *bytes += *size; *size = 0; - SecOTRPDHKUpdateHash(newPDHK); + require_noerr(SecOTRPDHKUpdateHash(newPDHK), fail); return newPDHK; fail: @@ -359,12 +368,20 @@ static int ccec_cmp(ccec_pub_ctx_t l, ccec_pub_ctx_t r) int result = 0; if (lsize == rsize) { - uint8_t lpub[lsize]; - uint8_t rpub[rsize]; + // Keys should never be larger than 256. + // But if they are, we want to draw attention to it. + if (lsize > 65) { + secerror("The size of an SecOTRDHKey is larger than 65 bytes. \ + This is not supported in SecOTR and will result in malformed ciphertexts."); + return false; + } + + uint8_t lpub[65]; + uint8_t rpub[65]; ccec_export_pub(l, lpub); ccec_export_pub(r, rpub); - + result = memcmp(lpub, rpub, lsize); } else { result = rsize < lsize ? -1 : 1; diff --git a/OSX/sec/Security/SecOTRDHKey.h b/OSX/sec/Security/SecOTRDHKey.h index 39773ebd..5e9345cf 100644 --- a/OSX/sec/Security/SecOTRDHKey.h +++ b/OSX/sec/Security/SecOTRDHKey.h @@ -37,7 +37,7 @@ typedef struct _SecOTRPublicDHKey* SecOTRPublicDHKeyRef; SecOTRFullDHKeyRef SecOTRFullDHKCreate(CFAllocatorRef allocator); SecOTRFullDHKeyRef SecOTRFullDHKCreateFromBytes(CFAllocatorRef allocator, const uint8_t**bytes, size_t*size); -void SecFDHKNewKey(SecOTRFullDHKeyRef key); +OSStatus SecFDHKNewKey(SecOTRFullDHKeyRef key); void SecFDHKAppendSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo); void SecFDHKAppendPublicSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo); void SecFDHKAppendCompactPublicSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo); diff --git a/OSX/sec/Security/SecOTRPublicIdentity.c b/OSX/sec/Security/SecOTRPublicIdentity.c index fdec642e..b0f666db 100644 --- a/OSX/sec/Security/SecOTRPublicIdentity.c +++ b/OSX/sec/Security/SecOTRPublicIdentity.c @@ -346,8 +346,9 @@ bool SecOTRPIVerifySignature(SecOTRPublicIdentityRef publicID, (uint8_t*)signatureStart, signatureSize, NULL), fail); return true; fail: ; + uint8_t *replacementSignature = malloc(signatureSize + 3); + require(replacementSignature != NULL, fail2); - uint8_t replacementSignature[signatureSize + 3]; size_t replacementSignatureLen = sizeof(replacementSignature); uint8_t *replacementSignaturePtr = replacementSignature; @@ -358,9 +359,11 @@ fail: ; require(SecKeyDigestAndVerifyWithError(publicID->publicSigningKey, kOTRSignatureAlgIDPtr, dataToHash, amountToHash, replacementSignaturePtr, replacementSignatureLen, error), fail2); + free(replacementSignature); return true; fail2: + free(replacementSignature); return false; } diff --git a/OSX/sec/Security/SecOTRSession.c b/OSX/sec/Security/SecOTRSession.c index 56480f49..3079da33 100644 --- a/OSX/sec/Security/SecOTRSession.c +++ b/OSX/sec/Security/SecOTRSession.c @@ -122,7 +122,7 @@ static void SecOTRSExpireCachedKeysForPublicKey(SecOTRSessionRef session, SecOTR } } -static void SecOTRGenerateNewProposedKey(SecOTRSessionRef session) +static OSStatus SecOTRGenerateNewProposedKey(SecOTRSessionRef session) { SecOTRSExpireCachedKeysForFullKey(session, session->_myKey); @@ -134,9 +134,11 @@ static void SecOTRGenerateNewProposedKey(SecOTRSessionRef session) } // Derive a new next key by regenerating over the old key. - SecFDHKNewKey(session->_myNextKey); + OSStatus ret = SecFDHKNewKey(session->_myNextKey); session->_keyID += 1; + + return ret; } diff --git a/OSX/sec/Security/SecPBKDF.c b/OSX/sec/Security/SecPBKDF.c index 84ac9409..855b9644 100644 --- a/OSX/sec/Security/SecPBKDF.c +++ b/OSX/sec/Security/SecPBKDF.c @@ -9,7 +9,9 @@ #include "Security/pbkdf2.h" #include +#include "Security/SecBase.h" +#include #include /* CC Based HMAC PRF functions */ @@ -41,15 +43,19 @@ void hmac_sha256_PRF(const uint8_t *key, /* This implements the HMAC SHA-1 version of pbkdf2 and allocates a local buffer for the HMAC */ -void pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen, +OSStatus pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen, const uint8_t *saltPtr, size_t saltLen, uint32_t iterationCount, void *dkPtr, size_t dkLen) { // MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20; // salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize. - const size_t kBigEnoughSize = (saltLen + CC_SHA1_DIGEST_LENGTH) + 2 * CC_SHA1_DIGEST_LENGTH; - uint8_t temp_data[kBigEnoughSize]; + size_t kBigEnoughSize = (saltLen + CC_SHA1_DIGEST_LENGTH) + 2 * CC_SHA1_DIGEST_LENGTH; + uint8_t *temp_data = malloc(kBigEnoughSize); + + if (temp_data == NULL) { + return errSecMemoryError; + } pbkdf2(hmac_sha1_PRF, CC_SHA1_DIGEST_LENGTH, passwordPtr, passwordLen, @@ -58,19 +64,25 @@ void pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen, dkPtr, dkLen, temp_data); - bzero(temp_data, kBigEnoughSize); + bzero(temp_data, kBigEnoughSize); + + return errSecSuccess; } /* This implements the HMAC SHA-256 version of pbkdf2 and allocates a local buffer for the HMAC */ -void pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen, +OSStatus pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen, const uint8_t *saltPtr, size_t saltLen, uint32_t iterationCount, void *dkPtr, size_t dkLen) { // MAX(salt_length + 4, 32 /* SHA1 Digest size */) + 2 * 32; // salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize. - const size_t kBigEnoughSize = (saltLen + CC_SHA256_DIGEST_LENGTH) + 2 * CC_SHA256_DIGEST_LENGTH; - uint8_t temp_data[kBigEnoughSize]; + size_t kBigEnoughSize = (saltLen + CC_SHA256_DIGEST_LENGTH) + 2 * CC_SHA256_DIGEST_LENGTH; + uint8_t *temp_data = malloc(kBigEnoughSize); + + if (temp_data == NULL) { + return errSecMemoryError; + } pbkdf2(hmac_sha256_PRF, CC_SHA256_DIGEST_LENGTH, passwordPtr, passwordLen, @@ -80,20 +92,22 @@ void pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen, temp_data); bzero(temp_data, kBigEnoughSize); + + return errSecSuccess; } -void SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey) +OSStatus SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey) { - pbkdf2_hmac_sha1(CFDataGetBytePtr(password), CFDataGetLength(password), + return pbkdf2_hmac_sha1(CFDataGetBytePtr(password), CFDataGetLength(password), CFDataGetBytePtr(salt), CFDataGetLength(salt), interationCount, CFDataGetMutableBytePtr(derivedKey), CFDataGetLength(derivedKey)); } -void SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey) +OSStatus SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey) { - pbkdf2_hmac_sha256(CFDataGetBytePtr(password), CFDataGetLength(password), + return pbkdf2_hmac_sha256(CFDataGetBytePtr(password), CFDataGetLength(password), CFDataGetBytePtr(salt), CFDataGetLength(salt), interationCount, CFDataGetMutableBytePtr(derivedKey), CFDataGetLength(derivedKey)); diff --git a/OSX/sec/Security/SecPBKDF.h b/OSX/sec/Security/SecPBKDF.h index 167339c7..5ced7b50 100644 --- a/OSX/sec/Security/SecPBKDF.h +++ b/OSX/sec/Security/SecPBKDF.h @@ -22,14 +22,37 @@ void hmac_sha256_PRF(const uint8_t *key, size_t text_len, uint8_t digest[CC_SHA256_DIGEST_LENGTH]); -/* PBKDF for clients who want to let us allocate the intermediate buffer. - We over write any intermediate results we use in calculating */ -void pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen, + +/** + PBKDF2 key derivation with HMAC-SHA1. + + @param passwordPtr The pointer to the passsword data + @param passwordLen The password data length + @param saltPtr The pointer to the salt + @param saltLen The salt length + @param iterationCount Number of PBKDF2 iterations + @param dkPtr The pointer to the derived key + @param dkLen The derived key length + @return errSecMemoryError on a failure to allocate the buffer. errSecSuccess otherwise. + */ +OSStatus pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen, const uint8_t *saltPtr, size_t saltLen, uint32_t iterationCount, void *dkPtr, size_t dkLen); -void pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen, +/** + PBKDF2 key derivation with HMAC-SHA256. + + @param passwordPtr The pointer to the passsword data + @param passwordLen The password data length + @param saltPtr The pointer to the salt + @param saltLen The salt length + @param iterationCount Number of PBKDF2 iterations + @param dkPtr The pointer to the derived key + @param dkLen The derived key length + @return errSecMemoryError on a failure to allocate the buffer. errSecSuccess otherwise. + */ +OSStatus pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen, const uint8_t *saltPtr, size_t saltLen, uint32_t iterationCount, void *dkPtr, size_t dkLen); @@ -64,5 +87,24 @@ void pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen, */ -void SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey); -void SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey); +/** + PBKDF2 key derivation with HMAC-SHA1. + + @param password Password data + @param salt Salt data + @param interationCount Number of PBKDF2 iterations + @param derivedKey Mutable data reference to write the result of the key derivation + @return errSecMemoryError on a failure to allocate the buffer. errSecSuccess otherwise. + */ +OSStatus SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey); + +/** + PBKDF2 key derivation with HMAC-SHA256. + + @param password Password data + @param salt Salt data + @param interationCount Number of PBKDF2 iterations + @param derivedKey Mutable data reference to write the result of the key derivation + @return errSecMemoryError on a failure to allocate the buffer. errSecSuccess otherwise. + */ +OSStatus SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey); diff --git a/OSX/sec/Security/SecPasswordGenerate.c b/OSX/sec/Security/SecPasswordGenerate.c index a095a5c3..603eeb6c 100644 --- a/OSX/sec/Security/SecPasswordGenerate.c +++ b/OSX/sec/Security/SecPasswordGenerate.c @@ -870,10 +870,17 @@ fail: return false; } -static void getPasswordRandomCharacters(CFStringRef *returned, CFDictionaryRef requirements, CFIndex *numberOfRandomCharacters, CFStringRef allowedCharacters) +static OSStatus getPasswordRandomCharacters(CFStringRef *returned, CFDictionaryRef requirements, CFIndex *numberOfRandomCharacters, CFStringRef allowedCharacters) { - uint8_t randomNumbers[*numberOfRandomCharacters]; - unsigned char randomCharacters[*numberOfRandomCharacters]; + uint8_t *randomNumbers = malloc(*numberOfRandomCharacters); + unsigned char *randomCharacters = malloc(*numberOfRandomCharacters); + + if (randomNumbers == NULL || randomCharacters == NULL) { + free(randomNumbers); + free(randomCharacters); + return errSecMemoryError; + } + getUniformRandomNumbers(randomNumbers, *numberOfRandomCharacters, CFStringGetLength(allowedCharacters)); CFTypeRef prohibitedCharacters = NULL; @@ -901,6 +908,11 @@ static void getPasswordRandomCharacters(CFStringRef *returned, CFDictionaryRef r } *returned = CFStringCreateWithBytes(kCFAllocatorDefault, randomCharacters, *numberOfRandomCharacters, kCFStringEncodingUTF8, false); + + free(randomCharacters); + free(randomNumbers); + + return errSecSuccess; } static bool doesPasswordEndWith(CFStringRef password, CFStringRef prohibitedCharacters) @@ -1527,7 +1539,7 @@ CF_RETURNS_RETAINED CFStringRef SecPasswordGenerate(SecPasswordType type, CFErro while (true) { allowedChars = CFDictionaryGetValue(properlyFormattedRequirements, kSecAllowedCharactersKey); - getPasswordRandomCharacters(&randomCharacters, properlyFormattedRequirements, &requiredCharactersSize, allowedChars); + require_noerr(getPasswordRandomCharacters(&randomCharacters, properlyFormattedRequirements, &requiredCharactersSize, allowedChars), fail); if(numberOfGroupsRef && groupSizeRef){ finalPassword = CFStringCreateMutable(kCFAllocatorDefault, 0); diff --git a/OSX/sec/Security/SecPolicy.c b/OSX/sec/Security/SecPolicy.c index 2c8ed323..661f3a2f 100644 --- a/OSX/sec/Security/SecPolicy.c +++ b/OSX/sec/Security/SecPolicy.c @@ -1778,6 +1778,9 @@ SecPolicyRef SecPolicyCreateiPhoneApplicationSigning(void) { /* Chain length check */ require(SecPolicyAddChainLengthOptions(options, 3), errOut); + /* Skip networked revocation checks */ + CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); + require(result = SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning, kSecPolicyNameiPhoneApplicationSigning, options), errOut); @@ -1823,6 +1826,9 @@ SecPolicyRef SecPolicyCreateiPhoneVPNApplicationSigning(void) { /* Chain length check */ require(SecPolicyAddChainLengthOptions(options, 3), errOut); + /* Skip networked revocation checks */ + CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); + require(result = SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning, kSecPolicyNameiPhoneVPNApplicationSigning, options), errOut); @@ -1869,7 +1875,6 @@ SecPolicyRef SecPolicyCreateiPhoneProfileApplicationSigning(void) { /* Revocation via any available method */ CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); - require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning, kSecPolicyNameiPhoneProfileApplicationSigning, options), errOut); @@ -1914,7 +1919,6 @@ SecPolicyRef SecPolicyCreateMacOSProfileApplicationSigning(void) { /* Revocation via any available method */ CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); - require(result = SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning, kSecPolicyNameMacOSProfileApplicationSigning, options), errOut); @@ -1951,6 +1955,9 @@ SecPolicyRef SecPolicyCreateiPhoneProvisioningProfileSigning(void) { require(SecPolicyAddChainLengthOptions(options, 3), errOut); require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneProvisioningProfileSigning), errOut); + /* Skip networked revocation checks */ + CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); + require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning, kSecPolicyNameiPhoneProvisioningProfileSigning, options), errOut); @@ -1991,6 +1998,9 @@ SecPolicyRef SecPolicyCreateAppleTVOSApplicationSigning(void) { add_leaf_marker(options, &oidAppleTVOSApplicationSigningProd); add_leaf_marker(options, &oidAppleTVOSApplicationSigningProdQA); + /* Skip networked revocation checks */ + CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); + require(result = SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning, kSecPolicyNameTVOSApplicationSigning, options), errOut); @@ -3826,8 +3836,8 @@ errOut: /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */ /* Signature Algorithm: ecdsa-with-SHA384 */ const uint8_t BASystemRootCA_SHA256[kSecPolicySHA256Size] = { - 0x29, 0x75, 0x9b, 0x53, 0x8a, 0xd1, 0xcb, 0x4f, 0x3b, 0xa5, 0x20, 0x4d, 0x60, 0x4b, 0x25, 0x81, - 0x8d, 0x18, 0x9f, 0x62, 0xe3, 0x94, 0x2d, 0x99, 0x52, 0x54, 0x22, 0x5a, 0xe5, 0x7f, 0x42, 0xca + 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64, + 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47 }; /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */ @@ -3893,6 +3903,40 @@ errOut: return result; } +SecPolicyRef SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration) { + CFMutableDictionaryRef options = NULL; + SecPolicyRef result = NULL; + + require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks), errOut); + + /* iAP checks expiration on developement certs, but not on production certs */ + if (checkExpiration) { + SecPolicyAddBasicX509Options(options); + } else { + SecPolicyAddBasicCertOptions(options); + } + + /* Exactly 2 certs in the chain */ + require(SecPolicyAddChainLengthOptions(options, 2), errOut); + + /* iAP SW Auth General Capabilities Extension present */ + add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.59.1")); + + require(result = SecPolicyCreate(kSecPolicyAppleiAPSWAuth, + kSecPolicyNameiAPSWAuth, options), errOut); + +errOut: + CFReleaseSafe(options); + return result; +} + +SecPolicyRef SecPolicyCreateiAPSWAuth(void) { + /* By default, iAP SW Auth certs don't expire */ + return SecPolicyCreateiAPSWAuthWithExpiration(false); +} + SecPolicyRef SecPolicyCreateDemoDigitalCatalogSigning(void) { CFMutableDictionaryRef options = NULL; SecPolicyRef result = NULL; @@ -3918,3 +3962,89 @@ errOut: CFReleaseSafe(options); return result; } + +SecPolicyRef SecPolicyCreateAppleAssetReceipt(void) { + CFMutableDictionaryRef options = NULL; + SecPolicyRef result = NULL; + + require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks), errOut); + + /* No expiration check. */ + SecPolicyAddBasicCertOptions(options); + + /* Apple Anchor */ + require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAssetReceipt), errOut); + + /* Exactly 3 certs in the chain */ + require(SecPolicyAddChainLengthOptions(options, 3), errOut); + + /* Intermediate marker OID is Apple System Integration 2 CA */ + add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.10")); + + /* Leaf marker OID is the Asset Receipt OID */ + add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.61")); + + /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ + require(SecPolicyAddStrongKeySizeOptions(options), errOut); + + require(result = SecPolicyCreate(kSecPolicyAppleAssetReceipt, + kSecPolicyNameAssetReceipt, options), errOut); + +errOut: + CFReleaseNull(options); + return result; +} + +SecPolicyRef SecPolicyCreateAppleDeveloperIDPlusTicket(void) { + CFMutableDictionaryRef options = NULL; + SecPolicyRef result = NULL; + + require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks), errOut); + + /* No expiration check. */ + SecPolicyAddBasicCertOptions(options); + + /* Apple Anchor */ + require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameDeveloperIDPlusTicket), errOut); + + /* Exactly 3 certs in the chain */ + require(SecPolicyAddChainLengthOptions(options, 3), errOut); + + /* Intermediate marker OID is Apple System Integration CA 4 */ + add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.17")); + + /* Leaf marker OID is the Developer ID+ Ticket OID */ + add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.30")); + + /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ + require(SecPolicyAddStrongKeySizeOptions(options), errOut); + + require(result = SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket, + kSecPolicyNameDeveloperIDPlusTicket, options), errOut); + +errOut: + CFReleaseNull(options); + return result; +} + +SecPolicyRef SecPolicyCreateAppleFDRProvisioning(void) { + CFMutableDictionaryRef options = NULL; + SecPolicyRef result = NULL; + + require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks), errOut); + + /* No expiration check. */ + SecPolicyAddBasicCertOptions(options); + + require(result = SecPolicyCreate(kSecPolicyAppleFDRProvisioning, + kSecPolicyNameFDRProvisioning, options), errOut); +errOut: + CFReleaseNull(options); + return result; +} diff --git a/OSX/sec/Security/SecPolicy.list b/OSX/sec/Security/SecPolicy.list index 3206ccfc..226d94a2 100644 --- a/OSX/sec/Security/SecPolicy.list +++ b/OSX/sec/Security/SecPolicy.list @@ -88,4 +88,8 @@ POLICYMACRO(MobileAssetDevelopment, 83, , MobileAsset, POLICYMACRO(BasicAttestationSystem, 84, , BAA-SCRT, , , AppleBasicAttestationSystem) POLICYMACRO(BasicAttestationUser, 85, , BAA-UCRT, , , AppleBasicAttestationUser) POLICYMACRO(iPhoneVPNApplicationSigning, 86, , iPhoneVPNApplicationSigning, , Y, iPhoneVPNApplicationSigning) +POLICYMACRO(iAPSWAuth, 87, , iAPSWAuth, , Y, iAPSWAuth) POLICYMACRO(DemoDigitalCatalog, 88, , DemoCatalog, , Y, DemoDigitalCatalogSigning) +POLICYMACRO(AssetReceipt, 89, , AssetReceipt, , Y, AppleAssetReceipt) +POLICYMACRO(DeveloperIDPlusTicket, 90, , DeveloperIDPlusTicket, , Y, AppleDeveloperIDPlusTicket) +POLICYMACRO(FDRProvisioning, 91, , FDRProvisioning, , Y, AppleFDRProvisioning) diff --git a/OSX/sec/Security/SecPolicyChecks.list b/OSX/sec/Security/SecPolicyChecks.list index cf524754..6d28fd46 100644 --- a/OSX/sec/Security/SecPolicyChecks.list +++ b/OSX/sec/Security/SecPolicyChecks.list @@ -7,7 +7,7 @@ // TRUSTRESULT: the trust result this check should produce. R is Recoverable, F is Fatal, D is Deny // SUBTYPE: the type of failure. // N is a name failure, E is expiration, S is key size, H is weak hash, U is usage, P is pinning, V is revocation -// T is trust, C is compliance, D is denied +// T is trust, C is compliance, D is denied, B is blocked // LEAFCHECK: L for checks that happen in the leaf callbacks // PATHCHECK: A for checks that happen in the path callbacks // LEAFONLY: O for checks that are done in leaf-only trust evaluations @@ -21,7 +21,7 @@ POLICYCHECKMACRO(SSLHostname, R, N, L, , O, 0x80012400, errS POLICYCHECKMACRO(Email, R, N, L, , O, 0x80012418, errSecSMIMEEmailAddressesNotFound) //CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND POLICYCHECKMACRO(TemporalValidity, R, E, L, A, O, 0x8001210A, errSecCertificateExpired) //CSSMERR_TP_CERT_EXPIRED POLICYCHECKMACRO(WeakKeySize, F, S, L, A, O, 0x80012115, errSecUnsupportedKeySize) //CSSMERR_TP_INVALID_CERTIFICATE -POLICYCHECKMACRO(WeakSignature, R, H, L, A, O, 0x80010955, errSecInvalidDigestAlgorithm) //CSSMERR_CSP_INVALID_DIGEST_ALGORITHM +POLICYCHECKMACRO(WeakSignature, F, H, L, A, O, 0x80010955, errSecInvalidDigestAlgorithm) //CSSMERR_CSP_INVALID_DIGEST_ALGORITHM POLICYCHECKMACRO(KeyUsage, R, U, L, , O, 0x80012406, errSecInvalidKeyUsageForPolicy) //CSSMERR_APPLETP_INVALID_KEY_USAGE POLICYCHECKMACRO(ExtendedKeyUsage, R, U, L, , O, 0x80012407, errSecInvalidExtendedKeyUsage) //CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE POLICYCHECKMACRO(SubjectCommonName, R, P, L, , O, 0x8001243B, errSecInvalidSubjectName) //CSSMERR_APPLETP_IDENTIFIER_MISSING @@ -34,7 +34,7 @@ POLICYCHECKMACRO(EAPTrustedServerNames, R, N, L, , O, 0x80012400, errS POLICYCHECKMACRO(LeafMarkerOid, R, P, L, , O, 0x80012439, errSecMissingRequiredExtension) //CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION POLICYCHECKMACRO(LeafMarkerOidWithoutValueCheck, R, P, L, , O, 0x80012439, errSecMissingRequiredExtension) //CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION POLICYCHECKMACRO(LeafMarkersProdAndQA, R, P, L, , O, 0x80012439, errSecMissingRequiredExtension) //CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION -POLICYCHECKMACRO(BlackListedLeaf, F, V, L, , , 0x8001210C, errSecCertificateRevoked) //CSSMERR_TP_CERT_REVOKED +POLICYCHECKMACRO(BlackListedLeaf, F, B, L, , , 0x8001210C, errSecCertificateRevoked) //CSSMERR_TP_CERT_REVOKED POLICYCHECKMACRO(GrayListedLeaf, R, T, L, , , 0x8001212A, errSecNotTrusted) //CSSMERR_TP_NOT_TRUSTED /******************************************************** @@ -78,7 +78,7 @@ POLICYCHECKMACRO(BasicCertificateProcessing, R, C, , A, , 0x80012115, errS POLICYCHECKMACRO(NameConstraints, R, C, , , , 0x80012115, errSecInvalidName) //CSSMERR_TP_INVALID_CERTIFICATE POLICYCHECKMACRO(PolicyConstraints, R, C, , , , 0x80012115, errSecInvalidPolicyIdentifiers) //CSSMERR_TP_INVALID_CERTIFICATE POLICYCHECKMACRO(GrayListedKey, R, T, , , , 0x8001212A, errSecNotTrusted) //CSSMERR_TP_NOT_TRUSTED -POLICYCHECKMACRO(BlackListedKey, F, V, , , , 0x8001210C, errSecCertificateRevoked) //CSSMERR_TP_CERT_REVOKED +POLICYCHECKMACRO(BlackListedKey, F, B, , , , 0x8001210C, errSecCertificateRevoked) //CSSMERR_TP_CERT_REVOKED POLICYCHECKMACRO(UsageConstraints, D, D, , , , 0x80012436, errSecTrustSettingDeny) //CSSMERR_APPLETP_TRUST_SETTING_DENY POLICYCHECKMACRO(SystemTrustedWeakHash, R, C, , A, , 0x80010955, errSecInvalidDigestAlgorithm) //CSSMERR_CSP_INVALID_DIGEST_ALGORITHM POLICYCHECKMACRO(SystemTrustedWeakKey, R, C, , A, , 0x80010918, errSecUnsupportedKeySize) //CSSMERR_CSP_UNSUPPORTED_KEY_SIZE diff --git a/OSX/sec/Security/SecPolicyLeafCallbacks.c b/OSX/sec/Security/SecPolicyLeafCallbacks.c index bad7f8ca..843e2fe6 100644 --- a/OSX/sec/Security/SecPolicyLeafCallbacks.c +++ b/OSX/sec/Security/SecPolicyLeafCallbacks.c @@ -638,7 +638,11 @@ bool SecPolicyCheckCertWeakSignature(SecCertificateRef cert, CFTypeRef __unused CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD2); CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD4); CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD5); - if (!SecPolicyCheckCertSignatureHashAlgorithms(cert, disallowedHashes)) { + + /* Weak Signature failures only for non-self-signed certs */ + Boolean isSelfSigned = false; + OSStatus status = SecCertificateIsSelfSigned(cert, &isSelfSigned); + if (!SecPolicyCheckCertSignatureHashAlgorithms(cert, disallowedHashes) && (status != errSecSuccess || !isSelfSigned)) { result = false; } CFReleaseSafe(disallowedHashes); @@ -690,7 +694,7 @@ __PC_ADD_CHECK_##LEAFONLY(NAME) void SecLeafPVCInit(SecLeafPVCRef pvc, SecCertificateRef leaf, CFArrayRef policies, CFAbsoluteTime verifyTime) { - secdebug("alloc", "%p", pvc); + secdebug("alloc", "leafpvc %p", pvc); // Weird logging policies crashes. //secdebug("policy", "%@", policies); pvc->leaf = CFRetainSafe(leaf); @@ -709,7 +713,7 @@ void SecLeafPVCInit(SecLeafPVCRef pvc, SecCertificateRef leaf, CFArrayRef polici void SecLeafPVCDelete(SecLeafPVCRef pvc) { - secdebug("alloc", "%p", pvc); + secdebug("alloc", "delete leaf pvc %p", pvc); CFReleaseNull(pvc->policies); CFReleaseNull(pvc->details); CFReleaseNull(pvc->callbacks); diff --git a/OSX/sec/Security/SecSCEP.c b/OSX/sec/Security/SecSCEP.c index 05ab7634..48ea10c5 100644 --- a/OSX/sec/Security/SecSCEP.c +++ b/OSX/sec/Security/SecSCEP.c @@ -246,7 +246,7 @@ out: CFDataRef SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters, - SecKeyRef __unused publicKey, SecKeyRef privateKey, + SecKeyRef publicKey, SecKeyRef privateKey, SecIdentityRef signer, CFTypeRef recipients) { CFDataRef csr = NULL; @@ -275,14 +275,16 @@ SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters require(recipient, out); /* We don't support EC recipients for SCEP yet. */ -#if TARGET_OS_IPHONE - recipientKey = SecCertificateCopyPublicKey(recipient); -#else - recipientKey = SecCertificateCopyPublicKey_ios(recipient); -#endif + recipientKey = SecCertificateCopyKey(recipient); require(SecKeyGetAlgorithmId(recipientKey) == kSecRSAAlgorithmID, out); - require(realPublicKey = SecKeyCopyPublicKey(privateKey), out); + realPublicKey = SecKeyCopyPublicKey(privateKey); + if (!realPublicKey) { + /* If we can't get the public key from the private key, + * fall back to the public key provided by the caller. */ + realPublicKey = CFRetainSafe(publicKey); + } + require(realPublicKey, out); require(csr = SecGenerateCertificateRequest(subject, parameters, realPublicKey, privateKey), out); require(enveloped_data = CFDataCreateMutable(kCFAllocatorDefault, 0), out); require_noerr(SecCMSCreateEnvelopedData(recipient, parameters, csr, enveloped_data), out); @@ -384,11 +386,7 @@ SecSCEPCertifyRequestWithAlgorithms(CFDataRef request, SecIdentityRef ca_identit CFMutableDictionaryRef parameters = NULL; require_noerr(SecIdentityCopyCertificate(ca_identity, &ca_certificate), out); -#if TARGET_OS_IPHONE - ca_public_key = SecCertificateCopyPublicKey(ca_certificate); /*@@@*/ -#else - ca_public_key = SecCertificateCopyPublicKey_ios(ca_certificate); -#endif + ca_public_key = SecCertificateCopyKey(ca_certificate); /* unwrap outer layer: */ policy = SecPolicyCreateBasicX509(); diff --git a/OSX/sec/Security/SecServerEncryptionSupport.h b/OSX/sec/Security/SecServerEncryptionSupport.h index 4f12baee..eec06daa 100644 --- a/OSX/sec/Security/SecServerEncryptionSupport.h +++ b/OSX/sec/Security/SecServerEncryptionSupport.h @@ -24,7 +24,7 @@ CFDataRef SecCopyEncryptedToServer(SecTrustRef trustedEvaluation, CFDataRef data // /* Caution: These functions take an iOS SecKeyRef. Careful use is required on OS X. */ CFDataRef SecCopyDecryptedForServer(SecKeyRef serverFullKey, CFDataRef encryptedData, CFErrorRef* error) - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_NA, __MAC_NA, __IPHONE_8_0, __IPHONE_11_0,"Migrate to SecKeyCreateEncryptedData with kSecKeyAlgorithmECIESEncryptionStandardVariableIV* or Security Foundation SFIESOperation for improved security (encryption is not compatible)"); + API_DEPRECATED("Migrate to SecKeyCreateEncryptedData with kSecKeyAlgorithmECIESEncryptionStandardVariableIV* or Security Foundation SFIESOperation for improved security (encryption is not compatible)", macos(10.12,10.13), ios(8.0,11.0)); // SFIESCiphertext diff --git a/OSX/sec/Security/SecTrust.c b/OSX/sec/Security/SecTrust.c index 063e1564..01b079b9 100644 --- a/OSX/sec/Security/SecTrust.c +++ b/OSX/sec/Security/SecTrust.c @@ -148,6 +148,9 @@ struct __SecTrust { /* Forward declarations of static functions. */ static OSStatus SecTrustEvaluateIfNecessary(SecTrustRef trust); +static void SecTrustEvaluateIfNecessaryFastAsync(SecTrustRef trust, + dispatch_queue_t queue, + void (^handler)(OSStatus status)); /* Static functions. */ static CFStringRef SecTrustCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) { @@ -986,6 +989,7 @@ static CFStringRef SecTrustCopyChainSummary(SecTrustRef trust) { } typedef enum { + kSecTrustErrorSubTypeBlocked, kSecTrustErrorSubTypeRevoked, kSecTrustErrorSubTypeKeySize, kSecTrustErrorSubTypeWeakHash, @@ -1022,6 +1026,7 @@ const checkmap_entry_t checkmap[] = { #define __PC_SUBTYPE_T kSecTrustErrorSubTypeTrust #define __PC_SUBTYPE_C kSecTrustErrorSubTypeCompliance #define __PC_SUBTYPE_D kSecTrustErrorSubTypeDenied +#define __PC_SUBTYPE_B kSecTrustErrorSubTypeBlocked #define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ { __PC_SUBTYPE_##SUBTYPE , OSSTATUS, SEC_TRUST_ERROR_##NAME }, #include "SecPolicyChecks.list" @@ -1099,6 +1104,10 @@ static OSStatus SecTrustCopyErrorStrings(SecTrustRef trust, CFStringRef format = NULL; CFStringRef certSummary = SecCertificateCopySubjectSummary(SecTrustGetCertificateAtIndex(trust, simpleErrorCertIndex)); switch (simpleErrorSubType) { + case kSecTrustErrorSubTypeBlocked: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_BLOCKED); + break; + } case kSecTrustErrorSubTypeRevoked: { format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_REVOKED); break; @@ -1154,7 +1163,7 @@ static OSStatus SecTrustCopyErrorStrings(SecTrustRef trust, return simpleErrorStatus; } -static CFErrorRef SecTrustCopyError(SecTrustRef trust) { +static CF_RETURNS_RETAINED CFErrorRef SecTrustCopyError(SecTrustRef trust) { if (!trust) { return NULL; } (void)SecTrustEvaluateIfNecessary(trust); OSStatus status = errSecSuccess; @@ -1169,6 +1178,13 @@ static CFErrorRef SecTrustCopyError(SecTrustRef trust) { CFStringRef detailedError = NULL; CFStringRef simpleError = NULL; status = SecTrustCopyErrorStrings(trust, &simpleError, &detailedError); + /* failure to obtain either string must not cause a failure to create the CFErrorRef */ + if (!simpleError) { + simpleError = SecCopyErrorMessageString(status, NULL); + } + if (!detailedError) { + detailedError = SecCopyErrorMessageString(status, NULL); + } CFDictionaryRef userInfo = CFDictionaryCreate(NULL, (const void **)&kCFErrorLocalizedDescriptionKey, (const void **)&detailedError, 1, &kCFTypeDictionaryKeyCallBacks, @@ -1211,14 +1227,45 @@ bool SecTrustEvaluateWithError(SecTrustRef trust, CFErrorRef *error) { OSStatus SecTrustEvaluateAsync(SecTrustRef trust, dispatch_queue_t queue, SecTrustCallback result) { - CFRetainSafe(trust); + CFRetainSafe(trust); dispatch_async(queue, ^{ SecTrustResultType trustResult; if (errSecSuccess != SecTrustEvaluate(trust, &trustResult)) { trustResult = kSecTrustResultInvalid; } result(trust, trustResult); - CFReleaseSafe(trust); + CFReleaseSafe(trust); + }); + return errSecSuccess; +} + +OSStatus SecTrustEvaluateFastAsync(SecTrustRef trust, + dispatch_queue_t queue, SecTrustCallback result) +{ + if (trust == NULL || queue == NULL || result == NULL) { + return errSecParam; + } + + dispatch_assert_queue(queue); + SecTrustEvaluateIfNecessaryFastAsync(trust, queue, ^(OSStatus status) { + if (status != noErr) { + result(trust, kSecTrustResultInvalid); + return; + } + __block SecTrustResultType trustResult = kSecTrustResultInvalid; + dispatch_sync(trust->_trustQueue, ^{ + trustResult = trust->_trustResult; + }); + /* log to syslog when there is a trust failure */ + if (trustResult != kSecTrustResultProceed && + trustResult != kSecTrustResultUnspecified) { + CFStringRef failureDesc = SecTrustCopyFailureDescription(trust); + secerror("Trust evaluate failure:%{public}@", failureDesc); + CFRelease(failureDesc); + } + + + result(trust, trustResult); }); return errSecSuccess; } @@ -1403,6 +1450,55 @@ static SecTrustResultType handle_trust_evaluate_xpc(enum SecXPCOperation op, CFA return tr; } +typedef void (^trust_handler_t)(SecTrustResultType tr, CFErrorRef error); + +static void handle_trust_evaluate_xpc_async(dispatch_queue_t replyq, trust_handler_t trustHandler, + enum SecXPCOperation op, CFArrayRef certificates, + CFArrayRef anchors, bool anchorsOnly, + bool keychainsAllowed, CFArrayRef policies, + CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, + CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, + CFArrayRef exceptions, CFArrayRef *details, + CFDictionaryRef *info, CFArrayRef *chain) +{ + securityd_send_async_and_do(op, replyq, ^bool(xpc_object_t message, CFErrorRef *error) { + if (!SecXPCDictionarySetCertificates(message, kSecTrustCertificatesKey, certificates, error)) + return false; + if (anchors && !SecXPCDictionarySetCertificates(message, kSecTrustAnchorsKey, anchors, error)) + return false; + if (anchorsOnly) + xpc_dictionary_set_bool(message, kSecTrustAnchorsOnlyKey, anchorsOnly); + xpc_dictionary_set_bool(message, kSecTrustKeychainsAllowedKey, keychainsAllowed); + if (!SecXPCDictionarySetPolicies(message, kSecTrustPoliciesKey, policies, error)) + return false; + if (responses && !SecXPCDictionarySetDataArray(message, kSecTrustResponsesKey, responses, error)) + return false; + if (SCTs && !SecXPCDictionarySetDataArray(message, kSecTrustSCTsKey, SCTs, error)) + return false; + if (trustedLogs && !SecXPCDictionarySetPList(message, kSecTrustTrustedLogsKey, trustedLogs, error)) + return false; + xpc_dictionary_set_double(message, kSecTrustVerifyDateKey, verifyTime); + if (exceptions && !SecXPCDictionarySetPList(message, kSecTrustExceptionsKey, exceptions, error)) + return false; + return true; + }, ^(xpc_object_t response, CFErrorRef error) { + secdebug("trust", "response: %@", response); + if (response == NULL || error != NULL) { + trustHandler(kSecTrustResultInvalid, error); + return; + } + SecTrustResultType tr = kSecTrustResultInvalid; + CFErrorRef error2 = NULL; + if (SecXPCDictionaryCopyArrayOptional(response, kSecTrustDetailsKey, details, &error2) && + SecXPCDictionaryCopyDictionaryOptional(response, kSecTrustInfoKey, info, &error2) && + SecXPCDictionaryCopyChainOptional(response, kSecTrustChainKey, chain, &error2)) { + tr = SecXPCDictionaryGetNonZeroInteger(response, kSecTrustResultKey, &error2); + } + trustHandler(tr, error2); + CFReleaseNull(error2); + }); +} + OSStatus validate_array_of_items(CFArrayRef array, CFStringRef arrayItemType, CFTypeID itemTypeID, bool required) { OSStatus result = errSecSuccess; CFIndex index, count; @@ -1537,6 +1633,98 @@ static OSStatus SecTrustEvaluateIfNecessary(SecTrustRef trust) { return result; } +// IMPORTANT: this MUST be called on the provided queue as it will call the handler synchronously +// if no asynchronous work is needed +static void SecTrustEvaluateIfNecessaryFastAsync(SecTrustRef trust, + dispatch_queue_t queue, + void (^handler)(OSStatus status)) { + check(trust); + check(queue); + check(handler); + if (handler == NULL) { + return; + } + if (trust == NULL || queue == NULL) { + handler(errSecParam); + return; + } + + __block bool shouldReturnSuccess = false; + __block CFAbsoluteTime verifyTime = SecTrustGetVerifyTime(trust); + SecTrustAddPolicyAnchors(trust); + dispatch_sync(trust->_trustQueue, ^{ + if (trust->_trustResult != kSecTrustResultInvalid) { + shouldReturnSuccess = true; + return; + } + + trust->_trustResult = kSecTrustResultOtherError; /* to avoid potential recursion */ + + CFReleaseNull(trust->_chain); + CFReleaseNull(trust->_details); + CFReleaseNull(trust->_info); + if (trust->_legacy_info_array) { + free(trust->_legacy_info_array); + trust->_legacy_info_array = NULL; + } + if (trust->_legacy_status_array) { + free(trust->_legacy_status_array); + trust->_legacy_status_array = NULL; + } + + os_activity_t activity = os_activity_create("SecTrustEvaluateIfNecessaryFastAsync", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + __block struct os_activity_scope_state_s activityState; + os_activity_scope_enter(activity, &activityState); + os_release(activity); + + SecTrustValidateInput(trust); + + CFRetainSafe(trust); + TRUSTD_XPC_ASYNC(sec_trust_evaluate, + handle_trust_evaluate_xpc_async, + queue, + ^(SecTrustResultType tr, CFErrorRef error) { + __block OSStatus result = errSecInternalError; + dispatch_sync(trust->_trustQueue, ^{ + trust->_trustResult = tr; + if (trust->_trustResult == kSecTrustResultInvalid /* TODO check domain */ && + SecErrorGetOSStatus(error) == errSecNotAvailable && + CFArrayGetCount(trust->_certificates)) { + /* We failed to talk to securityd. The only time this should + happen is when we are running prior to launchd enabling + registration of services. This currently happens when we + are running from the ramdisk. To make ASR happy we initialize + _chain and return success with a failure as the trustResult, to + make it seem like we did a cert evaluation, so ASR can extract + the public key from the leaf. */ + SecCertificateRef leafCert = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_certificates, 0); + CFArrayRef leafCertArray = CFArrayCreate(NULL, (const void**)&leafCert, 1, &kCFTypeArrayCallBacks); + trust->_chain = leafCertArray; + result = errSecSuccess; + return; + } + result = SecOSStatusWith(^bool (CFErrorRef *error2) { + if (error2 != NULL) { + *error2 = error; + } + return trust->_trustResult != kSecTrustResultInvalid; + }); + }); + os_activity_scope_leave(&activityState); + handler(result); + CFReleaseSafe(trust); + }, + trust->_certificates, trust->_anchors, trust->_anchorsOnly, trust->_keychainsAllowed, + trust->_policies, trust->_responses, trust->_SCTs, trust->_trustedLogs, + verifyTime, SecAccessGroupsGetCurrent(), trust->_exceptions, + &trust->_details, &trust->_info, &trust->_chain); + }); + if (shouldReturnSuccess) { + handler(errSecSuccess); + } +} + /* Helper for the qsort below. */ static int compare_strings(const void *a1, const void *a2) { CFStringRef s1 = *(CFStringRef *)a1; @@ -1603,11 +1791,7 @@ SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust) return; } SecCertificateRef leaf = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_certificates, 0); -#if TARGET_OS_OSX - trust->_publicKey = SecCertificateCopyPublicKey_ios(leaf); -#else - trust->_publicKey = SecCertificateCopyPublicKey(leaf); -#endif + trust->_publicKey = SecCertificateCopyKey(leaf); if (trust->_publicKey) { publicKey = CFRetainSafe(trust->_publicKey); } @@ -1618,11 +1802,7 @@ SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust) dispatch_sync(trust->_trustQueue, ^{ if (trust->_chain) { SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_chain, 0); -#if TARGET_OS_OSX - trust->_publicKey = SecCertificateCopyPublicKey_ios(cert); -#else - trust->_publicKey = SecCertificateCopyPublicKey(cert); -#endif + trust->_publicKey = SecCertificateCopyKey(cert); publicKey = CFRetainSafe(trust->_publicKey); } }); @@ -1886,6 +2066,7 @@ struct TrustFailures { bool badLinkage; bool unknownCritExtn; bool untrustedAnchor; + bool missingIntermediate; bool hostnameMismatch; bool policyFail; bool invalidCert; @@ -1918,9 +2099,10 @@ static void applyDetailProperty(const void *_key, const void *_value, } else if (CFEqual(key, kSecPolicyCheckAnchorTrusted) || CFEqual(key, kSecPolicyCheckAnchorSHA1) || CFEqual(key, kSecPolicyCheckAnchorSHA256) - || CFEqual(key, kSecPolicyCheckAnchorApple) - || CFEqual(key, kSecPolicyCheckMissingIntermediate)) { + || CFEqual(key, kSecPolicyCheckAnchorApple)) { tf->untrustedAnchor = true; + } else if (CFEqual(key, kSecPolicyCheckMissingIntermediate)) { + tf->missingIntermediate = true; } else if (CFEqual(key, kSecPolicyCheckSSLHostname)) { tf->hostnameMismatch = true; } else if (CFEqual(key, kSecPolicyCheckTemporalValidity)) { @@ -2006,6 +2188,9 @@ CFArrayRef SecTrustCopyProperties(SecTrustRef trust) if (tf.untrustedAnchor) { appendError(properties, CFSTR("Root certificate is not trusted."), localized); } + if (tf.missingIntermediate) { + appendError(properties, CFSTR("Unable to build chain to root certificate."), localized); + } if (tf.hostnameMismatch) { appendError(properties, CFSTR("Hostname mismatch."), localized); } diff --git a/OSX/sec/Security/SecuritydXPC.c b/OSX/sec/Security/SecuritydXPC.c index 9c9fdfd1..a9afea35 100644 --- a/OSX/sec/Security/SecuritydXPC.c +++ b/OSX/sec/Security/SecuritydXPC.c @@ -56,9 +56,6 @@ const char *kSecXPCPublicPeerId = "publicPeerId"; // Public peer id const char *kSecXPCOTRSession = "otrsess"; // OTR session bytes const char *kSecXPCData = "data"; // Data to process const char *kSecXPCOTRReady = "otrrdy"; // OTR ready for messages -const char *kSecXPCKeyDeviceID = "deviceID"; -const char *kSecXPCKeySendIDSMessage = "sendIDSMessageCommand"; -const char *kSecXPCKeyIDSMessage = "idsMessage"; const char *kSecXPCKeyViewName = "viewname"; const char *kSecXPCKeyViewActionCode = "viewactioncode"; const char *kSecXPCKeyHSA2AutoAcceptInfo = "autoacceptinfo"; @@ -82,7 +79,7 @@ const char *kSecXPCKeySerialNumber = "serialNum"; const char *kSecXPCKeyBackupKeybagIdentifier = "backupKeybagID"; const char *kSecXPCKeyBackupKeybagPath = "backupKeybagPath"; const char *kSecXPCVersion = "version"; - +const char *kSecXPCKeySignInAnalytics = "signinanalytics"; // // XPC Functions for both client and server. // @@ -135,20 +132,12 @@ CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op) return CFSTR("GetAllTheRings"); case kSecXPCOpGetLastDepartureReason: return CFSTR("GetLastDepartureReason"); - case kSecXPCOpHandleIDSMessage: - return CFSTR("HandleIDSMessage"); case kSecXPCOpSyncWithKVSPeer: return CFSTR("SyncKVSPeer"); - case kSecXPCOpSyncWithIDSPeer: - return CFSTR("SyncIDSPeer"); - case kSecXPCOpIDSDeviceID: - return CFSTR("IDSDeviceID"); case kSecXPCOpClearKVSPeerMessage: return CFSTR("kSecXPCOpClearKVSPeerMessage"); case kSecXPCOpLoggedOutOfAccount: return CFSTR("LoggedOutOfAccount"); - case kSecXPCOpPingTest: - return CFSTR("PingTest"); case kSecXPCOpProcessSyncWithAllPeers: return CFSTR("ProcessSyncWithAllPeers"); case kSecXPCOpProcessSyncWithPeers: @@ -161,32 +150,34 @@ CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op) return CFSTR("RejectApplicants"); case kSecXPCOpRemoveThisDeviceFromCircle: return CFSTR("RemoveThisDeviceFromCircle"); + case kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics: + return CFSTR("RemoveThisDeviceFromCircleWithAnalytics"); case kSecXPCOpRemovePeersFromCircle: return CFSTR("RemovePeersFromCircle"); - case kSecXPCOpRequestDeviceID: - return CFSTR("RequestDeviceID"); + case kSecXPCOpRemovePeersFromCircleWithAnalytics: + return CFSTR("RemovePeersFromCircleWithAnalytics"); case kSecXPCOpRequestEnsureFreshParameters: return CFSTR("RequestEnsureFreshParameters"); case kSecXPCOpRequestToJoin: return CFSTR("RequestToJoin"); + case kSecXPCOpRequestToJoinWithAnalytics: + return CFSTR("RequestToJoinWithAnalytics"); case kSecXPCOpRequestToJoinAfterRestore: return CFSTR("RequestToJoinAfterRestore"); + case kSecXPCOpRequestToJoinAfterRestoreWithAnalytics: + return CFSTR("RequestToJoinAfterRestoreWithAnalytics"); case kSecXPCOpResetToEmpty: return CFSTR("ResetToEmpty"); + case kSecXPCOpResetToEmptyWithAnalytics: + return CFSTR("ResetToEmptyWithAnalytics"); case kSecXPCOpResetToOffering: return CFSTR("ResetToOffering"); case kSecXPCOpRingStatus: return CFSTR("RingStatus"); case kSecXPCOpRollKeys: return CFSTR("RollKeys"); - case kSecXPCOpSecurityProperty: - return CFSTR("SecurityProperty"); - case kSecXPCOpSendIDSMessage: - return CFSTR("SendIDSMessage"); case kSecXPCOpSetBagForAllSlices: return CFSTR("SetBagForAllSlices"); - case kSecXPCOpSetDeviceID: - return CFSTR("SetDeviceID"); case kSecXPCOpSetLastDepartureReason: return CFSTR("SetLastDepartureReason"); case kSecXPCOpSetNewPublicBackupKey: @@ -195,6 +186,8 @@ CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op) return CFSTR("SetUserCredentials"); case kSecXPCOpSetUserCredentialsAndDSID: return CFSTR("SetUserCredentialsAndDSID"); + case kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics: + return CFSTR("SetUserCredentialsAndDSIDWithAnalytics"); case kSecXPCOpTryUserCredentials: return CFSTR("TryUserCredentials"); case kSecXPCOpValidateUserPublic: diff --git a/OSX/sec/Security/Tool/keychain_find.m b/OSX/sec/Security/Tool/keychain_find.m index c396e189..4f5c3fc7 100644 --- a/OSX/sec/Security/Tool/keychain_find.m +++ b/OSX/sec/Security/Tool/keychain_find.m @@ -24,6 +24,7 @@ */ #include +#import #include #include @@ -39,11 +40,14 @@ #include #include +#import + // // Craptastic hacks. - +#ifndef _SECURITY_SECKEYCHAIN_H_ typedef uint32_t SecProtocolType; typedef uint32_t SecAuthenticationType; +#endif static CFMutableDictionaryRef @@ -193,6 +197,10 @@ do_keychain_find_or_delete_internet_password(Boolean do_delete, const void *keys[11], *values[11]; CFIndex ix = 0; + if (do_delete && !serverName && !securityDomain && !accountName && !path && !port && !protocol && !authenticationType) { + return SHOW_USAGE_MESSAGE; + } + keys[ix] = kSecClass; values[ix++] = kSecClassInternetPassword; if (serverName) { @@ -339,6 +347,10 @@ do_keychain_find_or_delete_generic_password(Boolean do_delete, const void *keys[6], *values[6]; CFIndex ix = 0; + if (do_delete && !serviceName && !accountName) { + return SHOW_USAGE_MESSAGE; + } + keys[ix] = kSecClass; values[ix++] = kSecClassGenericPassword; if (serviceName) { @@ -374,8 +386,111 @@ do_keychain_find_or_delete_generic_password(Boolean do_delete, return result; } +static SFServiceIdentifier* serviceIdentifierInQuery(NSDictionary* query) +{ + NSString* domain = query[@"domain"]; + NSString* bundleID = query[@"bundleID"]; + NSString* accessGroup = query[@"accessGroup"]; + NSString* customServiceID = query[@"customServiceID"]; + + SFServiceIdentifier* serviceIdentifier = nil; + if (domain) { + serviceIdentifier = [[SFServiceIdentifier alloc] initWithServiceID:domain forType:SFServiceIdentifierTypeDomain]; + } + else if (bundleID) { + serviceIdentifier = [[SFServiceIdentifier alloc] initWithServiceID:bundleID forType:SFServiceIdentifierTypeBundleID]; + } + else if (accessGroup) { + serviceIdentifier = [[SFServiceIdentifier alloc] initWithServiceID:accessGroup forType:SFServiceIdentifierTypeAccessGroup]; + } + else if (customServiceID) { + serviceIdentifier = [[SFServiceIdentifier alloc] initWithServiceID:customServiceID forType:SFServiceIdentifierTypeCustom]; + } + if (!serviceIdentifier) { + sec_error("need service identifier"); + } + + return serviceIdentifier; +} + +static SFPasswordCredential* lookupCredential(SFServiceIdentifier* serviceIdentifier, NSString* username) +{ + __block SFPasswordCredential* result = nil; + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [[SFCredentialStore defaultCredentialStore] lookupCredentialsForServiceIdentifiers:@[serviceIdentifier] withResultHandler:^(NSArray* results, NSError* error) { + if (error) { + sec_error("error looking up credentials: %s", error.description.UTF8String); + } + else { + bool foundCredential = false; + for (SFPasswordCredential* credential in results) { + if ([credential.username isEqualToString:username]) { + result = credential; + dispatch_semaphore_signal(semaphore); + return; + } + } + + if (!foundCredential) { + sec_error("did not find credential"); + } + } + + dispatch_semaphore_signal(semaphore); + }]; + if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) { + sec_error("timed out trying to communicate with credential store"); + } + + return result; +} + +static SFPasswordCredential* credentialFromQuery(NSDictionary* query) +{ + NSString* username = query[@"username"]; + NSData* passwordData = query[(__bridge id)kSecValueData]; + NSString* password = [[NSString alloc] initWithData:passwordData encoding:NSUTF8StringEncoding]; + if (!username) { + sec_error("need username"); + return nil; + } + if (!password) { + sec_error("need password"); + return nil; + } + + SFServiceIdentifier* serviceIdentifier = serviceIdentifierInQuery(query); + + if (username && password && serviceIdentifier) { + return [[SFPasswordCredential alloc] initWithUsername:username password:password primaryServiceIdentifier:serviceIdentifier]; + } + else { + return nil; + } +} + +static SFAccessPolicy* accessPolicyInQuery(NSDictionary* query) +{ + CFStringRef accessibility = (__bridge CFStringRef)query[(__bridge id)kSecAttrAccessible]; + if (!accessibility) { + accessibility = kSecAttrAccessibleWhenUnlocked; + } + + SFAccessPolicy* accessPolicy = [SFAccessPolicy accessPolicyWithSecAccessibility:accessibility error:nil]; + NSNumber* synchronizableValue = query[(__bridge id)kSecAttrSynchronizable]; + if (accessPolicy.sharingPolicy == SFSharingPolicyWithTrustedDevices && synchronizableValue && synchronizableValue.boolValue == NO) { + accessPolicy.sharingPolicy = SFSharingPolicyWithBackup; + } + if (!accessPolicy) { + sec_error("need access policy"); + } + + return accessPolicy; +} + int keychain_item(int argc, char * const *argv) { - int ch, result = 0; + int ch = 0; + __block int result = 0; CFMutableDictionaryRef query, update = NULL; bool get_password = false; bool do_delete = false; @@ -490,28 +605,116 @@ int keychain_item(int argc, char * const *argv) { CFShow(query); OSStatus error; + bool useCredentialStore = [(__bridge id)CFDictionaryGetValue(query, kSecClass) isEqual:@"credential"]; if (do_add) { - error = SecItemAdd(query, NULL); - if (error) { - sec_perror("SecItemAdd", error); - result = 1; + if (useCredentialStore) { + SFPasswordCredential* credential = credentialFromQuery((__bridge NSDictionary*)query); + SFAccessPolicy* accessPolicy = accessPolicyInQuery((__bridge NSDictionary*)query); + if (credential && accessPolicy) { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [[SFCredentialStore defaultCredentialStore] addCredential:credential withAccessPolicy:accessPolicy resultHandler:^(NSString* persistentIdentifier, NSError* error) { + if (error) { + sec_error("error adding credential to credential store: %s", error.description.UTF8String); + result = 1; + } + dispatch_semaphore_signal(semaphore); + }]; + if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) { + sec_error("timed out waiting for response from credential store"); + result = 1; + } + } + else { + sec_error("need username, password, service identiifer, and access policy to create a credential"); + result = 1; + } + } + else { + error = SecItemAdd(query, NULL); + if (error) { + sec_perror("SecItemAdd", error); + result = 1; + } } } else if (update) { - error = SecItemUpdate(query, update); - if (error) { - sec_perror("SecItemUpdate", error); - result = 1; + if (useCredentialStore) { + NSString* username = (__bridge NSString*)CFDictionaryGetValue(query, CFSTR("username")); + SFServiceIdentifier* serviceIdentifier = serviceIdentifierInQuery((__bridge NSDictionary*)query); + SFPasswordCredential* credential = lookupCredential(serviceIdentifier, username); + if (credential) { + SFPasswordCredential* updatedCredential = credentialFromQuery((__bridge NSDictionary*)update); + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [[SFCredentialStore defaultCredentialStore] replaceOldCredential:credential withNewCredential:updatedCredential resultHandler:^(NSString* newPersistentIdentifier, NSError* error) { + if (error) { + sec_error("error updating credential: %s", error.description.UTF8String); + result = 1; + } + dispatch_semaphore_signal(semaphore); + }]; + if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) { + sec_error("timed out trying to communicate with credential store"); + result = 1; + } + } + else { + result = 1; + } + } + else { + error = SecItemUpdate(query, update); + if (error) { + sec_perror("SecItemUpdate", error); + result = 1; + } } } else if (do_delete) { - error = SecItemDelete(query); - if (error) { - sec_perror("SecItemDelete", error); - result = 1; + if (useCredentialStore) { + NSString* username = (__bridge NSString*)CFDictionaryGetValue(query, CFSTR("username")); + SFServiceIdentifier* serviceIdentifier = serviceIdentifierInQuery((__bridge NSDictionary*)query); + SFPasswordCredential* credential = lookupCredential(serviceIdentifier, username); + if (credential) { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [[SFCredentialStore defaultCredentialStore] removeCredentialWithPersistentIdentifier:credential.persistentIdentifier withResultHandler:^(BOOL success, NSError* error) { + if (!success) { + sec_error("failed to remove credential with error: %s", error.description.UTF8String); + result = 1; + } + dispatch_semaphore_signal(semaphore); + }]; + if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) { + sec_error("timed out trying to communicate with credential store"); + result = 1; + } + } + else { + result = 1; + } + } + else { + error = SecItemDelete(query); + if (error) { + sec_perror("SecItemDelete", error); + result = 1; + } } } else { - if (!do_delete && CFDictionaryGetValue(query, kSecUseAuthenticationUI) == NULL) - CFDictionarySetValue(query, kSecUseAuthenticationUI, kSecUseAuthenticationUISkip); - do_find_or_delete(query, do_delete); + if (useCredentialStore) { + NSString* username = (__bridge NSString*)CFDictionaryGetValue(query, CFSTR("username")); + SFServiceIdentifier* serviceIdentifier = serviceIdentifierInQuery((__bridge NSDictionary*)query); + SFPasswordCredential* credential = lookupCredential(serviceIdentifier, username); + if (credential) { + CFStringWriteToFileWithNewline((__bridge CFStringRef)credential.description, stdout); + } + else { + result = 1; + } + } + else { + if (!do_delete && CFDictionaryGetValue(query, kSecUseAuthenticationUI) == NULL) { + CFDictionarySetValue(query, kSecUseAuthenticationUI, kSecUseAuthenticationUISkip); + } + do_find_or_delete(query, do_delete); + } } out: diff --git a/OSX/sec/Security/ios_tapi_hacks.h b/OSX/sec/Security/ios_tapi_hacks.h index 3719e13f..bd6b59fe 100644 --- a/OSX/sec/Security/ios_tapi_hacks.h +++ b/OSX/sec/Security/ios_tapi_hacks.h @@ -60,6 +60,10 @@ extern SecurityClient * SecSecurityClientGet(void); bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error, bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), bool (^handle_response)(xpc_object_t response, CFErrorRef* error)); +typedef void (^securityd_handler_t)(xpc_object_t reply, CFErrorRef error); +void securityd_send_async_and_do(enum SecXPCOperation op, dispatch_queue_t replyq, + bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), + securityd_handler_t handler); XPC_RETURNS_RETAINED xpc_object_t securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error); XPC_RETURNS_RETAINED xpc_object_t securityd_create_message(enum SecXPCOperation op, CFErrorRef *error); bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error); diff --git a/OSX/sec/Security/p12pbegen.c b/OSX/sec/Security/p12pbegen.c index 92c05be9..17abc062 100644 --- a/OSX/sec/Security/p12pbegen.c +++ b/OSX/sec/Security/p12pbegen.c @@ -152,13 +152,25 @@ int p12_pbe_gen(CFStringRef passphrase, uint8_t *salt_ptr, size_t salt_length, /* tmp1 = B+1 */ const cc_size tmp_n = ccn_nof_size(A_i_len + 1) > ccn_nof_size(hash_blocksize) ? ccn_nof_size(A_i_len + 1) : ccn_nof_size(hash_blocksize); - cc_unit tmp1[tmp_n]; + cc_unit *tmp1 = (cc_unit *)malloc(tmp_n * sizeof(cc_unit)); + if (!tmp1) { + free(A_i); + free(I_data); + free(temp_buf); + return -1; + } ccn_read_uint(tmp_n, tmp1, A_i_len, A_i); ccn_add1(tmp_n, tmp1, tmp1, 1); free(A_i); - cc_unit tmp2[tmp_n]; + cc_unit *tmp2 = (cc_unit *)malloc(tmp_n * sizeof(cc_unit)); + if (!tmp2) { + free(I_data); + free(temp_buf); + free(tmp1); + return -1; + } unsigned int j; for (j = 0; j < I_length; j+=hash_blocksize) { /* tempg = I[j]; */ @@ -182,6 +194,8 @@ int p12_pbe_gen(CFStringRef passphrase, uint8_t *salt_ptr, size_t salt_length, } cursor += hash_outputsize; + free(tmp1); + free(tmp2); } /* diff --git a/OSX/sec/SecurityTool/sos.m b/OSX/sec/SecurityTool/sos.m index 33558c8b..0b9b7448 100644 --- a/OSX/sec/SecurityTool/sos.m +++ b/OSX/sec/SecurityTool/sos.m @@ -88,16 +88,6 @@ dispatch_semaphore_signal(sema1); }]; - - [[self.connection remoteObjectProxy] idsPerformanceCounters:^(NSDictionary *counters){ - if (counters == NULL){ - printf("no IDS counters!"); - return; - } - [merged addEntriesFromDictionary:counters]; - dispatch_semaphore_signal(sema2); - }]; - [[self.connection remoteObjectProxy] rateLimitingPerformanceCounters:^(NSDictionary *returnedDiagnostics){ if (returnedDiagnostics == NULL){ printf("no rate limiting counters!"); diff --git a/OSX/sec/SharedWebCredential/swcagent.m b/OSX/sec/SharedWebCredential/swcagent.m index a4cad0c8..862b8376 100644 --- a/OSX/sec/SharedWebCredential/swcagent.m +++ b/OSX/sec/SharedWebCredential/swcagent.m @@ -331,7 +331,6 @@ static CFOptionFlags swca_handle_request(enum SWCAXPCOperation operation, Client CFUserNotificationRef notification = NULL; NSMutableDictionary *notification_dictionary = NULL; NSString *request_key; - NSString *request_format; NSString *default_button_key; NSString *alternate_button_key; NSString *other_button_key; @@ -390,16 +389,12 @@ check_database: goto out; } request_key = [NSString stringWithFormat:@"SWC_REQUEST_%s", op]; - request_format = NSLocalizedStringFromTableInBundle(request_key, swca_string_table, swca_get_security_bundle(), nil); alternate_button_key = (op) ? [NSString stringWithFormat:@"SWC_ALLOW_%s", op] : nil; default_button_key = @"SWC_NEVER"; other_button_key = @"SWC_DENY"; info_message_key = @"SWC_INFO_MESSAGE"; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wformat-nonliteral" - notification_dictionary[(__bridge NSString *)kCFUserNotificationAlertHeaderKey] = [NSString stringWithFormat:request_format, client.client_name, domain]; -#pragma clang diagnostic pop + notification_dictionary[(__bridge NSString *)kCFUserNotificationAlertHeaderKey] = NSLocalizedStringFromTableInBundle(request_key, swca_string_table, swca_get_security_bundle(), nil);; notification_dictionary[(__bridge NSString *)kCFUserNotificationAlertMessageKey] = NSLocalizedStringFromTableInBundle(info_message_key, swca_string_table, swca_get_security_bundle(), nil); notification_dictionary[(__bridge NSString *)kCFUserNotificationDefaultButtonTitleKey] = NSLocalizedStringFromTableInBundle(default_button_key, swca_string_table, swca_get_security_bundle(), nil); notification_dictionary[(__bridge NSString *)kCFUserNotificationAlternateButtonTitleKey] = NSLocalizedStringFromTableInBundle(alternate_button_key, swca_string_table, swca_get_security_bundle(), nil); @@ -709,14 +704,15 @@ static void swca_xpc_dictionary_handler(const xpc_connection_t connection, xpc_o // select a dictionary from an input array of dictionaries if (swca_select_item(items, client, accessGroups, &result, &error) && result) { #if TARGET_OS_IOS - if (MGGetBoolAnswer(kMGOPearlIDCapability) && + LAContext *ctx = [LAContext new]; + if ([ctx canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil] && [[MCProfileConnection sharedConnection] isAuthenticationBeforeAutoFillRequired]) { - LAContext *ctx = [LAContext new]; NSString *subTitle = NSLocalizedStringFromTableInBundle(@"SWC_FILLPWD", swca_string_table, swca_get_security_bundle(), nil); dispatch_semaphore_t sema = dispatch_semaphore_create(0); [ctx evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:subTitle reply:^(BOOL success, NSError * _Nullable laError) { - if (success || ([laError.domain isEqual:LAErrorDomain] && laError.code == LAErrorPasscodeNotSet)) + if (success || ([laError.domain isEqual:LAErrorDomain] && laError.code == LAErrorPasscodeNotSet)) { SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error); + } dispatch_semaphore_signal(sema); }]; dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); diff --git a/OSX/sec/SharedWebCredential/swcagent_client.h b/OSX/sec/SharedWebCredential/swcagent_client.h index 485e76b7..ea6c5023 100644 --- a/OSX/sec/SharedWebCredential/swcagent_client.h +++ b/OSX/sec/SharedWebCredential/swcagent_client.h @@ -62,9 +62,6 @@ extern const char *kSecXPCKeyDomain; extern const char *kSecXPCKeyDigest; extern const char *kSecXPCKeyCertificate; extern const char *kSecXPCKeySettings; -extern const char *kSecXPCKeyDeviceID; -extern const char *kSecXPCKeyIDSMessage; -extern const char *kSecXPCKeySendIDSMessage; extern const char *kSecXPCKeyEscrowLabel; extern const char *kSecXPCKeyTriesLabel; extern const char *kSecXPCKeyViewName; diff --git a/OSX/sec/ipc/client.c b/OSX/sec/ipc/client.c index eb722c63..c2b1c383 100644 --- a/OSX/sec/ipc/client.c +++ b/OSX/sec/ipc/client.c @@ -58,6 +58,8 @@ #include #include +#include "server_security_helpers.h" + struct securityd *gSecurityd; struct trustd *gTrustd; @@ -74,6 +76,7 @@ static CFArrayRef SecServerCopyAccessGroups(void) { CFSTR("lockdown-identities"), CFSTR("123456.test.group"), CFSTR("123456.test.group2"), + CFSTR("com.apple.cfnetwork"), #else CFSTR("sync"), #endif @@ -82,6 +85,7 @@ static CFArrayRef SecServerCopyAccessGroups(void) { CFSTR("com.apple.security.sos-usercredential"), CFSTR("com.apple.sbd"), CFSTR("com.apple.lakitu"), + CFSTR("com.apple.security.securityd"), kSecAttrAccessGroupToken, NULL); } @@ -123,7 +127,6 @@ CFArrayRef SecAccessGroupsGetCurrent(void) { } // Only for testing. -void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); void SecAccessGroupsSetCurrent(CFArrayRef accessGroups) { // Not thread safe at all, but OK because it is meant to be used only by tests. gClient.accessGroups = accessGroups; @@ -254,6 +257,46 @@ void SecServerSetTrustdMachServiceName(const char *name) { xpc_release(oldConection); } + +#define SECURITYD_MAX_XPC_TRIES 4 +// Per N61/12A342: Audio Playback... for why this needs to be at least 3, so we made it 4. + +static bool +_securityd_process_message_reply(xpc_object_t *reply, + CFErrorRef *error, + xpc_connection_t connection, + uint64_t operation) +{ + if (xpc_get_type(*reply) != XPC_TYPE_ERROR) { + return true; + } + CFIndex code = 0; + if (*reply == XPC_ERROR_CONNECTION_INTERRUPTED || *reply == XPC_ERROR_CONNECTION_INVALID) { + code = kSecXPCErrorConnectionFailed; + seccritical("Failed to talk to %s after %d attempts.", + (is_trust_operation((enum SecXPCOperation)operation)) ? "trustd" : +#if TARGET_OS_IPHONE + "securityd", +#else + "secd", +#endif + SECURITYD_MAX_XPC_TRIES); + } else if (*reply == XPC_ERROR_TERMINATION_IMMINENT) { + code = kSecXPCErrorUnknown; + } else { + code = kSecXPCErrorUnknown; + } + + char *conn_desc = xpc_copy_description(connection); + const char *description = xpc_dictionary_get_string(*reply, XPC_ERROR_KEY_DESCRIPTION); + SecCFCreateErrorWithFormat(code, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("%s: %s"), conn_desc, description); + free(conn_desc); + xpc_release(*reply); + *reply = NULL; + return false; +} + + XPC_RETURNS_RETAINED xpc_object_t securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error) @@ -262,7 +305,7 @@ securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error) uint64_t operation = xpc_dictionary_get_uint64(message, kSecXPCKeyOperation); xpc_connection_t connection = securityd_connection_for_operation((enum SecXPCOperation)operation); - const int max_tries = 4; // Per N61/12A342: Audio Playback... for why this needs to be at least 3, so we made it 4. + const int max_tries = SECURITYD_MAX_XPC_TRIES; unsigned int tries_left = max_tries; do { @@ -270,34 +313,46 @@ securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error) reply = xpc_connection_send_message_with_reply_sync(connection, message); } while (reply == XPC_ERROR_CONNECTION_INTERRUPTED && --tries_left > 0); - if (xpc_get_type(reply) == XPC_TYPE_ERROR) { - CFIndex code = 0; - if (reply == XPC_ERROR_CONNECTION_INTERRUPTED || reply == XPC_ERROR_CONNECTION_INVALID) { - code = kSecXPCErrorConnectionFailed; - seccritical("Failed to talk to %s after %d attempts.", - (is_trust_operation((enum SecXPCOperation)operation)) ? "trustd" : -#if TARGET_OS_IPHONE - "securityd", -#else - "secd", -#endif - max_tries); - } else if (reply == XPC_ERROR_TERMINATION_IMMINENT) - code = kSecXPCErrorUnknown; - else - code = kSecXPCErrorUnknown; - - char *conn_desc = xpc_copy_description(connection); - const char *description = xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION); - SecCFCreateErrorWithFormat(code, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("%s: %s"), conn_desc, description); - free(conn_desc); - xpc_release(reply); - reply = NULL; - } + _securityd_process_message_reply(&reply, error, connection, operation); return reply; } +static void +_securityd_message_with_reply_async_inner(xpc_object_t message, + dispatch_queue_t replyq, + securityd_handler_t handler, + uint32_t tries_left) +{ + uint64_t operation = xpc_dictionary_get_uint64(message, kSecXPCKeyOperation); + xpc_connection_t connection = securityd_connection_for_operation((enum SecXPCOperation)operation); + + xpc_retain(message); + dispatch_retain(replyq); + securityd_handler_t handlerCopy = Block_copy(handler); + xpc_connection_send_message_with_reply(connection, message, replyq, ^(xpc_object_t _Nonnull reply) { + if (reply == XPC_ERROR_CONNECTION_INTERRUPTED && tries_left > 0) { + _securityd_message_with_reply_async_inner(message, replyq, handlerCopy, tries_left - 1); + } else { + CFErrorRef error = NULL; + _securityd_process_message_reply(&reply, &error, connection, operation); + handlerCopy(reply, error); + CFReleaseNull(error); + } + xpc_release(message); + dispatch_release(replyq); + Block_release(handlerCopy); + }); +} + +void +securityd_message_with_reply_async(xpc_object_t message, + dispatch_queue_t replyq, + securityd_handler_t handler) +{ + _securityd_message_with_reply_async_inner(message, replyq, handler, SECURITYD_MAX_XPC_TRIES); +} + XPC_RETURNS_RETAINED xpc_object_t securityd_create_message(enum SecXPCOperation op, CFErrorRef* error) @@ -363,6 +418,42 @@ bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error, return ok; } +void securityd_send_async_and_do(enum SecXPCOperation op, dispatch_queue_t replyq, + bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), + securityd_handler_t handler) { + CFErrorRef error = NULL; + xpc_object_t message = securityd_create_message(op, &error); + if (message == NULL) { + handler(NULL, error); + CFReleaseNull(error); + return; + } + + if (add_to_message != NULL) { + if (!add_to_message(message, &error)) { + handler(NULL, error); + xpc_release(message); + CFReleaseNull(error); + return; + } + } + + securityd_message_with_reply_async(message, replyq, ^(xpc_object_t reply, CFErrorRef error2) { + if (error2 != NULL) { + handler(NULL, error2); + return; + } + CFErrorRef error3 = NULL; + if (!securityd_message_no_error(reply, &error3)) { + handler(NULL, error3); + CFReleaseNull(error3); + return; + } + handler(reply, NULL); + }); + xpc_release(message); +} + CFDictionaryRef _SecSecuritydCopyWhoAmI(CFErrorRef *error) @@ -488,3 +579,9 @@ _SecSecuritydCopyKeychainControlEndpoint(CFErrorRef* error) { return _SecSecuritydCopyEndpoint(kSecXPCOpKeychainControlEndpoint, error); } + +XPC_RETURNS_RETAINED xpc_endpoint_t +_SecSecuritydCopySFKeychainEndpoint(CFErrorRef* error) +{ + return _SecSecuritydCopyEndpoint(kSecXPCOpSFKeychainEndpoint, error); +} diff --git a/OSX/sec/ipc/com.apple.secd.plist b/OSX/sec/ipc/com.apple.secd.plist index c3470d0f..0824d373 100644 --- a/OSX/sec/ipc/com.apple.secd.plist +++ b/OSX/sec/ipc/com.apple.secd.plist @@ -28,6 +28,8 @@ com.apple.securityd.sos + com.apple.security.sfkeychainserver + ProgramArguments diff --git a/OSX/sec/ipc/com.apple.securityd.plist b/OSX/sec/ipc/com.apple.securityd.plist index 5de57431..a0d71850 100644 --- a/OSX/sec/ipc/com.apple.securityd.plist +++ b/OSX/sec/ipc/com.apple.securityd.plist @@ -31,6 +31,8 @@ com.apple.securityd.sos + com.apple.security.sfkeychainserver + ProgramArguments diff --git a/OSX/sec/ipc/securityd_client.h b/OSX/sec/ipc/securityd_client.h index 30c08c05..496f67a4 100644 --- a/OSX/sec/ipc/securityd_client.h +++ b/OSX/sec/ipc/securityd_client.h @@ -110,6 +110,18 @@ extern const char *kSecXPCKeyBackupKeybagPath; #define SECURITYD_XPC(sdp, wrapper, ...) ((gSecurityd && gSecurityd->sdp) ? gSecurityd->sdp(__VA_ARGS__) : wrapper(sdp ## _id, __VA_ARGS__)) #define TRUSTD_XPC(sdp, wrapper, ...) ((gTrustd && gTrustd->sdp) ? gTrustd->sdp(__VA_ARGS__) : wrapper(sdp ## _id, __VA_ARGS__)) +#define TRUSTD_XPC_ASYNC(sdp, wrapper, q, h, ...) do { \ + if (gTrustd != NULL && gTrustd->sdp != NULL) { \ + dispatch_async(q, ^{ \ + CFErrorRef _error = NULL; \ + SecTrustResultType _tr = gTrustd->sdp(__VA_ARGS__, &_error); \ + h(_tr, _error); \ + }); \ + } else { \ + wrapper(q, h, sdp ## _id, __VA_ARGS__); \ + } \ +} while (0) + // // MARK: Object to XPC format conversion. // @@ -138,11 +150,8 @@ extern const char *kSecXPCPublicPeerId; // Public peer id extern const char *kSecXPCOTRSession; // OTR session bytes extern const char *kSecXPCData; // Data to process extern const char *kSecXPCOTRReady; // OTR ready for messages -extern const char *kSecXPCKeyDeviceID; -extern const char *kSecXPCKeyIDSMessage; extern const char *kSecXPCKeyViewName; extern const char *kSecXPCKeyViewActionCode; -extern const char *kSecXPCKeySendIDSMessage; extern const char *kSecXPCKeyHSA2AutoAcceptInfo; extern const char *kSecXPCKeyEscrowLabel; extern const char *kSecXPCKeyTriesLabel; @@ -151,7 +160,7 @@ extern const char *kSecXPCKeyArray; extern const char *kSecXPCKeySet; extern const char *kSecXPCKeySet2; extern const char *kSecXPCVersion; - +extern const char *kSecXPCKeySignInAnalytics; extern const char *kSecXPCKeyReason; // @@ -213,18 +222,24 @@ enum SecXPCOperation { kSecXPCOpTryUserCredentials, kSecXPCOpSetUserCredentials, kSecXPCOpSetUserCredentialsAndDSID, + kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics, kSecXPCOpCanAuthenticate, kSecXPCOpPurgeUserCredentials, kSecXPCOpDeviceInCircle, kSecXPCOpRequestToJoin, + kSecXPCOpRequestToJoinWithAnalytics, kSecXPCOpRequestToJoinAfterRestore, + kSecXPCOpRequestToJoinAfterRestoreWithAnalytics, kSecXPCOpResetToOffering, kSecXPCOpResetToEmpty, + kSecXPCOpResetToEmptyWithAnalytics, kSecXPCOpView, kSecXPCOpViewSet, - kSecXPCOpSecurityProperty, + kSecXPCOpViewSetWithAnalytics, kSecXPCOpRemoveThisDeviceFromCircle, + kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics, kSecXPCOpRemovePeersFromCircle, + kSecXPCOpRemovePeersFromCircleWithAnalytics, kSecXPCOpLoggedOutOfAccount, kSecXPCOpBailFromCircle, kSecXPCOpAcceptApplicants, @@ -247,6 +262,7 @@ enum SecXPCOperation { kSecXPCOpSetNewPublicBackupKey, kSecXPCOpSetBagForAllSlices, kSecXPCOpWaitForInitialSync, + kSecXPCOpWaitForInitialSyncWithAnalytics, kSecXPCOpCopyYetToSyncViews, kSecXPCOpSetEscrowRecord, kSecXPCOpGetEscrowRecord, @@ -288,6 +304,7 @@ enum SecXPCOperation { sec_item_certificate_exists_id, kSecXPCOpBackupKeybagAdd, kSecXPCOpBackupKeybagDelete, + kSecXPCOpSFKeychainEndpoint, kSecXPCOpKeychainControlEndpoint, kSecXPCOpTLSAnaltyicsReport, }; @@ -340,34 +357,34 @@ struct securityd { bool (*soscc_TryUserCredentials)(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); bool (*soscc_SetUserCredentials)(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error); bool (*soscc_SetUserCredentialsAndDSID)(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); + bool (*soscc_SetUserCredentialsAndDSIDWithAnalytics)(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error); bool (*soscc_CanAuthenticate)(CFErrorRef *error); bool (*soscc_PurgeUserCredentials)(CFErrorRef *error); SOSCCStatus (*soscc_ThisDeviceIsInCircle)(CFErrorRef* error); bool (*soscc_RequestToJoinCircle)(CFErrorRef* error); + bool (*soscc_RequestToJoinCircleWithAnalytics)(CFDataRef parentEvent, CFErrorRef* error); bool (*soscc_RequestToJoinCircleAfterRestore)(CFErrorRef* error); + bool (*soscc_RequestToJoinCircleAfterRestoreWithAnalytics)(CFDataRef parentEvent, CFErrorRef* error); bool (*soscc_RequestEnsureFreshParameters)(CFErrorRef* error); CFStringRef (*soscc_GetAllTheRings)(CFErrorRef *error); bool (*soscc_ApplyToARing)(CFStringRef ringName, CFErrorRef* error); bool (*soscc_WithdrawlFromARing)(CFStringRef ringName, CFErrorRef* error); bool (*soscc_EnableRing)(CFStringRef ringName, CFErrorRef* error); SOSRingStatus (*soscc_RingStatus)(CFStringRef ringName, CFErrorRef* error); - CFStringRef (*soscc_CopyDeviceID)(CFErrorRef* error); - bool (*soscc_SetDeviceID)(CFStringRef IDS, CFErrorRef *error); - HandleIDSMessageReason (*soscc_HandleIDSMessage)(CFDictionaryRef IDS, CFErrorRef *error); - bool (*soscc_CheckIDSRegistration)(CFStringRef message, CFErrorRef *error); - bool (*soscc_PingTest)(CFStringRef message, CFErrorRef *error); - bool (*soscc_GetIDSIDFromIDS)(CFErrorRef *error); bool (*soscc_SetToNew)(CFErrorRef *error); bool (*soscc_ResetToOffering)(CFErrorRef* error); bool (*soscc_ResetToEmpty)(CFErrorRef* error); + bool (*soscc_ResetToEmptyWithAnalytics)(CFDataRef parentEvent, CFErrorRef* error); SOSViewResultCode (*soscc_View)(CFStringRef view, SOSViewActionCode action, CFErrorRef *error); bool (*soscc_ViewSet)(CFSetRef enabledViews, CFSetRef disabledViews); - SOSSecurityPropertyResultCode (*soscc_SecurityProperty)(CFStringRef property, SOSSecurityPropertyActionCode action, CFErrorRef *error); + bool (*soscc_ViewSetWithAnalytics)(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent); bool (*soscc_RegisterSingleRecoverySecret)(CFDataRef backupSlice, bool forV0Only, CFErrorRef *error); bool (*soscc_RegisterRecoveryPublicKey)(CFDataRef recovery_key, CFErrorRef *error); CFDataRef (*soscc_CopyRecoveryPublicKey)(CFErrorRef *error); bool (*soscc_RemoveThisDeviceFromCircle)(CFErrorRef* error); + bool (*soscc_RemoveThisDeviceFromCircleWithAnalytics)(CFDataRef parentEvent, CFErrorRef* error); bool (*soscc_RemovePeersFromCircle)(CFArrayRef peers, CFErrorRef* error); + bool (*soscc_RemovePeersFromCircleWithAnalytics)(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error); bool (*soscc_LoggedOutOfAccount)(CFErrorRef* error); bool (*soscc_BailFromCircle)(uint64_t limit_in_seconds, CFErrorRef* error); bool (*soscc_AcceptApplicants)(CFArrayRef applicants, CFErrorRef* error); @@ -397,6 +414,7 @@ struct securityd { bool (*sec_set_circle_log_settings)(CFTypeRef type, CFErrorRef* error); SOSPeerInfoRef (*soscc_CopyMyPeerInfo)(CFErrorRef*); bool (*soscc_WaitForInitialSync)(CFErrorRef*); + bool (*soscc_WaitForInitialSyncWithAnalytics)(CFDataRef parentEvent, CFErrorRef *error); CFArrayRef (*soscc_CopyYetToSyncViewsList)(CFErrorRef*); bool (*soscc_SetEscrowRecords)(CFStringRef escrow_label, uint64_t tries, CFErrorRef *error); CFDictionaryRef (*soscc_CopyEscrowRecords)(CFErrorRef *error); @@ -419,10 +437,8 @@ struct securityd { bool (*sec_delete_items_with_access_groups)(CFArrayRef bundleIDs, SecurityClient *client, CFErrorRef *error); bool (*soscc_IsThisDeviceLastBackup)(CFErrorRef *error); bool (*soscc_requestSyncWithPeerOverKVS)(CFStringRef peerID, CFDataRef message, CFErrorRef *error); - bool (*soscc_requestSyncWithPeerOverIDS)(CFStringRef peerID, CFErrorRef *error); CFBooleanRef (*soscc_SOSCCPeersHaveViewsEnabled)(CFArrayRef views, CFErrorRef *error); bool (*socc_clearPeerMessageKeyInKVS)(CFStringRef peerID, CFErrorRef *error); - bool (*soscc_requestSyncWithPeerOverKVSIDOnly)(CFStringRef peerID, CFErrorRef *error); bool (*soscc_SOSCCMessageFromPeerIsPending)(SOSPeerInfoRef peer, CFErrorRef* error); bool (*soscc_SOSCCSendToPeerIsPending)(SOSPeerInfoRef peer, CFErrorRef* error); CFTypeRef (*soscc_status)(void); @@ -454,6 +470,9 @@ CFArrayRef SecAccessGroupsGetCurrent(void); // TODO Rename me CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op); XPC_RETURNS_RETAINED xpc_object_t securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error); +typedef void (^securityd_handler_t)(xpc_object_t reply, CFErrorRef error); +void securityd_message_with_reply_async(xpc_object_t message, dispatch_queue_t replyq, + securityd_handler_t handler); XPC_RETURNS_RETAINED xpc_object_t securityd_create_message(enum SecXPCOperation op, CFErrorRef *error); bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error); @@ -462,6 +481,10 @@ bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error, bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), bool (^handle_response)(xpc_object_t response, CFErrorRef* error)); +void securityd_send_async_and_do(enum SecXPCOperation op, dispatch_queue_t replyq, + bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), + securityd_handler_t handler); + // For testing only, never call this in a threaded program! void SecServerSetTrustdMachServiceName(const char *name); diff --git a/OSX/sec/ipc/server.c b/OSX/sec/ipc/server.c index e338b59a..111b1165 100644 --- a/OSX/sec/ipc/server.c +++ b/OSX/sec/ipc/server.c @@ -66,6 +66,8 @@ #include #include "keychain/ot/OctagonControlServer.h" +#include + #include #include #include @@ -845,6 +847,19 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, }); } break; + case kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics: + if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + with_label_and_password_and_dsid(event, ^(CFStringRef label, CFDataRef password, CFStringRef dsid) { + CFDataRef parentEvent = NULL; + if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetUserCredentialsAndDSIDWithAnalytics_Server(label, password, dsid, parentEvent, &error)); + }else{ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetUserCredentialsAndDSID_Server(label, password, dsid, &error)); + } + CFReleaseNull(parentEvent); + }); + } + break; case kSecXPCOpView: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { with_label_and_number(event, ^(CFStringRef view, uint64_t actionCode) { @@ -862,13 +877,20 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, CFReleaseNull(disabledViews); } break; - case kSecXPCOpSecurityProperty: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - with_label_and_number(event, ^(CFStringRef property, uint64_t actionCode) { - xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult, - SOSCCSecurityProperty_Server(property, (SOSSecurityPropertyActionCode)actionCode, &error)); - }); - } + case kSecXPCOpViewSetWithAnalytics: + if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + CFSetRef enabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyEnabledViewsKey); + CFSetRef disabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyDisabledViewsKey); + CFDataRef parentEvent = NULL; + if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCViewSetWithAnalytics_Server(enabledViews, disabledViews, parentEvent)); + }else{ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCViewSet_Server(enabledViews, disabledViews)); + } + CFReleaseNull(enabledViews); + CFReleaseNull(disabledViews); + CFReleaseNull(parentEvent); + } break; case kSecXPCOpCanAuthenticate: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { @@ -894,6 +916,17 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, SOSCCRequestToJoinCircle_Server(&error)); } break; + case kSecXPCOpRequestToJoinWithAnalytics: + if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + CFDataRef parentEvent = NULL; + if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircleWithAnalytics_Server(parentEvent, &error)); + }else{ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircle_Server(&error)); + } + CFReleaseNull(parentEvent); + } + break; case kSecXPCOpAccountHasPublicKey: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, @@ -912,6 +945,17 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, SOSCCRequestToJoinCircleAfterRestore_Server(&error)); } break; + case kSecXPCOpRequestToJoinAfterRestoreWithAnalytics: + if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + CFDataRef parentEvent = NULL; + if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircleAfterRestoreWithAnalytics_Server(parentEvent, &error)); + }else{ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircleAfterRestore_Server(&error)); + } + CFReleaseNull(parentEvent); + } + break; case kSecXPCOpRequestEnsureFreshParameters: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, @@ -955,68 +999,14 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpRequestDeviceID: - if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFStringRef deviceID = SOSCCCopyDeviceID_Server(&error); - if (deviceID) { - SecXPCDictionarySetString(replyMessage, kSecXPCKeyResult, deviceID, &error); - } - CFReleaseNull(deviceID); - } - break; case kSecXPCOpSetDeviceID: - if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFStringRef IDS = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetDeviceID_Server(IDS, &error)); - CFReleaseNull(IDS); - } - break; case kSecXPCOpHandleIDSMessage: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFDictionaryRef IDS = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyIDSMessage, &error); - xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult, SOSCCHandleIDSMessage_Server(IDS, &error)); - CFReleaseNull(IDS); - } - break; - case kSecXPCOpClearKVSPeerMessage: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFStringRef peerID = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCClearPeerMessageKeyInKVS_Server(peerID, &error)); - CFReleaseNull(peerID); - } - break; + case kSecXPCOpSyncWithIDSPeer: case kSecXPCOpSendIDSMessage: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFStringRef message = SecXPCDictionaryCopyString(event, kSecXPCKeySendIDSMessage, &error); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSServiceRegistrationTest_Server(message, &error)); - CFReleaseNull(message); - } - break; - case kSecXPCOpSyncWithKVSPeer: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFStringRef peerID = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error); - CFDataRef message = SecXPCDictionaryCopyData(event, kSecXPCKeyIDSMessage, &error); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestSyncWithPeerOverKVS_Server(peerID, message, &error)); - CFReleaseNull(message); - CFReleaseNull(peerID); - } - break; - case kSecXPCOpSyncWithKVSPeerIDOnly: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFStringRef peerID = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestSyncWithPeerOverKVSUsingIDOnly_Server(peerID, &error)); - CFReleaseNull(peerID); - } - break; case kSecXPCOpPingTest: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFStringRef message = SecXPCDictionaryCopyString(event, kSecXPCKeySendIDSMessage, &error); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSPingTest_Server(message, &error)); - CFReleaseNull(message); - } - break; case kSecXPCOpIDSDeviceID: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSDeviceIDIsAvailableTest_Server(&error)); + case kSecXPCOpSyncWithKVSPeerIDOnly:{ + xpc_dictionary_set_int64(replyMessage, kSecXPCKeyError, errSecUnimplemented); } break; case kSecXPCOpAccountSetToNew: @@ -1036,12 +1026,33 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, SOSCCResetToEmpty_Server(&error)); } break; + case kSecXPCOpResetToEmptyWithAnalytics: + if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + CFDataRef parentEvent = NULL; + if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCResetToEmptyWithAnalytics_Server(parentEvent, &error)); + }else{ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCResetToEmpty_Server(&error)); + } + } + break; case kSecXPCOpRemoveThisDeviceFromCircle: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemoveThisDeviceFromCircle_Server(&error)); } break; + case kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics: + if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + CFDataRef parentEvent = NULL; + if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemoveThisDeviceFromCircleWithAnalytics_Server(parentEvent, &error)); + }else{ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemoveThisDeviceFromCircle_Server(&error)); + } + CFReleaseNull(parentEvent); + } + break; case kSecXPCOpRemovePeersFromCircle: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { CFArrayRef applicants = SecXPCDictionaryCopyPeerInfoArray(event, kSecXPCKeyPeerInfoArray, &error); @@ -1050,6 +1061,19 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, CFReleaseNull(applicants); } break; + case kSecXPCOpRemovePeersFromCircleWithAnalytics: + if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + CFArrayRef applicants = SecXPCDictionaryCopyPeerInfoArray(event, kSecXPCKeyPeerInfoArray, &error); + CFDataRef parentEvent = NULL; + if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemovePeersFromCircleWithAnalytics_Server(applicants, parentEvent, &error)); + }else{ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemovePeersFromCircle_Server(applicants, &error)); + } + CFReleaseNull(parentEvent); + CFReleaseNull(applicants); + } + break; case kSecXPCOpLoggedOutOfAccount: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, @@ -1333,6 +1357,17 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; + case kSecXPCOpWaitForInitialSyncWithAnalytics: + if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + CFDataRef parentEvent = NULL; + if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCWaitForInitialSyncWithAnalytics_Server(parentEvent, &error)); + }else{ + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCWaitForInitialSync_Server(&error)); + } + CFReleaseNull(parentEvent); + } + break; case kSecXPCOpCopyYetToSyncViews: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { CFArrayRef array = SOSCCCopyYetToSyncViewsList_Server(&error); @@ -1378,13 +1413,6 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, CFReleaseNull(record); } break; - - case kSecXPCOpCheckPeerAvailability: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCCheckPeerAvailability_Server(&error)); - } - break; - case kSecXPCOpIsThisDeviceLastBackup: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { @@ -1716,9 +1744,6 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } if (xpcError) xpc_release(xpcError); -#if TARGET_OS_IPHONE - pthread_setspecific(taskThreadKey, NULL); -#endif CFReleaseSafe(error); CFReleaseSafe(client.accessGroups); CFReleaseSafe(client.musr); @@ -1729,11 +1754,6 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, static void securityd_xpc_init(const char *service_name) { -#if TARGET_OS_IPHONE - pthread_key_create(&taskThreadKey, NULL); - SecTaskDiagnoseEntitlements = secTaskDiagnoseEntitlements; -#endif - secdebug("serverxpc", "start"); xpc_connection_t listener = xpc_connection_create_mach_service(service_name, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER); if (!listener) { @@ -1745,13 +1765,24 @@ static void securityd_xpc_init(const char *service_name) if (xpc_get_type(connection) == XPC_TYPE_CONNECTION) { xpc_connection_set_event_handler(connection, ^(xpc_object_t event) { if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) { - xpc_retain(connection); - xpc_retain(event); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + /* + * rdar://problem/37690394&39323293 + * Some operations cannot be performed synchronously. + * SecItemCopyMatching is particularly important, and + * should be safe to perform synchronously. + */ + uint64_t operation = xpc_dictionary_get_uint64(event, kSecXPCKeyOperation); + if (operation == sec_item_copy_matching_id) { securityd_xpc_dictionary_handler(connection, event); - xpc_release(event); - xpc_release(connection); - }); + } else { + xpc_retain(connection); + xpc_retain(event); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + securityd_xpc_dictionary_handler(connection, event); + xpc_release(event); + xpc_release(connection); + }); + } } }); xpc_connection_resume(connection); @@ -1889,6 +1920,7 @@ int main(int argc, char *argv[]) CKKSControlServerInitialize(); SOSControlServerInitialize(); OctagonControlServerInitialize(); + SFKeychainServerInitialize(); // 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp #if TARGET_OS_EMBEDDED diff --git a/OSX/sec/ipc/server_entitlement_helpers.c b/OSX/sec/ipc/server_entitlement_helpers.c index 68b9d1c9..93db1fda 100644 --- a/OSX/sec/ipc/server_entitlement_helpers.c +++ b/OSX/sec/ipc/server_entitlement_helpers.c @@ -40,8 +40,7 @@ CFStringRef SecTaskCopyStringForEntitlement(SecTaskRef task, CFStringRef value = (CFStringRef)SecTaskCopyValueForEntitlement(task, entitlement, NULL); if (value && CFGetTypeID(value) != CFStringGetTypeID()) { - CFRelease(value); - value = NULL; + CFReleaseNull(value); } return value; @@ -58,14 +57,12 @@ CFArrayRef SecTaskCopyArrayOfStringsForEntitlement(SecTaskRef task, for (ix = 0; ix < count; ++ix) { CFStringRef string = (CFStringRef)CFArrayGetValueAtIndex(value, ix); if (CFGetTypeID(string) != CFStringGetTypeID()) { - CFRelease(value); - value = NULL; + CFReleaseNull(value); break; } } } else { - CFRelease(value); - value = NULL; + CFReleaseNull(value); } } @@ -76,130 +73,92 @@ CFStringRef SecTaskCopyApplicationIdentifier(SecTaskRef task) { return SecTaskCopyStringForEntitlement(task, kSecEntitlementApplicationIdentifier); } + #if TARGET_OS_IOS CFArrayRef SecTaskCopySharedWebCredentialDomains(SecTaskRef task) { return SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementAssociatedDomains); } #endif -CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task) { + +CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task) +{ CFMutableArrayRef groups = NULL; - CFArrayRef keychainAccessGroups = SecTaskCopyArrayOfStringsForEntitlement(task, - kSecEntitlementKeychainAccessGroups); - CFArrayRef appleSecurityApplicationGroups = SecTaskCopyArrayOfStringsForEntitlement(task, - kSecEntitlementAppleSecurityApplicationGroups); - CFStringRef appID = SecTaskCopyApplicationIdentifier(task); - CFIndex kagLen = keychainAccessGroups ? CFArrayGetCount(keychainAccessGroups) : 0; - CFIndex asagLen = appleSecurityApplicationGroups ? CFArrayGetCount(appleSecurityApplicationGroups) : 0; - bool entitlementsValidated = true; - bool hasEntitlements = (kagLen + asagLen + (appID ? 1 : 0)) > 0; -#if TARGET_OS_OSX - entitlementsValidated = SecTaskEntitlementsValidated(task); - if ((appID || asagLen) && !entitlementsValidated) { - CFReleaseNull(appID); - asagLen = 0; + +#if TARGET_SIMULATOR + groups = (CFMutableArrayRef)CFRetainSafe(SecAccessGroupsGetCurrent()); +#else + CFArrayRef keychainAccessGroups, appleSecurityApplicationGroups; + CFStringRef appID; + + keychainAccessGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementKeychainAccessGroups); + appleSecurityApplicationGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementAppleSecurityApplicationGroups); + appID = SecTaskCopyApplicationIdentifier(task); + + groups = CFArrayCreateMutableForCFTypes(NULL); + + if (keychainAccessGroups) { + CFArrayAppendArray(groups, keychainAccessGroups, CFRangeMake(0, CFArrayGetCount(keychainAccessGroups))); } + +#if TARGET_OS_OSX + const bool entitlementsValidated = SecTaskEntitlementsValidated(task); +#else + const bool entitlementsValidated = true; #endif - CFIndex len = kagLen + asagLen + (appID ? 1 : 0); - // Always allow access to com.apple.token access group, unless entitlement validation explicitly failed. - CFIndex tokenLen = (!hasEntitlements || entitlementsValidated) ? 1 : 0; -#if TARGET_OS_IPHONE - if (len + tokenLen) -#endif - { - groups = CFArrayCreateMutable(kCFAllocatorDefault, len + tokenLen, &kCFTypeArrayCallBacks); - if (kagLen) - CFArrayAppendArray(groups, keychainAccessGroups, CFRangeMake(0, kagLen)); - if (appID) + + if (entitlementsValidated) { + // If app-id or k-a-g are present but binary is not validated, just honor k-a-g. + // Because AMFI would not allow client to run if it would have k-a-g entitlement + // and not being properly signed. + if (appID) { CFArrayAppendValue(groups, appID); - if (asagLen) - CFArrayAppendArray(groups, appleSecurityApplicationGroups, CFRangeMake(0, asagLen)); - if (tokenLen) - CFArrayAppendValue(groups, kSecAttrAccessGroupToken); -#if TARGET_IPHONE_SIMULATOR + } + if (appleSecurityApplicationGroups) { + CFArrayAppendArray(groups, appleSecurityApplicationGroups, CFRangeMake(0, CFArrayGetCount(appleSecurityApplicationGroups))); + } } else { - secwarning("No keychain access group specified while running in simulator, falling back to default set"); - groups = (CFMutableArrayRef)CFRetainSafe(SecAccessGroupsGetCurrent()); -#endif - } - - CFReleaseSafe(appID); - CFReleaseSafe(keychainAccessGroups); - CFReleaseSafe(appleSecurityApplicationGroups); - return groups; -} - -#if TARGET_OS_IPHONE -pthread_key_t taskThreadKey; -void secTaskDiagnoseEntitlements(CFArrayRef accessGroups) { - SecTaskRef taskRef = pthread_getspecific(taskThreadKey); - if (taskRef == NULL) - return; - - CFErrorRef error = NULL; - CFArrayRef entitlementNames = CFArrayCreateForCFTypes(NULL, - kSecEntitlementApplicationIdentifier, - kSecEntitlementKeychainAccessGroups, - kSecEntitlementAppleSecurityApplicationGroups, - NULL); - CFDictionaryRef rawEntitlements = SecTaskCopyValuesForEntitlements(taskRef, entitlementNames, &error); - CFReleaseNull(entitlementNames); - - // exclude some error types because they're accounted-for and not the reason we're here - if (rawEntitlements == NULL && error) { - CFErrorDomain domain = CFErrorGetDomain(error); - if (domain && CFEqual(domain, kCFErrorDomainPOSIX)) { - CFIndex c = CFErrorGetCode(error); - int err = (int) c; - - switch (err) { - case ESRCH: // no such process (bad pid or process died) - return; - default: - break; + // Try to provide some hopefully helpful diagnostics for common failure cases. + if (CFArrayGetCount(groups) == 0) { + if (appID) { + secwarning("Entitlement %@=%@ is ignored because of invalid application signature or incorrect provisioning profile", + kSecEntitlementApplicationIdentifier, appID); + } + if (appleSecurityApplicationGroups) { + secwarning("Entitlement %@=%@ is ignored because of invalid application signature or incorrect provisioning profile", + kSecEntitlementAppleSecurityApplicationGroups, appleSecurityApplicationGroups); } } } - uint32_t cs_flags = SecTaskGetCodeSignStatus(taskRef); - CFStringRef identifier = SecTaskCopySigningIdentifier(taskRef, NULL); - CFStringRef message = NULL; - - if (rawEntitlements == NULL) { // NULL indicates failure-to-fetch (SecTask entitlements not initialized) - message = CFStringCreateWithFormat(NULL, NULL, CFSTR("failed to fetch keychain client entitlements. task=%@ procid=%@ cs_flags=0x%08.8x error=%@"), - taskRef, identifier, cs_flags, error); - secerror("MISSING keychain entitlements: retrieve-entitlements error %@", error); - } else { - // non-NULL entitlement return => SecTaskCopyEntitlements succeeeded, no error - // but note that kernel EINVAL => no entitlements, no error to deal with unsigned code - message = CFStringCreateWithFormat(NULL, NULL, CFSTR("found no keychain client entitlements. task=%@ procid=%@ cs_flags=0x%08.8x"), - taskRef, identifier, cs_flags); - secerror("MISSING keychain entitlements: raw entitlement values: %@", rawEntitlements); - secerror("MISSING keychain entitlements: original ag: %@", accessGroups); - CFArrayRef newAccessGroups = SecTaskCopyAccessGroups(taskRef); - secerror("MISSING keychain entitlements: newly parsed ag: %@", newAccessGroups); - CFReleaseNull(newAccessGroups); + /* + * We would like to add implicit token access group always, but we avoid doing that in case that application + * clearly intended to use non-smartcard functionality of keychain but messed up signing or provisioning. In this case, + * we want to return -34018 (errSecMissingEntitlements) to help diagnosing the issue for the app authors and adding + * implicit token access group would instead result in errSecItemNotFound. + */ + bool entitlementsFailure = (CFArrayGetCount(groups) == 0 && appID != NULL); + if (!entitlementsFailure) { + CFArrayAppendValue(groups, kSecAttrAccessGroupToken); } - char buffer[1000] = "?"; - CFStringGetCString(message, buffer, sizeof(buffer), kCFStringEncodingUTF8); - secerror("%s", buffer); - __security_simulatecrash(message, __sec_exception_code_MissingEntitlements); - - CFReleaseNull(rawEntitlements); - CFReleaseNull(message); - CFReleaseNull(identifier); - CFReleaseNull(error); -} + + CFReleaseNull(appID); + CFReleaseNull(keychainAccessGroups); + CFReleaseNull(appleSecurityApplicationGroups); #endif -bool SecTaskGetBooleanValueForEntitlement(SecTaskRef task, - CFStringRef entitlement) { - CFTypeRef canModify = SecTaskCopyValueForEntitlement(task, entitlement, NULL); - if (!canModify) - return false; - CFTypeID canModifyType = CFGetTypeID(canModify); - bool ok = (CFBooleanGetTypeID() == canModifyType) && CFBooleanGetValue((CFBooleanRef)canModify); - CFRelease(canModify); - return ok; + return groups; } +bool +SecTaskGetBooleanValueForEntitlement(SecTaskRef task, CFStringRef entitlement) +{ + CFTypeRef value = SecTaskCopyValueForEntitlement(task, entitlement, NULL); + bool ok = false; + + if (value && CFBooleanGetTypeID() == CFGetTypeID(value)) { + ok = CFBooleanGetValue(value); + } + CFReleaseNull(value); + return ok; +} diff --git a/OSX/sec/ipc/server_entitlement_helpers.h b/OSX/sec/ipc/server_entitlement_helpers.h index 2aeb3411..e8a37b90 100644 --- a/OSX/sec/ipc/server_entitlement_helpers.h +++ b/OSX/sec/ipc/server_entitlement_helpers.h @@ -36,10 +36,6 @@ CFStringRef SecTaskCopyStringForEntitlement(SecTaskRef task, CFArrayRef SecTaskCopyArrayOfStringsForEntitlement(SecTaskRef task, CFStringRef entitlement); -#if TARGET_OS_IPHONE -void secTaskDiagnoseEntitlements(CFArrayRef accessGroups); -extern pthread_key_t taskThreadKey; -#endif #if TARGET_OS_IOS CFArrayRef SecTaskCopySharedWebCredentialDomains(SecTaskRef task); #endif diff --git a/OSX/sec/ipc/server_security_helpers.c b/OSX/sec/ipc/server_security_helpers.c index a982bbb1..88d71b90 100644 --- a/OSX/sec/ipc/server_security_helpers.c +++ b/OSX/sec/ipc/server_security_helpers.c @@ -104,10 +104,6 @@ void fill_security_client(SecurityClient * client, const uid_t uid, audit_token_ client->task = SecTaskCreateWithAuditToken(kCFAllocatorDefault, auditToken); -#if TARGET_OS_IPHONE - pthread_setspecific(taskThreadKey, client->task); -#endif - client->accessGroups = SecTaskCopyAccessGroups(client->task); #if TARGET_OS_IPHONE diff --git a/OSX/sec/ipc/server_security_helpers.h b/OSX/sec/ipc/server_security_helpers.h index 7f99e901..0ff23beb 100644 --- a/OSX/sec/ipc/server_security_helpers.h +++ b/OSX/sec/ipc/server_security_helpers.h @@ -34,5 +34,6 @@ void SecCreateSecuritydXPCServer(void); void fill_security_client(SecurityClient * client, const uid_t uid, audit_token_t auditToken); CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task); +void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); #endif /* server_security_helpers_h */ diff --git a/OSX/sec/ipc/server_xpc.m b/OSX/sec/ipc/server_xpc.m index 15f2d9e7..8a55d96e 100644 --- a/OSX/sec/ipc/server_xpc.m +++ b/OSX/sec/ipc/server_xpc.m @@ -29,7 +29,7 @@ #include #if OCTAGON -#include "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #include // If your callbacks might pass back a CK error, you should use the XPCSanitizeError() spi on all branches at this layer. // Otherwise, XPC might crash on the other side if they haven't linked CloudKit.framework. diff --git a/OSX/sec/securityd/OTATrustUtilities.h b/OSX/sec/securityd/OTATrustUtilities.h index 9494478b..71ccc3b6 100644 --- a/OSX/sec/securityd/OTATrustUtilities.h +++ b/OSX/sec/securityd/OTATrustUtilities.h @@ -128,6 +128,10 @@ uint64_t SecOTAPKIGetTrustStoreVersion(SecOTAPKIRef otapkiRef); CF_EXPORT uint64_t SecOTAPKIGetAssetVersion(SecOTAPKIRef otapkiRef); +// Accessor to retrieve the last check in time for the OTAPKI asset +CF_EXPORT +CFDateRef SecOTAPKICopyLastAssetCheckInDate(SecOTAPKIRef otapkiRef); + #if __OBJC__ // SPI to return the current sampling rate for the event name // This rate is actually n where we sample 1 out of every n diff --git a/OSX/sec/securityd/OTATrustUtilities.m b/OSX/sec/securityd/OTATrustUtilities.m index 31f0bad9..6431ac00 100644 --- a/OSX/sec/securityd/OTATrustUtilities.m +++ b/OSX/sec/securityd/OTATrustUtilities.m @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -170,10 +172,12 @@ static CFDataRef SecSystemTrustStoreCopyResourceContents(CFStringRef resourceNam static uint64_t GetAssetVersion(void); #if !TARGET_OS_BRIDGE static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version); +static BOOL UpdateOTACheckInDate(void); #endif // MARK: Constants NSString *kOTATrustContentVersionKey = @"MobileAssetContentVersion"; +NSString *kOTATrustLastCheckInKey = @"MobileAssetLastCheckIn"; NSString *kOTATrustContextFilename = @"OTAPKIContext.plist"; NSString *kOTATrustTrustedCTLogsFilename = @"TrustedCTLogs.plist"; NSString *kOTATrustAnalyticsSamplingRatesFilename = @"AnalyticsSamplingRates.plist"; @@ -183,6 +187,7 @@ NSString *kOTATrustAppleCertifcateAuthoritiesFilename = @"AppleCertificateAuthor const NSString *OTATrustMobileAssetType = @"com.apple.MobileAsset.PKITrustSupplementals"; #define kOTATrustMobileAssetNotification "com.apple.MobileAsset.PKITrustSupplementals.cached-metadata-updated" #define kOTATrustOnDiskAssetNotification "com.apple.trustd.asset-updated" +#define kOTATrustCheckInNotification "com.apple.trustd.asset-check-in" const NSUInteger OTATrustMobileAssetCompatibilityVersion = 1; #define kOTATrustDefaultUpdatePeriod 60*60*12 // 12 hours #define kOTATrustMinimumUpdatePeriod 60*5 // 5 min @@ -200,7 +205,7 @@ typedef enum { OTATrustLogLevelError, } OTATrustLogLevel; -static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, OSStatus errCode, NSString *format,...) NS_FORMAT_FUNCTION(4,5); +static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) NS_FORMAT_FUNCTION(5,6); static void LogLocally(OTATrustLogLevel level, NSString *errorString) { switch (level) { @@ -230,26 +235,26 @@ static void LogRemotely(OTATrustLogLevel level, NSError **error) { #endif // ENABLE_TRUSTD_ANALYTICS } -static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, OSStatus errCode, NSString *format,...) { +static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) { va_list args; va_start(args, format); NSString *formattedString = nil; if (format) { formattedString = [[NSString alloc] initWithFormat:format arguments:args]; } - if (error) { - NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; - if (format) { - [userInfo setObject:formattedString forKey:NSLocalizedDescriptionKey]; - } - *error = [NSError errorWithDomain:NSOSStatusErrorDomain + NSError *localError = nil; + NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; + if (format) { + [userInfo setObject:formattedString forKey:NSLocalizedDescriptionKey]; + } + localError = [NSError errorWithDomain:errDomain code:errCode userInfo:userInfo]; - } LogLocally(level, formattedString); - LogRemotely(level, error); + LogRemotely(level, &localError); + if (error) { *error = localError; } va_end(args); } @@ -330,11 +335,12 @@ static NSURL *GetAssetFileURL(NSString *filename) { } static void DeleteFileWithName(NSString *filename) { - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSError *error = nil; - [fileManager removeItemAtURL:GetAssetFileURL(filename) error:&error]; - if (error) { - secerror("OTATrust: failed to remove %@: %@", filename, error); + NSURL *fileURL = GetAssetFileURL(filename); + if (remove([fileURL fileSystemRepresentation]) == -1) { + int error = errno; + if (error != ENOENT) { + secnotice("OTATrust", "failed to remove %@: %s", fileURL, strerror(error)); + } } } @@ -347,11 +353,22 @@ static void DeleteAssetFromDisk(void) { } } -static BOOL WriteAssetVersionToDisk(NSNumber *asset_version) { +static BOOL UpdateOTAContextOnDisk(NSString *key, id value) { if (SecOTAPKIIsSystemTrustd()) { + /* Get current context, if applicable, and update/add key/value */ + NSURL *otaContextFile = GetAssetFileURL(kOTATrustContextFilename); + NSDictionary *currentContext = [NSDictionary dictionaryWithContentsOfURL:otaContextFile]; + NSMutableDictionary *newContext = nil; + if (currentContext) { + newContext = [currentContext mutableCopy]; + } else { + newContext = [NSMutableDictionary dictionary]; + } + newContext[key] = value; + + /* Write dictionary to disk */ NSError *error = nil; - NSDictionary *version_dict = @{ kOTATrustContentVersionKey : asset_version }; - [version_dict writeToURL:GetAssetFileURL(kOTATrustContextFilename) error:&error]; + [newContext writeToURL:otaContextFile error:&error]; if (error) { secerror("OTATrust: unable to write asset version to disk: %@", error); LogRemotely(OTATrustLogLevelError, &error); @@ -362,18 +379,20 @@ static BOOL WriteAssetVersionToDisk(NSNumber *asset_version) { return NO; } - static BOOL CopyFileToDisk(NSString *filename, NSURL *localURL) { if (SecOTAPKIIsSystemTrustd()) { - NSFileManager * fileManager = [NSFileManager defaultManager]; - NSError *error = nil; - [fileManager copyItemAtURL:localURL toURL:GetAssetFileURL(filename) error:&error]; - if (error) { - secerror("OTATrust: unable to write CT logs to disk: %@", error); - LogRemotely(OTATrustLogLevelError, &error); + NSURL *toFileURL = GetAssetFileURL(filename); + secdebug("OTATrust", "will copy asset file data from \"%@\"", localURL); + copyfile_state_t state = copyfile_state_alloc(); + int retval = copyfile([localURL fileSystemRepresentation], [toFileURL fileSystemRepresentation], + state, COPYFILE_DATA); + copyfile_state_free(state); + if (retval < 0) { + secerror("OTATrust: copyfile error for asset %d", retval); return NO; + } else { + return YES; } - return YES; } return NO; } @@ -394,7 +413,7 @@ static NSNumber *UpdateAndPurgeAsset(MAAsset *asset, NSNumber *asset_version, NS }]; return asset_version; } else { - MakeOTATrustError(error, OTATrustLogLevelError, errSecCallbackFailed, + MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecCallbackFailed, @"Failed to install new asset version %@ from %@", asset_version, [asset getLocalFileUrl]); return nil; } @@ -402,7 +421,7 @@ static NSNumber *UpdateAndPurgeAsset(MAAsset *asset, NSNumber *asset_version, NS static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) { if (!CanCheckMobileAsset()) { - MakeOTATrustError(error, OTATrustLogLevelNotice, errSecServiceNotAvailable, + MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecServiceNotAvailable, @"MobileAsset disabled, skipping check."); return NO; } @@ -412,83 +431,98 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) __block NSError *ma_error = nil; secnotice("OTATrust", "begin MobileAsset query for catalog"); [MAAsset startCatalogDownload:(NSString *)OTATrustMobileAssetType then:^(MADownLoadResult result) { - if (result != MADownloadSucceesful) { - MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, - @"failed to download catalog: %ld", (long)result); - return; - } - MAAssetQuery *query = [[MAAssetQuery alloc] initWithType:(NSString *)OTATrustMobileAssetType]; - [query augmentResultsWithState:true]; - - secnotice("OTATrust", "begin MobileAsset metadata sync request"); - MAQueryResult queryResult = [query queryMetaDataSync]; - if (queryResult != MAQuerySucceesful) { - MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, - @"failed to query MobileAsset metadata: %ld", (long)queryResult); - return; - } - - if (!query.results) { - MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, - @"no results in MobileAsset query"); - return; - } - - bool began_async_job = false; - for (MAAsset *asset in query.results) { - /* Check Compatibility Version against this software version */ - NSNumber *compatibilityVersion = [asset assetProperty:@"_CompatibilityVersion"]; - if (!isNSNumber(compatibilityVersion) || - [compatibilityVersion unsignedIntegerValue] != OTATrustMobileAssetCompatibilityVersion) { - MakeOTATrustError(&ma_error, OTATrustLogLevelNotice, errSecIncompatibleVersion, - @"skipping asset because Compatibility Version doesn't match %@", compatibilityVersion); - continue; + @autoreleasepool { + os_transaction_t transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.download"); + if (result != MADownloadSucceesful) { + MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", result, + @"failed to download catalog: %ld", (long)result); + return; } - /* Check Content Version agains the current content version */ - NSNumber *asset_version = [asset assetProperty:@"_ContentVersion"]; - if (!ShouldUpdateWithAsset(asset_version)) { - MakeOTATrustError(&ma_error, OTATrustLogLevelNotice, errSecDuplicateItem, - @"skipping asset because we already have _ContentVersion %@ (or newer)", asset_version); - continue; + MAAssetQuery *query = [[MAAssetQuery alloc] initWithType:(NSString *)OTATrustMobileAssetType]; + [query augmentResultsWithState:true]; + + secnotice("OTATrust", "begin MobileAsset metadata sync request"); + MAQueryResult queryResult = [query queryMetaDataSync]; + if (queryResult != MAQuerySucceesful) { + MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MAQueryResult", queryResult, + @"failed to query MobileAsset metadata: %ld", (long)queryResult); + return; } - switch (asset.state) { - default: - MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, - @"unknown asset state %ld", (long)asset.state); + if (!query.results) { + MakeOTATrustError(&ma_error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, + @"no results in MobileAsset query"); + return; + } + + bool began_async_job = false; + for (MAAsset *asset in query.results) { + /* Check Compatibility Version against this software version */ + NSNumber *compatibilityVersion = [asset assetProperty:@"_CompatibilityVersion"]; + if (!isNSNumber(compatibilityVersion) || + [compatibilityVersion unsignedIntegerValue] != OTATrustMobileAssetCompatibilityVersion) { + MakeOTATrustError(&ma_error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecIncompatibleVersion, + @"skipping asset because Compatibility Version doesn't match %@", compatibilityVersion); continue; - case MAInstalled: - /* The asset is already in the cache, get it from disk. */ - secdebug("OTATrust", "OTATrust asset already installed"); - updated_version = UpdateAndPurgeAsset(asset, asset_version, &ma_error); - break; - case MAUnknown: - MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, - @"asset is unknown"); + } + + /* We got an Asset that this device could use; write the last check-in time as now. */ + (void)UpdateOTACheckInDate(); + + /* Check Content Version against the current content version */ + NSNumber *asset_version = [asset assetProperty:@"_ContentVersion"]; + if (!ShouldUpdateWithAsset(asset_version)) { + MakeOTATrustError(&ma_error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem, + @"skipping asset because we already have _ContentVersion %@ (or newer)", asset_version); continue; - case MADownloading: - secnotice("OTATrust", "asset is downloading"); - /* fall through */ - case MANotPresent: - secnotice("OTATrust", "begin download of OTATrust asset"); - began_async_job = true; - [asset startDownload:^(MADownLoadResult downloadResult) { - if (downloadResult != MADownloadSucceesful) { - MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, - @"failed to download asset: %ld", (long)downloadResult); - return; - } + } + + switch (asset.state) { + default: + MakeOTATrustError(&ma_error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, + @"unknown asset state %ld", (long)asset.state); + continue; + case MAInstalled: + /* The asset is already in the cache, get it from disk. */ + secdebug("OTATrust", "OTATrust asset already installed"); updated_version = UpdateAndPurgeAsset(asset, asset_version, &ma_error); - if (wait) { - dispatch_semaphore_signal(done); - } - }]; - break; - } /* switch (asset.state) */ - } /* for (MAAsset.. */ - if (wait && !began_async_job) { - dispatch_semaphore_signal(done); - } + break; + case MAUnknown: + MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MAAssetState", asset.state, + @"asset is unknown"); + continue; + case MADownloading: + secnotice("OTATrust", "asset is downloading"); + /* fall through */ + case MANotPresent: + secnotice("OTATrust", "begin download of OTATrust asset"); + began_async_job = true; + [asset startDownload:^(MADownLoadResult downloadResult) { + @autoreleasepool { + os_transaction_t inner_transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.downloadAsset"); + if (downloadResult != MADownloadSucceesful) { + MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", downloadResult, + @"failed to download asset: %ld", (long)downloadResult); + return; + } + updated_version = UpdateAndPurgeAsset(asset, asset_version, &ma_error); + if (wait) { + dispatch_semaphore_signal(done); + } + (void)inner_transaction; // dead store + inner_transaction = nil; + } + }]; + break; + } /* switch (asset.state) */ + } /* for (MAAsset.. */ + if (wait && !began_async_job) { + dispatch_semaphore_signal(done); + } + /* Done with the transaction */ + (void)transaction; // dead store + transaction = nil; + } /* autoreleasepool */ }]; /* [MAAsset startCatalogDownload: ] */ /* If the caller is waiting for a response, wait up to one minute for the update to complete. @@ -500,14 +534,14 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) BOOL result = NO; if (wait) { if (dispatch_semaphore_wait(done, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { - MakeOTATrustError(error, OTATrustLogLevelError, errSecNetworkFailure, + MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecNetworkFailure, @"Failed to get asset metadata within 1 minute."); } else { result = (updated_version != nil); if (error && ma_error) { *error = ma_error; } else if (!result) { - MakeOTATrustError(error, OTATrustLogLevelError, errSecInternalComponent, + MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternalComponent, @"Unknown error occurred."); } } @@ -516,7 +550,7 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) } #else /* !TARGET_OS_IPHONE */ /* MobileAssetV2 fails on macOS, so use V1 */ -static NSNumber *UpdateAndPurgeAsset(ASAsset *asset, NSNumber *asset_version, NSError ** error) { +static NSNumber *UpdateAndPurgeAsset(ASAsset *asset, NSNumber *asset_version, NSError **error) { if (SecPinningDbUpdateFromURL((__bridge CFURLRef)[asset localURL]) && UpdateFromAsset([asset localURL], asset_version)) { secnotice("OTATrust", "finished update to version %@ from installed asset. purging asset.", asset_version); @@ -524,13 +558,13 @@ static NSNumber *UpdateAndPurgeAsset(ASAsset *asset, NSNumber *asset_version, NS [[TrustdHealthAnalytics logger] logSuccessForEventNamed:TrustdHealthAnalyticsEventOTAPKIEvent]; #endif // ENABLE_TRUSTD_ANALYTICS [asset purge:^(NSError *ma_error) { - if (error) { + if (ma_error) { secerror("OTATrust: purge failed %@", ma_error); } }]; return asset_version; } else { - MakeOTATrustError(error, OTATrustLogLevelError, errSecCallbackFailed, + MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecCallbackFailed, @"Failed to install new asset version %@ from %@", asset_version, [asset localURL]); return nil; } @@ -538,18 +572,20 @@ static NSNumber *UpdateAndPurgeAsset(ASAsset *asset, NSNumber *asset_version, NS static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) { if (!CanCheckMobileAsset()) { - MakeOTATrustError(error, OTATrustLogLevelNotice, errSecServiceNotAvailable, + MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecServiceNotAvailable, @"MobileAsset disabled, skipping check."); return NO; } + NSError *localError = nil; // -[ASAssetQuery runQueryAndReturnError:] leaks if you pass null ASAssetQuery *query = [[ASAssetQuery alloc] initWithAssetType:(NSString *)OTATrustMobileAssetType]; [query setQueriesLocalAssetInformationOnly:isLocalOnly]; // Omitting this leads to a notifcation loop. - NSArray*query_results = [query runQueryAndReturnError:error]; + NSArray*query_results = [query runQueryAndReturnError:&localError]; if (!query_results) { - if (error) { - secerror("OTATrust: asset query failed: %@", *error); - LogRemotely(OTATrustLogLevelError, error); + if (localError) { + secerror("OTATrust: asset query failed: %@", localError); + LogRemotely(OTATrustLogLevelError, &localError); + if (error) { *error = localError; } } return NO; } @@ -561,17 +597,22 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) for (ASAsset *asset in query_results) { NSDictionary *attributes = [asset attributes]; + /* Check Compatibility Version against this software version */ NSNumber *compatibilityVersion = [attributes objectForKey:ASAttributeCompatibilityVersion]; if (!isNSNumber(compatibilityVersion) || [compatibilityVersion unsignedIntegerValue] != OTATrustMobileAssetCompatibilityVersion) { - MakeOTATrustError(error, OTATrustLogLevelNotice, errSecIncompatibleVersion, + MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecIncompatibleVersion, @"skipping asset because Compatibility Version doesn't match %@", compatibilityVersion); continue; } + /* We got an Asset that this device could use; write the last check-in time as now. */ + (void)UpdateOTACheckInDate(); + + /* Check Content Version against the current content version */ NSNumber *contentVersion = [attributes objectForKey:ASAttributeContentVersion]; if (!ShouldUpdateWithAsset(contentVersion)) { - MakeOTATrustError(error, OTATrustLogLevelNotice, errSecDuplicateItem, + MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem, @"skipping asset because we already have _ContentVersion %@ (or newer)", contentVersion); continue; } @@ -579,8 +620,9 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) ASProgressHandler OTATrustHandler = ^(NSDictionary *state, NSError *progressError){ NSString *operationState = nil; if (progressError) { - MakeOTATrustError(&handler_error, OTATrustLogLevelError, errSecInternal, - @"OTATrust: asset download error: %@", progressError); + secerror("progress handler failed: %@", progressError); + LogRemotely(OTATrustLogLevelError, &progressError); + handler_error = [progressError copy]; if (wait) { dispatch_semaphore_signal(done); } @@ -588,7 +630,7 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) } if (!state) { - MakeOTATrustError(&handler_error, OTATrustLogLevelError, errSecInternal, + MakeOTATrustError(&handler_error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, @"OTATrust: no asset state in progress handler"); if (wait) { dispatch_semaphore_signal(done); @@ -625,10 +667,11 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) secdebug("OTATrust", "OTATrust asset download paused"); asset.progressHandler = OTATrustHandler; asset.userInitiatedDownload = YES; - if (![asset resumeDownloadAndReturnError:error]) { - if (error) { - secerror("OTATrust: failed to resume download of asset: %@", *error); - LogRemotely(OTATrustLogLevelError, error); + if (![asset resumeDownloadAndReturnError:&localError]) { + if (localError) { + secerror("OTATrust: failed to resume download of asset: %@", localError); + LogRemotely(OTATrustLogLevelError, &localError); + if (error) { *error = localError; } } } else { began_async_job = true; @@ -641,7 +684,7 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) began_async_job = true; break; default: - MakeOTATrustError(error, OTATrustLogLevelError, errSecInternal, + MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, @"unhandled asset state %ld", (long)asset.state); continue; } @@ -654,7 +697,7 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) BOOL result = (updated_version != nil); if (wait && began_async_job) { if (dispatch_semaphore_wait(done, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { - MakeOTATrustError(error, OTATrustLogLevelError, errSecNetworkFailure, + MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecNetworkFailure, @"Failed to get asset metadata within 1 minute."); } else { /* finished an async job, update the result */ @@ -667,7 +710,7 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) /* If we failed and don't know why, report an unknown error */ if (!result && error && (*error == NULL)) { - MakeOTATrustError(error, OTATrustLogLevelError, errSecInternalComponent, + MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternalComponent, @"Unknown error occurred."); } return result; @@ -699,6 +742,11 @@ static void InitializeOTATrustAsset(dispatch_queue_t queue) { secnotice("OTATrust", "Got notification about a new PKITrustSupplementals asset from system trustd."); UpdateFromAsset(GetAssetFileURL(nil), [NSNumber numberWithUnsignedLongLong:GetAssetVersion()]); }); + int out_token2 = 0; + notify_register_dispatch(kOTATrustCheckInNotification, &out_token2, queue, ^(int __unused token) { + secinfo("OTATrust", "Got notification about successful PKITrustSupplementals asset check-in"); + (void)UpdateOTACheckInDate(); + }); } } @@ -1231,6 +1279,7 @@ struct _OpaqueSecOTAPKI { CFIndex _validSnapshotVersion; CFIndex _validSnapshotFormat; uint64_t _assetVersion; + CFDateRef _lastAssetCheckIn; CFDictionaryRef _eventSamplingRates; CFArrayRef _appleCAs; }; @@ -1258,6 +1307,7 @@ static void SecOTAPKIDestroy(CFTypeRef cf) { CFReleaseNull(otapkiref->_pinningList); CFReleaseNull(otapkiref->_eventSamplingRates); CFReleaseNull(otapkiref->_appleCAs); + CFReleaseNull(otapkiref->_lastAssetCheckIn); if (otapkiref->_anchorTable) { free((void *)otapkiref->_anchorTable); @@ -1299,6 +1349,17 @@ static uint64_t GetAssetVersion(void) { } } +static CF_RETURNS_RETAINED CFDateRef InitializeLastAssetCheckIn(void) { +#if !TARGET_OS_BRIDGE + NSDictionary *OTAPKIContext = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustContextFilename)]; + if (isNSDictionary(OTAPKIContext)) { + NSDate *checkIn = OTAPKIContext[kOTATrustLastCheckInKey]; + return CFRetainSafe((__bridge CFDateRef)checkIn); + } +#endif + return NULL; +} + static SecOTAPKIRef SecOTACreate() { SecOTAPKIRef otapkiref = NULL; @@ -1349,6 +1410,7 @@ static SecOTAPKIRef SecOTACreate() { // Get the asset version (after possible reset due to missing asset date) otapkiref->_assetVersion = GetAssetVersion(); + otapkiref->_lastAssetCheckIn = InitializeLastAssetCheckIn(); // Get the valid update snapshot version and format CFIndex update_format = 0; @@ -1425,6 +1487,23 @@ SecOTAPKIRef SecOTAPKICopyCurrentOTAPKIRef() { } #if !TARGET_OS_BRIDGE +static BOOL UpdateOTACheckInDate(void) { + __block NSDate *checkIn = [NSDate date]; + dispatch_sync(kOTAQueue, ^{ + CFRetainAssign(kCurrentOTAPKIRef->_lastAssetCheckIn, (__bridge CFDateRef)checkIn); + }); + + if (SecOTAPKIIsSystemTrustd()) { + /* Let the other trustds know we successfully checked in */ + notify_post(kOTATrustCheckInNotification); + + /* Update the on-disk check-in date, so when we re-launch we remember */ + return UpdateOTAContextOnDisk(kOTATrustLastCheckInKey, checkIn); + } else { + return NO; + } +} + static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version) { if (!localURL || !asset_version) { secerror("OTATrust: missing url and version for downloaded asset"); @@ -1473,7 +1552,7 @@ static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version) { if (CopyFileToDisk(kOTATrustTrustedCTLogsFilename, TrustedCTLogsFileLoc) && CopyFileToDisk(kOTATrustAnalyticsSamplingRatesFilename, AnalyticsSamplingRatesFileLoc) && CopyFileToDisk(kOTATrustAppleCertifcateAuthoritiesFilename, AppleCAsFileLoc) && - WriteAssetVersionToDisk(asset_version)) { + UpdateOTAContextOnDisk(kOTATrustContentVersionKey, asset_version)) { /* If we successfully updated the "asset" on disk, signal the other trustds to pick up the changes */ notify_post(kOTATrustOnDiskAssetNotification); } @@ -1695,6 +1774,13 @@ uint64_t SecOTAPKIGetAssetVersion(SecOTAPKIRef otapkiRef) { return otapkiRef->_assetVersion; } +CFDateRef SecOTAPKICopyLastAssetCheckInDate(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + return CFRetainSafe(otapkiRef->_lastAssetCheckIn); +} + NSNumber *SecOTAPKIGetSamplingRateForEvent(SecOTAPKIRef otapkiRef, NSString *eventName) { if (NULL == otapkiRef) { return nil; diff --git a/OSX/sec/securityd/Regressions/SOSAccountTesting.h b/OSX/sec/securityd/Regressions/SOSAccountTesting.h index 47805102..b5029c15 100644 --- a/OSX/sec/securityd/Regressions/SOSAccountTesting.h +++ b/OSX/sec/securityd/Regressions/SOSAccountTesting.h @@ -116,15 +116,6 @@ static inline SOSViewResultCode SOSAccountUpdateView_wTxn(SOSAccount* acct, CFSt return result; } -static inline bool SOSAccountSetMyDSID_wTxn(SOSAccount* acct, CFStringRef dsid, CFErrorRef* error) -{ - __block bool result = false; - [acct performTransaction:^(SOSAccountTransaction * _Nonnull txn) { - result = SOSAccountSetMyDSID(txn, dsid, error); - }]; - return result; -} - // // Account comparison // @@ -137,12 +128,10 @@ static void SOSAccountResetToTest(SOSAccount* a, CFStringRef accountName) { SOSUnregisterTransportKeyParameter(a.key_transport); SOSUnregisterTransportCircle((SOSCircleStorageTransport*)a.circle_transport); SOSUnregisterTransportMessage((SOSMessage*)a.kvs_message_transport); - SOSUnregisterTransportMessage((SOSMessage*)a.ids_message_transport); if(key_transports) CFArrayRemoveAllValue(key_transports, (__bridge CFTypeRef)(a.key_transport)); if(message_transports){ - CFArrayRemoveAllValue(message_transports, (__bridge CFTypeRef)a.ids_message_transport); CFArrayRemoveAllValue(message_transports, (__bridge CFTypeRef)a.kvs_message_transport); } if(circle_transports) @@ -150,7 +139,6 @@ static void SOSAccountResetToTest(SOSAccount* a, CFStringRef accountName) { a.circle_transport = nil; a.key_transport = nil; - a.ids_message_transport = nil; a.kvs_message_transport = nil; SOSAccountEnsureFactoryCirclesTest(a, accountName); @@ -440,15 +428,6 @@ static bool FillAllChanges(CFMutableDictionaryRef changes) { } SOSTransportMessageTestClearChanges(tpt); } - else if([(__bridge SOSMessage*)value SOSTransportMessageGetTransportType] == kIDSTest){ - SOSMessageIDSTest* ids = (__bridge SOSMessageIDSTest*) value; - CFDictionaryRemoveValue(SOSTransportMessageIDSTestGetChanges(ids), kCFNull); - if (AddNewChanges(changes, SOSTransportMessageIDSTestGetChanges(ids), SOSTransportMessageIDSTestGetAccount(ids))) { - changed |= true; - CFSetAddValue(changedAccounts, (__bridge CFTypeRef)(SOSTransportMessageIDSTestGetAccount(ids))); - } - SOSTransportMessageIDSTestClearChanges(ids); - } }); secnotice("process-changes", "Accounts with change (%@): %@", changed ? CFSTR("YES") : CFSTR("NO"), changedAccounts); @@ -483,14 +462,6 @@ static void FillChanges(CFMutableDictionaryRef changes, SOSAccount* forAccount) SOSTransportMessageTestClearChanges(tpt); } } - else{ - SOSMessageIDSTest* tpt = (__bridge SOSMessageIDSTest*) value; - if(CFEqualSafe((__bridge CFTypeRef)(forAccount), (__bridge CFTypeRef)(SOSTransportMessageIDSTestGetAccount(tpt)))){ - CFDictionaryRemoveValue(SOSTransportMessageIDSTestGetChanges(tpt), kCFNull); - AddNewChanges(changes, SOSTransportMessageIDSTestGetChanges(tpt), SOSTransportMessageIDSTestGetAccount(tpt)); - SOSTransportMessageIDSTestClearChanges(tpt); - } - } }); } @@ -674,11 +645,6 @@ static inline SOSAccount* CreateAccountForLocalChangesWithStartingAttributes(CFS CFMutableDictionaryRef testV2dict = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); CFDictionaryAddValue(testV2dict, sSerialNumberKey, serial); - CFDictionaryAddValue(testV2dict, sPreferIDS, preferIDS); - CFDictionaryAddValue(testV2dict, sPreferIDSFragmentation, preferIDSFragmentation); - CFDictionaryAddValue(testV2dict, sPreferIDSACKModel, preferIDSACKModel); - CFDictionaryAddValue(testV2dict, sTransportType, transportType); - CFDictionaryAddValue(testV2dict, sDeviceID, deviceID); SOSAccount* result = SOSAccountCreateTest(kCFAllocatorDefault, name, gestalt, factory); [result.trust updateV2Dictionary:result v2:testV2dict]; @@ -982,7 +948,7 @@ static inline bool SOSTestJoinThroughPiggyBack(CFDataRef cfpassword, CFStringRef is(ProcessChangesUntilNoChange(changes, approver, joiner, NULL), 2, "updates"); - ok((retval = [joiner.trust isInCircle:NULL]), "Joiner is in"); + ok((retval = [joiner isInCircle:NULL]), "Joiner is in"); accounts_agree_internal("Successful join shows same circle view", joiner, approver, false); is(countPeers(joiner), expectedCount, "There should be %d valid peers", expectedCount); diff --git a/OSX/sec/securityd/Regressions/SOSTransportTestTransports.h b/OSX/sec/securityd/Regressions/SOSTransportTestTransports.h index f05c42ab..71a715d2 100644 --- a/OSX/sec/securityd/Regressions/SOSTransportTestTransports.h +++ b/OSX/sec/securityd/Regressions/SOSTransportTestTransports.h @@ -3,7 +3,6 @@ #import "Security/SecureObjectSync/SOSTransportCircleKVS.h" #import "Security/SecureObjectSync/SOSTransportMessageKVS.h" -#import "Security/SecureObjectSync/SOSTransportMessageIDS.h" extern CFMutableArrayRef key_transports; extern CFMutableArrayRef circle_transports; @@ -11,24 +10,6 @@ extern CFMutableArrayRef message_transports; void SOSAccountUpdateTestTransports(SOSAccount* account, CFDictionaryRef gestalt); -@interface SOSMessageIDSTest : SOSMessageIDS - -@property (nonatomic) CFMutableDictionaryRef changes; -@property (nonatomic) CFStringRef accountName; - --(SOSMessageIDSTest*) initWithAccount:(SOSAccount*)acct andAccountName:(CFStringRef) aN andCircleName:(CFStringRef) cN err:(CFErrorRef *)error; --(CFIndex) SOSTransportMessageGetTransportType; --(CFStringRef) SOSTransportMessageGetCircleName; --(CFTypeRef) SOSTransportMessageGetEngine; --(SOSAccount*) SOSTransportMessageGetAccount; -void SOSTransportMessageIDSTestSetName(SOSMessageIDSTest* transport, CFStringRef acctName); --(bool) SOSTransportMessageSendMessages:(SOSMessageIDSTest*) transport pm:(CFDictionaryRef) peer_messages err:(CFErrorRef *)error; --(bool) SOSTransportMessageIDSGetIDSDeviceID:(SOSAccount*)acct; --(CFDictionaryRef)CF_RETURNS_RETAINED SOSTransportMessageHandlePeerMessageReturnsHandledCopy:(SOSMessageIDSTest*) transport peerMessages:(CFMutableDictionaryRef)message err:(CFErrorRef *)error; --(HandleIDSMessageReason) SOSTransportMessageIDSHandleMessage:(SOSAccount*)acct m:(CFDictionaryRef) message err:(CFErrorRef *)error; - -@end - @interface CKKeyParameterTest : CKKeyParameter @property (nonatomic) CFMutableDictionaryRef changes; @@ -73,7 +54,6 @@ bool SOSAccountInflateTestTransportsForCircle(SOSAccount* account, CFStringRef c -(CFMutableDictionaryRef) SOSTransportCircleTestGetChanges; @end -void SOSTransportMessageIDSTestSetName(SOSMessageIDSTest* transport, CFStringRef n); void SOSTransportMessageTestClearChanges(SOSMessageKVSTest* transport); void SOSTransportMessageKVSTestSetName(SOSMessageKVSTest* transport, CFStringRef n); @@ -86,9 +66,4 @@ void SOSTransportKeyParameterTestSetName(CKKeyParameterTest* transport, CFString void SOSTransportKeyParameterTestClearChanges(CKKeyParameterTest* transport); SOSAccount* SOSTransportKeyParameterTestGetAccount(CKKeyParameterTest* transport); SOSAccount* SOSTransportMessageKVSTestGetAccount(SOSMessageKVSTest* transport); -void SOSTransportMessageIDSTestClearChanges(SOSMessageIDSTest* transport); - -CFMutableDictionaryRef SOSTransportMessageIDSTestGetChanges(SOSMessageIDSTest* transport); -SOSAccount* SOSTransportMessageIDSTestGetAccount(SOSMessageIDSTest* transport); -CFStringRef SOSTransportMessageIDSTestGetName(SOSMessageIDSTest* transport); #endif diff --git a/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m b/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m index bd9449b3..391e75d8 100644 --- a/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m +++ b/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m @@ -6,7 +6,6 @@ #include #import #import -#import #import #include #include @@ -72,7 +71,6 @@ CFMutableArrayRef message_transports = NULL; CFArrayRemoveAllValue(key_transports, (__bridge CFTypeRef)(acct.key_transport)); } if(message_transports){ - CFArrayRemoveAllValue(message_transports, (__bridge CFTypeRef)acct.ids_message_transport); CFArrayRemoveAllValue(message_transports, (__bridge CFTypeRef)acct.kvs_message_transport); } if(circle_transports) @@ -496,31 +494,6 @@ static bool sendToPeer(SOSMessageKVSTest* transport, CFStringRef circleName, CFS return result; } --(CFDictionaryRef)CF_RETURNS_RETAINED SOSTransportMessageHandlePeerMessageReturnsHandledCopy:(SOSMessageIDSTest*) transport peerMessages:(CFMutableDictionaryRef) circle_peer_messages_table err:(CFErrorRef *)error{ - CFMutableDictionaryRef handled = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - CFDictionaryRef peerToMessage = CFDictionaryGetValue(circle_peer_messages_table, (__bridge CFStringRef)transport.circleName); - CFMutableArrayRef handled_peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); - CFDictionaryAddValue(handled, (__bridge CFStringRef)transport.circleName, handled_peers); - - if(peerToMessage){ - CFDictionaryForEach(peerToMessage, ^(const void *key, const void *value) { - CFStringRef peer_id = (CFStringRef) key; - CFDataRef peer_message = (CFDataRef) value; - CFErrorRef localError = NULL; - - if ([transport SOSTransportMessageHandlePeerMessage:transport id:peer_id cm:peer_message err:&localError]){ - CFArrayAppendValue(handled_peers, key); - } else { - secdebug("transport", "%@ KVSTransport handle message failed: %@", peer_id, localError); - } - CFReleaseNull(localError); - }); - } - CFReleaseNull(handled_peers); - - return handled; -} - -(bool) SOSTransportMessageFlushChanges:(SOSMessageKVSTest*) transport err:(CFErrorRef *)error { return true; @@ -531,325 +504,6 @@ SOSAccount* SOSTransportMessageKVSTestGetAccount(SOSMessageKVSTest* transport) { } @end -/// -//MARK IDS Message Test Transport -/// - -@implementation SOSMessageIDSTest --(SOSMessageIDSTest*) initWithAccount:(SOSAccount*)acct andAccountName:(CFStringRef) aN andCircleName:(CFStringRef) cN err:(CFErrorRef *)error -{ - self = [super init]; - if(self){ - self.engine = SOSDataSourceFactoryGetEngineForDataSourceName(acct.factory, cN, NULL); - self.useFragmentation = kCFBooleanTrue; - self.account = acct; - self.changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - self.circleName = (__bridge NSString*)cN; - self.accountName = CFRetainSafe(aN); - - if(!message_transports) - message_transports = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL); - CFArrayAppendValue(message_transports, (__bridge CFTypeRef)self); - SOSRegisterTransportMessage((SOSMessageIDSTest*)self); - } - - return self; -} - --(bool) SOSTransportMessageIDSGetIDSDeviceID:(SOSAccount*)acct{ - return true; -} - --(CFIndex) SOSTransportMessageGetTransportType -{ - return kIDSTest; -} --(CFStringRef) SOSTransportMessageGetCircleName -{ - return (__bridge CFStringRef)circleName; -} --(CFTypeRef) SOSTransportMessageGetEngine -{ - return engine; -} --(SOSAccount*) SOSTransportMessageGetAccount -{ - return self.account; -} - -void SOSTransportMessageIDSTestSetName(SOSMessageIDSTest* transport, CFStringRef acctName){ - transport.accountName = acctName; -} - - -static HandleIDSMessageReason checkMessageValidity(SOSAccount* account, CFStringRef fromDeviceID, CFStringRef fromPeerID, CFStringRef *peerID, SOSPeerInfoRef *theirPeerInfo){ - SOSAccountTrustClassic *trust = account.trust; - __block HandleIDSMessageReason reason = kHandleIDSMessageDontHandle; - - SOSCircleForEachPeer(trust.trustedCircle, ^(SOSPeerInfoRef peer) { - CFStringRef deviceID = SOSPeerInfoCopyDeviceID(peer); - CFStringRef pID = SOSPeerInfoGetPeerID(peer); - - if( deviceID && pID && fromPeerID && fromDeviceID && CFStringGetLength(fromPeerID) != 0 ){ - if(CFStringCompare(pID, fromPeerID, 0) == 0){ - if(CFStringGetLength(deviceID) == 0){ - secnotice("ids transport", "device ID was empty in the peer list, holding on to message"); - CFReleaseNull(deviceID); - reason = kHandleIDSMessageNotReady; - return; - } - else if(CFStringCompare(fromDeviceID, deviceID, 0) != 0){ //IDSids do not match, ghost - reason = kHandleIDSmessageDeviceIDMismatch; - CFReleaseNull(deviceID); - return; - } - else if(CFStringCompare(deviceID, fromDeviceID, 0) == 0){ - *peerID = pID; - *theirPeerInfo = peer; - CFReleaseNull(deviceID); - reason = kHandleIDSMessageSuccess; - return; - } - } - } - CFReleaseNull(deviceID); - }); - - return reason; -} -const char *kMessageKeyIDSDataMessage = "idsDataMessage"; -const char *kMessageKeyDeviceID = "deviceID"; -const char *kMessageKeyPeerID = "peerID"; -const char *kMessageKeySendersPeerID = "sendersPeerID"; - --(HandleIDSMessageReason) SOSTransportMessageIDSHandleMessage:(SOSAccount*)acct m:(CFDictionaryRef) message err:(CFErrorRef *)error -{ - secnotice("IDS Transport", "SOSTransportMessageIDSHandleMessage!"); - - CFStringRef dataKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyIDSDataMessage, kCFStringEncodingASCII); - CFStringRef deviceIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyDeviceID, kCFStringEncodingASCII); - CFStringRef sendersPeerIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeySendersPeerID, kCFStringEncodingASCII); - CFStringRef ourPeerIdKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyPeerID, kCFStringEncodingASCII); - - HandleIDSMessageReason result = kHandleIDSMessageSuccess; - - CFDataRef messageData = asData(CFDictionaryGetValue(message, dataKey), NULL); - __block CFStringRef fromDeviceID = asString(CFDictionaryGetValue(message, deviceIDKey), NULL); - __block CFStringRef fromPeerID = (CFStringRef)CFDictionaryGetValue(message, sendersPeerIDKey); - CFStringRef ourPeerID = asString(CFDictionaryGetValue(message, ourPeerIdKey), NULL); - - CFStringRef peerID = NULL; - SOSPeerInfoRef theirPeer = NULL; - - require_action_quiet(fromDeviceID, exit, result = kHandleIDSMessageDontHandle); - require_action_quiet(fromPeerID, exit, result = kHandleIDSMessageDontHandle); - require_action_quiet(messageData && CFDataGetLength(messageData) != 0, exit, result = kHandleIDSMessageDontHandle); - require_action_quiet(SOSAccountHasFullPeerInfo(account, error), exit, result = kHandleIDSMessageNotReady); - require_action_quiet(ourPeerID && [account.peerID isEqual: (__bridge NSString*) ourPeerID], exit, result = kHandleIDSMessageDontHandle; secnotice("IDS Transport","ignoring message for: %@", ourPeerID)); - - require_quiet((result = checkMessageValidity( account, fromDeviceID, fromPeerID, &peerID, &theirPeer)) == kHandleIDSMessageSuccess, exit); - - if ([account.ids_message_transport SOSTransportMessageHandlePeerMessage:account.ids_message_transport id:peerID cm:messageData err:error]) { - CFMutableDictionaryRef peersToSyncWith = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - CFMutableSetRef peerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(peerIDs, peerID); - SOSAccountTrustClassic* trust = account.trust; - //sync using fragmentation? - if(SOSPeerInfoShouldUseIDSMessageFragmentation(trust.peerInfo, theirPeer)){ - //set useFragmentation bit - [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref: kCFBooleanTrue]; - } - else{ - [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref: kCFBooleanFalse]; - } - - if(![account.ids_message_transport SOSTransportMessageSyncWithPeers:account.ids_message_transport p:peerIDs err:error]){ - secerror("SOSTransportMessageIDSHandleMessage Could not sync with all peers: %@", *error); - }else{ - secnotice("IDS Transport", "Synced with all peers!"); - } - - CFReleaseNull(peersToSyncWith); - CFReleaseNull(peerIDs); - }else{ - if(error && *error != NULL){ - CFStringRef errorMessage = CFErrorCopyDescription(*error); - if (-25308 == CFErrorGetCode(*error)) { // tell KeychainSyncingOverIDSProxy to call us back when device unlocks - result = kHandleIDSMessageLocked; - }else{ //else drop it, couldn't handle the message - result = kHandleIDSMessageDontHandle; - } - secerror("IDS Transport Could not handle message: %@, %@", messageData, *error); - CFReleaseNull(errorMessage); - - } - else{ //no error but failed? drop it, log message - secerror("IDS Transport Could not handle message: %@", messageData); - result = kHandleIDSMessageDontHandle; - - } - } - -exit: - CFReleaseNull(ourPeerIdKey); - CFReleaseNull(sendersPeerIDKey); - CFReleaseNull(deviceIDKey); - CFReleaseNull(dataKey); - return result; -} - --(CFDictionaryRef)CF_RETURNS_RETAINED SOSTransportMessageHandlePeerMessageReturnsHandledCopy:(SOSMessageIDSTest*) transport peerMessages:(CFMutableDictionaryRef)message err:(CFErrorRef *)error -{ - - CFMutableDictionaryRef handled = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - CFDictionaryRef peerToMessage = CFDictionaryGetValue(message, (__bridge CFTypeRef)(transport.circleName)); - CFMutableArrayRef handled_peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); - - secerror("Received IDS message!"); - if(peerToMessage){ - CFDictionaryForEach(peerToMessage, ^(const void *key, const void *value) { - CFStringRef peer_id = asString(key, NULL); - CFDataRef peer_message = asData(value, NULL); - CFErrorRef localError = NULL; - - if (peer_id && peer_message && [transport SOSTransportMessageHandlePeerMessage:transport id:peer_id cm:peer_message err:&localError]) { - CFArrayAppendValue(handled_peers, key); - } else { - secnotice("transport", "%@ KVSTransport handle message failed: %@", peer_id, localError); - } - CFReleaseNull(localError); - }); - } - CFDictionaryAddValue(handled, (__bridge CFStringRef)(transport.circleName), handled_peers); - CFReleaseNull(handled_peers); - - return handled; -} - -static void SOSTransportMessageIDSTestAddBulkToChanges(SOSMessageIDSTest* transport, CFDictionaryRef updates){ -#ifndef __clang_analyzer__ // The analyzer thinks transport.changes is a leak, but I don't know why. - if (transport.changes == NULL) { - transport.changes = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(updates), updates); - - } - else{ - CFDictionaryForEach(updates, ^(const void *key, const void *value) { - CFDictionaryAddValue(transport.changes, key, value); - }); - } -#endif -} -static bool sendDataToPeerIDSTest(SOSMessageIDSTest* transport, CFStringRef circleName, CFStringRef deviceID, CFStringRef peerID, CFDataRef message, CFErrorRef *error) -{ - secerror("sending message through test transport: %@", message); - NSString* myID = transport.account.peerID; - CFStringRef message_to_peer_key = SOSMessageKeyCreateFromTransportToPeer(transport, (__bridge CFStringRef) myID, peerID); - CFDictionaryRef a_message_to_a_peer = CFDictionaryCreateForCFTypes(NULL, message_to_peer_key, message, NULL); - - SOSTransportMessageIDSTestAddBulkToChanges(transport, a_message_to_a_peer); - - CFReleaseNull(message_to_peer_key); - CFReleaseNull(a_message_to_a_peer); - return true; - -} -static bool sendDictionaryToPeerIDSTest(SOSMessageIDSTest* transport, CFStringRef circleName, CFStringRef deviceID, CFStringRef peerID, CFDictionaryRef message, CFErrorRef *error) -{ - secerror("sending message through test transport: %@", message); - NSString* myID = transport.account.peerID; - CFStringRef message_to_peer_key = SOSMessageKeyCreateFromTransportToPeer(transport, (__bridge CFStringRef) myID, peerID); - CFDictionaryRef a_message_to_a_peer = CFDictionaryCreateForCFTypes(NULL, message_to_peer_key, message, NULL); - - SOSTransportMessageIDSTestAddBulkToChanges(transport, a_message_to_a_peer); - - CFReleaseNull(message_to_peer_key); - CFReleaseNull(a_message_to_a_peer); - return true; - -} - --(bool) SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*) transport p:(CFSetRef)peers err:(CFErrorRef *)error -{ - // Each entry is keyed by circle name and contains a list of peerIDs - __block bool result = true; - - CFSetForEach(peers, ^(const void *value) { - CFStringRef peerID = asString(value, NULL); - if (peerID) { - secnotice("transport", "IDS sync with peerIDs %@", peerID); - result &= [transport SOSTransportMessageSendMessageIfNeeded:transport id:(__bridge CFStringRef)transport.circleName pID:peerID err:error]; - } - }); - - return result; -} - --(bool) SOSTransportMessageSendMessages:(SOSMessageIDSTest*) transport pm:(CFDictionaryRef) peer_messages err:(CFErrorRef *)error -{ - __block bool result = true; - CFDictionaryForEach(peer_messages, ^(const void *key, const void *value) { - CFStringRef idsDeviceID = NULL;; - CFStringRef peerID = asString(key, NULL); - SOSPeerInfoRef pi = NULL; - if(peerID){ - if(!CFEqualSafe(peerID, (__bridge CFStringRef) transport.account.peerID)){ - - pi = SOSAccountCopyPeerWithID(transport.account, peerID, NULL); - if(pi){ - idsDeviceID = SOSPeerInfoCopyDeviceID(pi); - if(idsDeviceID != NULL){ - - CFDictionaryRef messageDictionary = asDictionary(value, NULL); - if (messageDictionary) { - result &= sendDictionaryToPeerIDSTest(transport, (__bridge CFStringRef)transport.circleName, idsDeviceID, peerID, messageDictionary, error); - } else { - CFDataRef messageData = asData(value, NULL); - if (messageData) { - result &= sendDataToPeerIDSTest(transport, (__bridge CFStringRef)transport.circleName, idsDeviceID, peerID, messageData, error); - } - } - } - } - } - } - CFReleaseNull(idsDeviceID); - CFReleaseNull(pi); - }); - - return result; -} - --(bool) SOSTransportMessageFlushChanges:(SOSMessageIDSTest*) transport err:(CFErrorRef *)error -{ - return true; -} - --(bool) SOSTransportMessageCleanupAfterPeerMessages:(SOSMessageIDSTest*) transport peers:(CFDictionaryRef) peers err:(CFErrorRef*) error -{ - return true; -} - -void SOSTransportMessageIDSTestClearChanges(SOSMessageIDSTest* transport) -{ - transport.changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); -} - -CFMutableDictionaryRef SOSTransportMessageIDSTestGetChanges(SOSMessageIDSTest* transport) -{ - return transport.changes; -} - -SOSAccount* SOSTransportMessageIDSTestGetAccount(SOSMessageIDSTest* transport) -{ - return transport.account; -} - -CFStringRef SOSTransportMessageIDSTestGetName(SOSMessageIDSTest* transport){ - return transport.accountName; -} - -@end - void SOSAccountUpdateTestTransports(SOSAccount* account, CFDictionaryRef gestalt){ CFStringRef new_name = (CFStringRef)CFDictionaryGetValue(gestalt, kPIUserDefinedDeviceNameKey); @@ -857,8 +511,6 @@ void SOSAccountUpdateTestTransports(SOSAccount* account, CFDictionaryRef gestalt SOSTransportKeyParameterTestSetName((CKKeyParameterTest*)account.key_transport, new_name); SOSTransportCircleTestSetName((SOSCircleStorageTransportTest*)account.circle_transport, new_name); SOSTransportMessageKVSTestSetName((SOSMessageKVSTest*)account.kvs_message_transport, new_name); - SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)account.ids_message_transport, new_name); - } static CF_RETURNS_RETAINED SOSCircleRef SOSAccountEnsureCircleTest(SOSAccount* a, CFStringRef name, CFStringRef accountName) @@ -926,9 +578,6 @@ bool SOSAccountInflateTestTransportsForCircle(SOSAccount* account, CFStringRef c if(account.kvs_message_transport == nil){ account.kvs_message_transport = (SOSMessageKVS*)[[SOSMessageKVSTest alloc] initWithAccount:account andName:accountName andCircleName:circleName]; } - if(account.ids_message_transport == nil){ - account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:account andAccountName:accountName andCircleName:circleName err:NULL]; - } success = true; fail: diff --git a/OSX/sec/securityd/Regressions/secd-02-upgrade-while-locked.m b/OSX/sec/securityd/Regressions/secd-02-upgrade-while-locked.m index 3f7756c5..01e207e4 100644 --- a/OSX/sec/securityd/Regressions/secd-02-upgrade-while-locked.m +++ b/OSX/sec/securityd/Regressions/secd-02-upgrade-while-locked.m @@ -113,7 +113,7 @@ static void *do_sos(void *arg) #define N_THREADS 10 void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); -CFArrayRef SecAccessGroupsGetCurrent(); +CFArrayRef SecAccessGroupsGetCurrent(void); int secd_02_upgrade_while_locked(int argc, char *const *argv) { diff --git a/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m b/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m index e02bc0fa..5fbdcb22 100644 --- a/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m +++ b/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m @@ -37,160 +37,9 @@ #import "SOSTransportTestTransports.h" #include "SOSTestDevice.h" #include "SOSTestDataSource.h" -#include #include static int kTestTestCount = 114; -static bool SOSAccountIsThisPeerIDMe(SOSAccount* account, CFStringRef peerID) { - SOSAccountTrustClassic* trust = account.trust; - SOSPeerInfoRef mypi = trust.peerInfo; - ok(mypi); - CFStringRef myPeerID = SOSPeerInfoGetPeerID(mypi); - ok(myPeerID); - return myPeerID && CFEqualSafe(myPeerID, peerID); -} - -__unused static void ids_test_sync(SOSAccount* alice_account, SOSAccount* bob_account){ - - CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - __block bool SyncingCompletedOverIDS = false; - __block CFErrorRef localError = NULL; - - SOSAccountTrustClassic* aliceTrust = alice_account.trust; - SOSAccountTrustClassic* bobTrust = bob_account.trust; - SOSDataSourceRef bob_ds = SOSDataSourceFactoryCreateDataSource(bob_account.factory, CFSTR("ak"), NULL); - SOSEngineRef bob_engine = bob_ds ? SOSDataSourceGetSharedEngine(bob_ds, NULL) : (SOSEngineRef) NULL; - SOSDataSourceRef alice_ds = SOSDataSourceFactoryCreateDataSource(alice_account.factory, CFSTR("ak"), NULL); - SOSEngineRef alice_engine = alice_ds ? SOSDataSourceGetSharedEngine(alice_ds, NULL) : (SOSEngineRef) NULL; - - /* new routines to test */ - __block NSString *bobID = bob_account.peerID; - __block NSString *aliceID = alice_account.peerID; - - - /////////////////////////// - //second exchange// - /////////////////////////// - - SOSCircleForEachValidPeer(aliceTrust.trustedCircle, alice_account.accountKey, ^(SOSPeerInfoRef peer) { - if (!SOSAccountIsThisPeerIDMe(alice_account, SOSPeerInfoGetPeerID(peer))) { - if(SOSPeerInfoShouldUseIDSTransport(aliceTrust.peerInfo, peer) && - SOSPeerInfoShouldUseIDSMessageFragmentation(aliceTrust.peerInfo, peer)){ - secnotice("IDS Transport","Syncing with IDS capable peers using IDS!"); - - CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer)); - - SyncingCompletedOverIDS = [alice_account.ids_message_transport SOSTransportMessageSyncWithPeers:alice_account.ids_message_transport p:ids err:&localError]; - CFReleaseNull(ids); - } - } - }); - - SOSEngineWithPeerID(alice_engine, (__bridge CFStringRef)bobID, NULL, ^(SOSPeerRef bob_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) { - ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(alice_account , bobID)); - ok(false == SOSPeerTimerForPeerExist(bob_peer)); - ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(alice_account, bobID)); - ok(true == SOSCoderIsCoderInAwaitingState(coder)); - }); - - ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL); - - SOSCircleForEachValidPeer(bobTrust.trustedCircle, bob_account.accountKey, ^(SOSPeerInfoRef peer) { - if (!SOSAccountIsThisPeerIDMe(bob_account, SOSPeerInfoGetPeerID(peer))) { - if(SOSPeerInfoShouldUseIDSTransport(bobTrust.peerInfo, peer) && - SOSPeerInfoShouldUseIDSMessageFragmentation(bobTrust.peerInfo, peer)){ - secnotice("IDS Transport","Syncing with IDS capable peers using IDS!"); - - CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer)); - - SyncingCompletedOverIDS = [(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*)bob_account.ids_message_transport p:ids err:&localError]; - CFReleaseNull(ids); - } - } - }); - - ok(SyncingCompletedOverIDS, "synced items over IDS"); - - SOSEngineWithPeerID(bob_engine, (__bridge CFStringRef)aliceID, NULL, ^(SOSPeerRef alice_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) { - ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(bob_account , aliceID)); - ok(false == SOSPeerTimerForPeerExist(alice_peer)); - ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(bob_account, aliceID)); - }); - - ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL); - - SOSEngineWithPeerID(alice_engine, (__bridge CFStringRef)bobID, NULL, ^(SOSPeerRef bob_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) { - ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(alice_account , bobID)); - ok(false == SOSPeerTimerForPeerExist(bob_peer)); - ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(alice_account, bobID)); - ok(true == SOSCoderIsCoderInAwaitingState(coder)); - }); - - /////////////////////////// - //second sync exchange // - /////////////////////////// - - SOSCircleForEachValidPeer(aliceTrust.trustedCircle, alice_account.accountKey, ^(SOSPeerInfoRef peer) { - if (!SOSAccountIsThisPeerIDMe(alice_account, SOSPeerInfoGetPeerID(peer))) { - if(SOSPeerInfoShouldUseIDSTransport(aliceTrust.peerInfo, peer) && - SOSPeerInfoShouldUseIDSMessageFragmentation(aliceTrust.peerInfo, peer)){ - secnotice("IDS Transport","Syncing with IDS capable peers using IDS!"); - - CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer)); - - SyncingCompletedOverIDS = [alice_account.ids_message_transport SOSTransportMessageSyncWithPeers:alice_account.ids_message_transport p:ids err:&localError]; - CFReleaseNull(ids); - } - } - }); - - SOSEngineWithPeerID(alice_engine, (__bridge CFStringRef)bobID, NULL, ^(SOSPeerRef bob_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) { - ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(alice_account , bobID)); - ok(false == SOSPeerTimerForPeerExist(bob_peer)); - ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(alice_account, bobID)); - ok(true == SOSCoderIsCoderInAwaitingState(coder)); - }); - - ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL); - - SOSCircleForEachValidPeer(bobTrust.trustedCircle, bob_account.accountKey, ^(SOSPeerInfoRef peer) { - if (!SOSAccountIsThisPeerIDMe(bob_account, SOSPeerInfoGetPeerID(peer))) { - if(SOSPeerInfoShouldUseIDSTransport(bobTrust.peerInfo, peer) && - SOSPeerInfoShouldUseIDSMessageFragmentation(bobTrust.peerInfo, peer)){ - secnotice("IDS Transport","Syncing with IDS capable peers using IDS!"); - - CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer)); - - SyncingCompletedOverIDS = [(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*)bob_account.ids_message_transport p:ids err:&localError]; - CFReleaseNull(ids); - } - } - }); - - ok(SyncingCompletedOverIDS, "synced items over IDS"); - - SOSEngineWithPeerID(bob_engine, (__bridge CFStringRef)aliceID, NULL, ^(SOSPeerRef alice_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) { - ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(bob_account , aliceID)); - ok(false == SOSPeerTimerForPeerExist(alice_peer)); - ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(bob_account, aliceID)); - }); - - ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL); - - SOSEngineWithPeerID(alice_engine, (__bridge CFStringRef)bobID, NULL, ^(SOSPeerRef bob_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) { - ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(alice_account , bobID)); - ok(false == SOSPeerTimerForPeerExist(bob_peer)); - ok(true == SOSPeerOTRTimerHaveAnRTTAvailable(alice_account, bobID)); - ok(false == SOSCoderIsCoderInAwaitingState(coder)); - }); - - CFReleaseNull(changes); -} - static void tests(void) { @@ -304,73 +153,6 @@ static void tests(void) SOSUnregisterAllTransportMessages(); CFArrayRemoveAllValues(message_transports); - SOSAccountTrustClassic* aliceTrust = alice_account.trust; - SOSAccountTrustClassic* bobTrust = bob_account.trust; - - alice_account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:alice_account andAccountName:CFSTR("Alice") andCircleName:SOSCircleGetName(aliceTrust.trustedCircle) err:&error ]; - - bob_account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:bob_account andAccountName:CFSTR("Bob") andCircleName:SOSCircleGetName(bobTrust.trustedCircle) err:&error]; - - ok(alice_account.ids_message_transport != NULL, "Alice Account, Created IDS Test Transport"); - ok(bob_account.ids_message_transport != NULL, "Bob Account, Created IDS Test Transport"); - - bool result = [alice_account.trust modifyCircle:alice_account.circle_transport err:&error action:^bool(SOSCircleRef circle) { - CFErrorRef localError = NULL; - - SOSFullPeerInfoUpdateTransportType(aliceTrust.fullPeerInfo, SOSTransportMessageTypeIDSV2, &localError); - SOSFullPeerInfoUpdateTransportPreference(aliceTrust.fullPeerInfo, kCFBooleanFalse, &localError); - SOSFullPeerInfoUpdateTransportFragmentationPreference(aliceTrust.fullPeerInfo, kCFBooleanTrue, &localError); - SOSFullPeerInfoUpdateTransportAckModelPreference(aliceTrust.fullPeerInfo, kCFBooleanTrue, &localError); - - return SOSCircleHasPeer(circle, aliceTrust.peerInfo, NULL); - }]; - - ok(result, "Alice account update circle with transport type"); - - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates"); - - result = [bob_account.trust modifyCircle:bob_account.circle_transport err:&error action:^bool(SOSCircleRef circle) { - CFErrorRef localError = NULL; - - SOSFullPeerInfoUpdateTransportType(bobTrust.fullPeerInfo, SOSTransportMessageTypeIDSV2, &localError); - SOSFullPeerInfoUpdateTransportPreference(bobTrust.fullPeerInfo, kCFBooleanFalse, &localError); - SOSFullPeerInfoUpdateTransportFragmentationPreference(bobTrust.fullPeerInfo, kCFBooleanTrue, &localError); - SOSFullPeerInfoUpdateTransportAckModelPreference(bobTrust.fullPeerInfo, kCFBooleanTrue, &localError); - - return SOSCircleHasPeer(circle, bobTrust.peerInfo, NULL); - }]; - - ok(result, "Bob account update circle with transport type"); - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates"); - - CFStringRef alice_transportType =SOSPeerInfoCopyTransportType(alice_account.peerInfo); - CFStringRef bob_accountTransportType = SOSPeerInfoCopyTransportType(bob_account.peerInfo); - ok(CFEqualSafe(alice_transportType, CFSTR("IDS2.0")), "Alice transport type not IDS"); - ok(CFEqualSafe(bob_accountTransportType, CFSTR("IDS2.0")), "Bob transport type not IDS"); - - CFReleaseNull(alice_transportType); - CFReleaseNull(bob_accountTransportType); - - SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)alice_account.ids_message_transport, CFSTR("Alice Account")); - ok(SOSTransportMessageIDSTestGetName((SOSMessageIDSTest*)alice_account.ids_message_transport) != NULL, "retrieved getting account name"); - ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(alice_account, &error) != false, "device ID from KeychainSyncingOverIDSProxy"); - - SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)bob_account.ids_message_transport, CFSTR("Bob Account")); - ok(SOSTransportMessageIDSTestGetName((SOSMessageIDSTest*)bob_account.ids_message_transport) != NULL, "retrieved getting account name"); - ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(bob_account, &error) != false, "device ID from KeychainSyncingOverIDSProxy"); - - - ok(SOSAccountSetMyDSID_wTxn(alice_account, CFSTR("Alice"),&error), "Setting IDS device ID"); - CFStringRef alice_dsid = SOSAccountCopyDeviceID(alice_account, &error); - ok(CFEqualSafe(alice_dsid, CFSTR("Alice")), "Getting IDS device ID"); - CFReleaseNull(alice_dsid); - - ok(SOSAccountSetMyDSID_wTxn(bob_account, CFSTR("Bob"),&error), "Setting IDS device ID"); - CFStringRef bob_dsid = SOSAccountCopyDeviceID(bob_account, &error); - ok(CFEqualSafe(bob_dsid, CFSTR("Bob")), "Getting IDS device ID"); - CFReleaseNull(bob_dsid); - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates"); - ok(SOSAccountEnsurePeerRegistration(alice_account, NULL), "ensure peer registration - alice"); ok(SOSAccountEnsurePeerRegistration(bob_account, NULL), "ensure peer registration - bob"); diff --git a/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m b/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m index a333f310..659f2b54 100644 --- a/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m +++ b/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m @@ -144,7 +144,7 @@ keychain_upgrade(bool musr, const char *dbname) } void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); -CFArrayRef SecAccessGroupsGetCurrent(); +CFArrayRef SecAccessGroupsGetCurrent(void); int secd_20_keychain_upgrade(int argc, char *const *argv) diff --git a/OSX/sec/securityd/Regressions/secd-200-logstate.m b/OSX/sec/securityd/Regressions/secd-200-logstate.m index ac1d8f34..265bda37 100644 --- a/OSX/sec/securityd/Regressions/secd-200-logstate.m +++ b/OSX/sec/securityd/Regressions/secd-200-logstate.m @@ -146,6 +146,34 @@ static bool AssertAllCredentialsAndUpdate(CFMutableDictionaryRef changes, SOSAcc return retval; } +static void timeval_delta(struct timeval *delta, struct timeval *start, struct timeval *end) { + if(end->tv_usec >= start->tv_usec) { + delta->tv_usec = end->tv_usec - start->tv_usec; + } else { + end->tv_sec--; + end->tv_usec += 1000000; + delta->tv_usec = end->tv_usec - start->tv_usec; + } + delta->tv_sec = end->tv_sec - start->tv_sec; +} + +static void reportTime(int peers, void(^action)(void)) { + struct rusage start_rusage; + struct rusage end_rusage; + struct timeval delta_utime; + struct timeval delta_stime; + + getrusage(RUSAGE_SELF, &start_rusage); + action(); + getrusage(RUSAGE_SELF, &end_rusage); + timeval_delta(&delta_utime, &start_rusage.ru_utime, &end_rusage.ru_utime); + timeval_delta(&delta_stime, &start_rusage.ru_stime, &end_rusage.ru_stime); + + diag("AccountLogState for %d peers: %ld.%06d user %ld.%06d system", peers, + delta_utime.tv_sec, delta_utime.tv_usec, + delta_stime.tv_sec, delta_stime.tv_usec); +} + static void tests(void) { NSError* ns_error = nil; @@ -162,14 +190,18 @@ static void tests(void) CFReleaseNull(cfpassword); secLogEnable(); - SOSAccountLogState(master_account); + reportTime(1, ^{ + SOSAccountLogState(master_account); + }); secLogDisable(); ok(MakeTheBigCircle(changes, master_account, minion_accounts, &error), "Get Everyone into the circle %@", error); diag("WHAT?"); secLogEnable(); - SOSAccountLogState(master_account); + reportTime(HOW_MANY_MINIONS+1, ^{ + SOSAccountLogState(master_account); + }); SOSAccountLogViewState(master_account); secLogDisable(); diff --git a/OSX/sec/securityd/Regressions/secd-201-coders.m b/OSX/sec/securityd/Regressions/secd-201-coders.m index 1f386a25..74a131db 100644 --- a/OSX/sec/securityd/Regressions/secd-201-coders.m +++ b/OSX/sec/securityd/Regressions/secd-201-coders.m @@ -59,135 +59,6 @@ #include "SecdTestKeychainUtilities.h" -static bool SOSAccountIsThisPeerIDMe(SOSAccount* account, CFStringRef peerID) { - SOSAccountTrustClassic*trust = account.trust; - SOSPeerInfoRef mypi = trust.peerInfo; - CFStringRef myPeerID = SOSPeerInfoGetPeerID(mypi); - - return myPeerID && CFEqualSafe(myPeerID, peerID); -} - -static void compareCoders(CFMutableDictionaryRef beforeCoders, CFMutableDictionaryRef afterCoderState) -{ - CFDictionaryForEach(beforeCoders, ^(const void *key, const void *value) { - CFStringRef beforePeerid = (CFStringRef)key; - SOSCoderRef beforeCoderData = (SOSCoderRef)value; - SOSCoderRef afterCoderData = (SOSCoderRef)CFDictionaryGetValue(afterCoderState, beforePeerid); - ok(CFEqual(beforeCoderData,afterCoderData)); - }); -} - -static void ids_test_sync(SOSAccount* alice_account, SOSAccount* bob_account){ - - CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - __block bool SyncingCompletedOverIDS = false; - __block CFErrorRef localError = NULL; - __block bool done = false; - SOSAccountTrustClassic *aliceTrust = alice_account.trust; - SOSAccountTrustClassic *bobTrust = bob_account.trust; - - do{ - SOSCircleForEachValidPeer(aliceTrust.trustedCircle, alice_account.accountKey, ^(SOSPeerInfoRef peer) { - if (!SOSAccountIsThisPeerIDMe(alice_account, SOSPeerInfoGetPeerID(peer))) { - if(SOSPeerInfoShouldUseIDSTransport(aliceTrust.peerInfo, peer) && - SOSPeerInfoShouldUseIDSMessageFragmentation(aliceTrust.peerInfo, peer)){ - secnotice("IDS Transport","Syncing with IDS capable peers using IDS!"); - - CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer)); - - CFTypeRef alice_engine = [(SOSMessageIDSTest*)alice_account.ids_message_transport SOSTransportMessageGetEngine]; - - //testing loading and saving coders - ok(TestSOSEngineGetCoders(alice_engine)); - CFMutableDictionaryRef beforeCoders = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(TestSOSEngineGetCoders(alice_engine)), TestSOSEngineGetCoders(alice_engine)); - TestSOSEngineDoTxnOnQueue(alice_engine, &localError, ^(SOSTransactionRef txn, bool *commit) { - ok(TestSOSEngineLoadCoders((SOSEngineRef)[(SOSMessageIDSTest*)alice_account.ids_message_transport SOSTransportMessageGetEngine], txn, &localError)); - }); - - ok(TestSOSEngineGetCoders(alice_engine)); - - TestSOSEngineDoTxnOnQueue(alice_engine, &localError, ^(SOSTransactionRef txn, bool *commit) { - ok(SOSTestEngineSaveCoders(alice_engine, txn, &localError)); - }); - - compareCoders(beforeCoders, TestSOSEngineGetCoders(alice_engine)); - - //syncing with all peers - SyncingCompletedOverIDS = [(SOSMessageIDSTest*)alice_account.ids_message_transport SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*)alice_account.ids_message_transport p:ids err:&localError]; - //testing load after sync with all peers - CFMutableDictionaryRef codersAfterSyncBeforeLoad = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(TestSOSEngineGetCoders(alice_engine)), TestSOSEngineGetCoders(alice_engine)); - TestSOSEngineDoTxnOnQueue(alice_engine, &localError, ^(SOSTransactionRef txn, bool *commit) { - ok(TestSOSEngineLoadCoders((SOSEngineRef)[(SOSMessageIDSTest*)alice_account.ids_message_transport SOSTransportMessageGetEngine], txn, &localError)); - }); - compareCoders(codersAfterSyncBeforeLoad, TestSOSEngineGetCoders(alice_engine)); - - CFReleaseNull(codersAfterSyncBeforeLoad); - CFReleaseNull(beforeCoders); - CFReleaseNull(ids); - } - } - }); - - ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL); - - SOSCircleForEachValidPeer(bobTrust.trustedCircle, bob_account.accountKey, ^(SOSPeerInfoRef peer) { - if (!SOSAccountIsThisPeerIDMe(bob_account, SOSPeerInfoGetPeerID(peer))) { - if(SOSPeerInfoShouldUseIDSTransport(bobTrust.peerInfo, peer) && - SOSPeerInfoShouldUseIDSMessageFragmentation(bobTrust.peerInfo, peer)){ - secnotice("IDS Transport","Syncing with IDS capable peers using IDS!"); - - CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer)); - - SOSEngineRef bob_engine = (SOSEngineRef)[(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageGetEngine]; - - //testing loading and saving coders - ok(TestSOSEngineGetCoders(bob_engine)); - CFMutableDictionaryRef beforeCoders = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(TestSOSEngineGetCoders(bob_engine)), TestSOSEngineGetCoders(bob_engine)); - TestSOSEngineDoTxnOnQueue(bob_engine, &localError, ^(SOSTransactionRef txn, bool *commit) { - ok(TestSOSEngineLoadCoders((SOSEngineRef)[(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageGetEngine], txn, &localError)); - }); - - ok((SOSEngineRef)TestSOSEngineGetCoders(bob_engine)); - - TestSOSEngineDoTxnOnQueue(bob_engine, &localError, ^(SOSTransactionRef txn, bool *commit) { - ok(SOSTestEngineSaveCoders(bob_engine, txn, &localError)); - }); - - compareCoders(beforeCoders, TestSOSEngineGetCoders(bob_engine)); - - SyncingCompletedOverIDS &= [(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*)bob_account.ids_message_transport p:ids err:&localError]; - - //testing load after sync with all peers - CFMutableDictionaryRef codersAfterSyncBeforeLoad = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(TestSOSEngineGetCoders(bob_engine)), TestSOSEngineGetCoders(bob_engine)); - TestSOSEngineDoTxnOnQueue(bob_engine, &localError, ^(SOSTransactionRef txn, bool *commit) { - ok(TestSOSEngineLoadCoders((SOSEngineRef)[(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageGetEngine], txn, &localError)); - }); - compareCoders(codersAfterSyncBeforeLoad, TestSOSEngineGetCoders(bob_engine)); - CFReleaseNull(codersAfterSyncBeforeLoad); - CFReleaseNull(beforeCoders); - CFReleaseNull(ids); - } - } - }); - if(!SyncingCompletedOverIDS) - return; - - if(CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges((SOSMessageIDSTest*)alice_account.ids_message_transport)) == 0 && CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges((SOSMessageIDSTest*)bob_account.ids_message_transport)) == 0){ - done = true; - break; - } - - ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL); - - }while(done == false); - CFReleaseNull(changes); - - ok(SyncingCompletedOverIDS, "synced items over IDS"); - -} - static void tests(void) { @@ -281,77 +152,10 @@ static void tests(void) SOSUnregisterAllTransportMessages(); CFArrayRemoveAllValues(message_transports); - SOSAccountTrustClassic *aliceTrust = alice_account.trust; - SOSAccountTrustClassic *bobTrust = bob_account.trust; - - alice_account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:alice_account andAccountName:CFSTR("Alice") andCircleName:CFSTR("TestSource") err:&error]; - - bob_account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:bob_account andAccountName:CFSTR("Bob") andCircleName:CFSTR("TestSource") err:&error]; - - bool result = [alice_account.trust modifyCircle:alice_account.circle_transport err:&error action:^(SOSCircleRef circle) { - - CFErrorRef localError = NULL; - - SOSFullPeerInfoUpdateTransportType(aliceTrust.fullPeerInfo, SOSTransportMessageTypeIDSV2, &localError); - SOSFullPeerInfoUpdateTransportPreference(aliceTrust.fullPeerInfo, kCFBooleanFalse, &localError); - SOSFullPeerInfoUpdateTransportFragmentationPreference(aliceTrust.fullPeerInfo, kCFBooleanTrue, &localError); - SOSFullPeerInfoUpdateTransportAckModelPreference(aliceTrust.fullPeerInfo, kCFBooleanTrue, &localError); - - return SOSCircleHasPeer(circle, aliceTrust.peerInfo, NULL); - }]; - - ok(result, "Alice account update circle with transport type"); - - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates"); - - result = [bob_account.trust modifyCircle:bob_account.circle_transport err:&error action:^(SOSCircleRef circle) { - CFErrorRef localError = NULL; - - SOSFullPeerInfoUpdateTransportType(bobTrust.fullPeerInfo, SOSTransportMessageTypeIDSV2, &localError); - SOSFullPeerInfoUpdateTransportPreference(bobTrust.fullPeerInfo, kCFBooleanFalse, &localError); - SOSFullPeerInfoUpdateTransportFragmentationPreference(bobTrust.fullPeerInfo, kCFBooleanTrue, &localError); - SOSFullPeerInfoUpdateTransportAckModelPreference(bobTrust.fullPeerInfo, kCFBooleanTrue, &localError); - - return SOSCircleHasPeer(circle, bobTrust.peerInfo, NULL); - }]; - - ok(result, "Bob account update circle with transport type"); - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates"); - - CFStringRef alice_transportType =SOSPeerInfoCopyTransportType(alice_account.peerInfo); - CFStringRef bob_accountTransportType = SOSPeerInfoCopyTransportType(bob_account.peerInfo); - ok(CFEqualSafe(alice_transportType, CFSTR("IDS2.0")), "Alice transport type not IDS"); - ok(CFEqualSafe(bob_accountTransportType, CFSTR("IDS2.0")), "Bob transport type not IDS"); - - CFReleaseNull(alice_transportType); - CFReleaseNull(bob_accountTransportType); - - SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)alice_account.ids_message_transport, CFSTR("Alice Account")); - ok(SOSTransportMessageIDSTestGetName((SOSMessageIDSTest*)alice_account.ids_message_transport) != NULL, "retrieved getting account name"); - ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(alice_account, &error) != false, "device ID from KeychainSyncingOverIDSProxy"); - - SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)bob_account.ids_message_transport, CFSTR("Bob Account")); - ok(SOSTransportMessageIDSTestGetName((SOSMessageIDSTest*)bob_account.ids_message_transport) != NULL, "retrieved getting account name"); - ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(bob_account, &error) != false, "device ID from KeychainSyncingOverIDSProxy"); - - - ok(SOSAccountSetMyDSID_wTxn(alice_account, CFSTR("Alice"),&error), "Setting IDS device ID"); - CFStringRef alice_dsid = SOSAccountCopyDeviceID(alice_account, &error); - ok(CFEqualSafe(alice_dsid, CFSTR("Alice")), "Getting IDS device ID"); - CFReleaseNull(alice_dsid); - - ok(SOSAccountSetMyDSID_wTxn(bob_account, CFSTR("Bob"),&error), "Setting IDS device ID"); - CFStringRef bob_dsid = SOSAccountCopyDeviceID(bob_account, &error); - ok(CFEqualSafe(bob_dsid, CFSTR("Bob")), "Getting IDS device ID"); - CFReleaseNull(bob_dsid); - - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates"); ok(SOSAccountEnsurePeerRegistration(alice_account, NULL), "ensure peer registration - alice"); ok(SOSAccountEnsurePeerRegistration(bob_account, NULL), "ensure peer registration - bob"); - ids_test_sync(alice_account, bob_account); - alice_account = nil; bob_account = nil; diff --git a/OSX/sec/securityd/Regressions/secd-21-transmogrify.m b/OSX/sec/securityd/Regressions/secd-21-transmogrify.m index 9ede92db..34f087f7 100644 --- a/OSX/sec/securityd/Regressions/secd-21-transmogrify.m +++ b/OSX/sec/securityd/Regressions/secd-21-transmogrify.m @@ -45,7 +45,7 @@ #include "SecdTestKeychainUtilities.h" void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); -CFArrayRef SecAccessGroupsGetCurrent(); +CFArrayRef SecAccessGroupsGetCurrent(void); int secd_21_transmogrify(int argc, char *const *argv) diff --git a/OSX/sec/securityd/Regressions/secd-230-keybagtable.m b/OSX/sec/securityd/Regressions/secd-230-keybagtable.m index afc16948..34545e6d 100644 --- a/OSX/sec/securityd/Regressions/secd-230-keybagtable.m +++ b/OSX/sec/securityd/Regressions/secd-230-keybagtable.m @@ -61,7 +61,7 @@ static const bool kTestCustomKeybag = false; static const bool kTestLocalKeybag = false; void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); -CFArrayRef SecAccessGroupsGetCurrent(); +CFArrayRef SecAccessGroupsGetCurrent(void); #define kSecdTestCreateCustomKeybagTestCount 6 #define kSecdTestLocalKeybagTestCount 1 diff --git a/OSX/sec/securityd/Regressions/secd-35-keychain-migrate-inet.m b/OSX/sec/securityd/Regressions/secd-35-keychain-migrate-inet.m index dc3c81ca..2c1c12ef 100644 --- a/OSX/sec/securityd/Regressions/secd-35-keychain-migrate-inet.m +++ b/OSX/sec/securityd/Regressions/secd-35-keychain-migrate-inet.m @@ -45,7 +45,7 @@ #include "ios8-inet-keychain-2.h" void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); -CFArrayRef SecAccessGroupsGetCurrent(); +CFArrayRef SecAccessGroupsGetCurrent(void); int secd_35_keychain_migrate_inet(int argc, char *const *argv) { diff --git a/OSX/sec/securityd/Regressions/secd-37-pairing-initial-sync.m b/OSX/sec/securityd/Regressions/secd-37-pairing-initial-sync.m index 72604f5c..b527505b 100644 --- a/OSX/sec/securityd/Regressions/secd-37-pairing-initial-sync.m +++ b/OSX/sec/securityd/Regressions/secd-37-pairing-initial-sync.m @@ -43,7 +43,7 @@ #include "SecdTestKeychainUtilities.h" void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); -CFArrayRef SecAccessGroupsGetCurrent(); +CFArrayRef SecAccessGroupsGetCurrent(void); static void AddItem(NSDictionary *attr) diff --git a/OSX/sec/securityd/Regressions/secd-40-cc-gestalt.m b/OSX/sec/securityd/Regressions/secd-40-cc-gestalt.m index 8278bf8c..4b3d21d5 100644 --- a/OSX/sec/securityd/Regressions/secd-40-cc-gestalt.m +++ b/OSX/sec/securityd/Regressions/secd-40-cc-gestalt.m @@ -30,7 +30,7 @@ static int kTestTestCount = 1; static void tests(void) { - CFStringRef osVersion = CopyOSVersion(); + CFStringRef osVersion = SOSCCCopyOSVersion(); ok(osVersion != NULL, "OS Version Exists"); diff --git a/OSX/sec/securityd/Regressions/secd-55-account-circle.m b/OSX/sec/securityd/Regressions/secd-55-account-circle.m index da395b8e..e21b77a4 100644 --- a/OSX/sec/securityd/Regressions/secd-55-account-circle.m +++ b/OSX/sec/securityd/Regressions/secd-55-account-circle.m @@ -53,7 +53,7 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 324; +static int kTestTestCount = 257; static void tests(void) { @@ -246,8 +246,9 @@ static void tests(void) ok(SOSAccountJoinCircles_wTxn(alice_account, &error), "Alice re-applies (%@)", error); CFReleaseNull(error); - FeedChangesTo(changes, bob_account); // Bob sees Alice reapply. - + //FeedChangesTo(changes, bob_account); // Bob sees Alice reapply. + is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates"); + { CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error); @@ -256,7 +257,7 @@ static void tests(void) CFReleaseNull(error); CFReleaseNull(applicants); } - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carol_account, NULL), 2, "updates"); + is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carol_account, NULL), 3, "updates"); accounts_agree("Alice comes back", bob_account, alice_account); @@ -328,10 +329,10 @@ static void tests(void) is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carol_account, NULL), 4, "Remove peers"); - ok([alice_account.trust isInCircle:&error], "Alice still here"); - ok(![bob_account.trust isInCircle:&error], "Bob not in circle"); + ok([alice_account isInCircle:&error], "Alice still here"); + ok(![bob_account isInCircle:&error], "Bob not in circle"); // Carol's not in circle, but reapplied, as she's persistent until positive rejection. - ok(![carol_account.trust isInCircle:NULL], "carol not in circle"); + ok(![carol_account isInCircle:NULL], "carol not in circle"); CFReleaseNull(peers_to_remove_array); diff --git a/OSX/sec/securityd/Regressions/secd-57-1-account-last-standing.m b/OSX/sec/securityd/Regressions/secd-57-1-account-last-standing.m index 3ffddba9..9ddf953c 100644 --- a/OSX/sec/securityd/Regressions/secd-57-1-account-last-standing.m +++ b/OSX/sec/securityd/Regressions/secd-57-1-account-last-standing.m @@ -107,7 +107,7 @@ static void tests(void) is(ProcessChangesUntilNoChange(changes, alice_account, NULL), 1, "updates"); - ok([alice_account.trust isInCircle:&error], "Alice is back in the circle (%@)", error); + ok([alice_account isInCircle:&error], "Alice is back in the circle (%@)", error); CFReleaseNull(error); is(countActivePeers(alice_account), 2, "Alice sees 2 active peers"); diff --git a/OSX/sec/securityd/Regressions/secd-57-account-leave.m b/OSX/sec/securityd/Regressions/secd-57-account-leave.m index ed672f79..a85691de 100644 --- a/OSX/sec/securityd/Regressions/secd-57-account-leave.m +++ b/OSX/sec/securityd/Regressions/secd-57-account-leave.m @@ -244,7 +244,7 @@ static void tests(void) ok([bob_account.trust leaveCircle:bob_account err:&error], "bob Leaves w/o credentials (%@)", error); CFReleaseNull(error); - ok(![bob_account.trust isInCircle:&error], "bob knows he's out (%@)", error); + ok(![bob_account isInCircle:&error], "bob knows he's out (%@)", error); CFReleaseNull(error); alice_account = nil; bob_account = nil; diff --git a/OSX/sec/securityd/Regressions/secd-63-account-resurrection.m b/OSX/sec/securityd/Regressions/secd-63-account-resurrection.m index 89aae049..2291a9a4 100644 --- a/OSX/sec/securityd/Regressions/secd-63-account-resurrection.m +++ b/OSX/sec/securityd/Regressions/secd-63-account-resurrection.m @@ -56,7 +56,7 @@ static int kTestTestCount = 107; typedef void (^stir_block)(int expected_iterations); -typedef int (^execute_block)(); +typedef int (^execute_block)(void); static void stirBetween(stir_block stir, ...) { va_list va; @@ -183,7 +183,7 @@ static void tests(void) CFReleaseNull(error); return 1; }, ^{ - ok(![alice_resurrected.trust isInCircle:&error], "Ressurrected not in circle: %@", error); + ok(![alice_resurrected isInCircle:&error], "Ressurrected not in circle: %@", error); CFReleaseNull(error); ok(SOSAccountJoinCircles_wTxn(alice_resurrected, &error), "Risen-alice Applies (%@)", error); diff --git a/OSX/sec/securityd/Regressions/secd-65-account-retirement-reset.m b/OSX/sec/securityd/Regressions/secd-65-account-retirement-reset.m index 7a4e2f21..ba205e63 100644 --- a/OSX/sec/securityd/Regressions/secd-65-account-retirement-reset.m +++ b/OSX/sec/securityd/Regressions/secd-65-account-retirement-reset.m @@ -56,7 +56,7 @@ static int kTestTestCount = 43; typedef void (^stir_block)(int expected_iterations); -typedef int (^execute_block)(); +typedef int (^execute_block)(void); static void stirBetween(stir_block stir, ...) { va_list va; @@ -156,10 +156,10 @@ static void tests(void) CFReleaseNull(error); return 1; }, ^{ - ok(![alice_resurrected.trust isInCircle:&error], "Ressurrected not in circle: %@", error); + ok(![alice_resurrected isInCircle:&error], "Ressurrected not in circle: %@", error); CFReleaseNull(error); - ok([bob_account.trust isInCircle:&error], "Should be in circle: %@", error); + ok([bob_account isInCircle:&error], "Should be in circle: %@", error); CFReleaseNull(error); return 1; diff --git a/OSX/sec/securityd/Regressions/secd-668-ghosts.m b/OSX/sec/securityd/Regressions/secd-668-ghosts.m index c018e6b5..95313c2e 100644 --- a/OSX/sec/securityd/Regressions/secd-668-ghosts.m +++ b/OSX/sec/securityd/Regressions/secd-668-ghosts.m @@ -81,9 +81,9 @@ static void hauntedCircle(SOSPeerInfoDeviceClass devClass, bool expectGhostBuste // Did ghostbuster work? is(ProcessChangesUntilNoChange(changes, bobFinal, NULL), 2, "updates"); if(expectGhostBusted) { // ghostbusting is currently disabled for MacOSX Peers - ok([bobFinal.trust isInCircle:NULL], "Bob is in"); + ok([bobFinal isInCircle:NULL], "Bob is in"); } else { - ok(![bobFinal.trust isInCircle:NULL], "Bob is not in"); + ok(![bobFinal isInCircle:NULL], "Bob is not in"); } is(countPeers(bobFinal), 1, "There should only be 1 valid peer"); @@ -141,7 +141,7 @@ static void multiBob(SOSPeerInfoDeviceClass devClass, bool expectGhostBusted, bo CFReleaseNull(cfpassword); - ok([bobFinal_account.trust isInCircle:NULL], "bobFinal_account is in"); + ok([bobFinal_account isInCircle:NULL], "bobFinal_account is in"); is(countPeers(bobFinal_account), 2, "Expect ghostBobs to be gone"); is(countPeers(alice_account), 2, "Expect ghostBobs to be gone"); diff --git a/OSX/sec/securityd/Regressions/secd-700-sftm.m b/OSX/sec/securityd/Regressions/secd-700-sftm.m deleted file mode 100644 index 49280848..00000000 --- a/OSX/sec/securityd/Regressions/secd-700-sftm.m +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -// -// secd-700-sftm.m -// - -#import -#import "secd_regressions.h" -#import "SecdTestKeychainUtilities.h" - -#import "keychain/Signin Metrics/SFTransactionMetric.h" - -static void test() -{ - SFTransactionMetric *metric = [[SFTransactionMetric alloc] initWithUUID:@"UUID" category:@"CoreCDP"]; - NSError *error = [[NSError alloc] initWithDomain:@"TestErrorDomain" code:42 userInfo:@{}]; - [metric logError:error]; - - NSDictionary* eventAttributes = @{@"wait for initial sync time" : @"90 s", @"event result" : @"success"}; - [metric logEvent:@"event" eventAttributes:eventAttributes]; - - NSDictionary *query = @{ - (id)kSecClass : (id)kSecClassGenericPassword, - (id)kSecAttrLabel : @"TestLabel", - (id)kSecAttrAccessGroup : @"com.apple.security.wiiss", - }; - - [metric timeEvent:@"Adding item to keychain" blockToTime:^{ - CFTypeRef result; - SecItemAdd((__bridge CFDictionaryRef)query, &result); - }]; - - [metric signInCompleted]; -} - -int secd_700_sftm(int argc, char *const *argv) -{ - plan_tests(1); - - secd_test_setup_temp_keychain(__FUNCTION__, NULL); - - test(); - - return 0; -} diff --git a/OSX/sec/securityd/Regressions/secd-82-secproperties-basic.m b/OSX/sec/securityd/Regressions/secd-82-secproperties-basic.m deleted file mode 100644 index 791024ca..00000000 --- a/OSX/sec/securityd/Regressions/secd-82-secproperties-basic.m +++ /dev/null @@ -1,129 +0,0 @@ -// -// secd-82-secproperties-basic.c -// sec -// -// Created by Richard Murphy on 4/16/15. -// -// - -#include -// -// secd-80-views-basic.c -// sec -// -// Created by Richard Murphy on 1/26/15. -// -// - -#include -/* - * Copyright (c) 2012-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@ - */ - - - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "secd_regressions.h" -#include "SOSTestDataSource.h" - -#include "SOSRegressionUtilities.h" -#include - -#include -#include "SecdTestKeychainUtilities.h" -#include "SOSAccountTesting.h" - - -static void testSecurityProperties(SOSAccount* account, SOSSecurityPropertyResultCode expected, CFStringRef property, SOSSecurityPropertyActionCode action, char *label) { - CFErrorRef error = NULL; - SOSSecurityPropertyResultCode pcode = 9999; - switch(action) { - case kSOSCCSecurityPropertyQuery: - pcode = [account.trust SecurityPropertyStatus:property err:&error]; - break; - case kSOSCCSecurityPropertyEnable: - case kSOSCCSecurityPropertyDisable: // fallthrough - pcode = [account.trust UpdateSecurityProperty:account property:property code:action err:&error]; - break; - default: - break; - } - ok((pcode == expected), "%s (%@)", label, error); - CFReleaseNull(error); -} - -static int kTestTestCount = 13; -static void tests(void) -{ - CFErrorRef error = NULL; - CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10); - CFStringRef cfaccount = CFSTR("test@test.org"); - - SOSDataSourceFactoryRef test_factory = SOSTestDataSourceFactoryCreate(); - SOSDataSourceRef test_source = SOSTestDataSourceCreate(); - SOSTestDataSourceFactorySetDataSource(test_factory, CFSTR("TestType"), test_source); - - SOSAccount* account = CreateAccountForLocalChanges(CFSTR("Test Device"),CFSTR("TestType") ); - - ok(SOSAccountAssertUserCredentialsAndUpdate(account, cfaccount, cfpassword, &error), "Credential setting (%@)", error); - CFReleaseNull(error); - CFReleaseNull(cfpassword); - - ok(SOSAccountJoinCircles_wTxn(account, &error), "Join Cirlce"); - - ok(NULL != account, "Created"); - - testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyHasEntropy, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyHasEntropy"); - testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyScreenLock, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyScreenLock"); - testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertySEP, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertySEP"); - testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyIOS"); - testSecurityProperties(account, kSOSCCSecurityPropertyValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyEnable, "Expected to add property: kSOSSecPropertyIOS"); - testSecurityProperties(account, kSOSCCSecurityPropertyValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyIOS"); - testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyDisable, "Expected to disable property: kSOSSecPropertyIOS"); - testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyIOS"); - testSecurityProperties(account, kSOSCCNoSuchSecurityProperty, CFSTR("FOO"), kSOSCCSecurityPropertyQuery, "Expected no such property for FOO"); - SOSDataSourceRelease(test_source, NULL); - SOSDataSourceFactoryRelease(test_factory); - - SOSTestCleanup(); -} - -int secd_82_secproperties_basic(int argc, char *const *argv) -{ - plan_tests(kTestTestCount); - - secd_test_setup_temp_keychain(__FUNCTION__, NULL); - - tests(); - - return 0; -} diff --git a/OSX/sec/securityd/Regressions/secd_regressions.h b/OSX/sec/securityd/Regressions/secd_regressions.h index 70a8fe41..fb52b6d0 100644 --- a/OSX/sec/securityd/Regressions/secd_regressions.h +++ b/OSX/sec/securityd/Regressions/secd_regressions.h @@ -66,8 +66,6 @@ ONE_TEST(secd_70_engine) ONE_TEST(secd_70_engine_corrupt) ONE_TEST(secd_70_engine_smash) ONE_TEST(secd_71_engine_save) -ONE_TEST(secd_76_idstransport) -ONE_TEST(secd_77_ids_messaging) ONE_TEST(secd_68_ghosts) ONE_TEST(secd_155_otr_negotiation_monitor) @@ -76,7 +74,6 @@ ONE_TEST(secd_74_engine_beer_servers) OFF_ONE_TEST(secd_75_engine_views) ONE_TEST(secd_80_views_basic) ONE_TEST(secd_80_views_alwayson) -ONE_TEST(secd_82_secproperties_basic) #if TARGET_IPHONE_SIMULATOR OFF_ONE_TEST(secd_81_item_acl_stress) OFF_ONE_TEST(secd_81_item_acl) @@ -97,6 +94,5 @@ ONE_TEST(secd_200_logstate) ONE_TEST(secd_201_coders) ONE_TEST(secd_202_recoverykey) ONE_TEST(secd_210_keyinterest) -ONE_TEST(secd_700_sftm) DISABLED_ONE_TEST(secd_230_keybagtable) diff --git a/OSX/sec/securityd/SFKeychainServer.h b/OSX/sec/securityd/SFKeychainServer.h new file mode 100644 index 00000000..771384cb --- /dev/null +++ b/OSX/sec/securityd/SFKeychainServer.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import + +#define kSFKeychainServerServiceName "com.apple.security.sfkeychainserver" + +#if !TARGET_OS_BRIDGE && __OBJC2__ + +#import +#import +#import "SecCDKeychain.h" + +@interface SFKeychainServer : NSObject + +- (instancetype)initWithStorageURL:(NSURL*)persistentStoreURL modelURL:(NSURL*)managedObjectURL encryptDatabase:(bool)encryptDatabase; + +@end + +@interface SecCDKeychainItemTypeCredential : SecCDKeychainItemType +@end + +@interface SFKeychainServerConnection : NSObject + +@property (readonly) NSArray* clientAccessGroups; + +@end + +#endif // !TARGET_OS_BRIDGE && __OBJC2__ + +void SFKeychainServerInitialize(void); diff --git a/OSX/sec/securityd/SFKeychainServer.m b/OSX/sec/securityd/SFKeychainServer.m new file mode 100644 index 00000000..ca6bc37b --- /dev/null +++ b/OSX/sec/securityd/SFKeychainServer.m @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "SFKeychainServer.h" +#import + +#if !TARGET_OS_BRIDGE +#if __OBJC2__ + +#import "SecCDKeychain.h" +#import "SecFileLocations.h" +#import "debugging.h" +#import "CloudKitCategories.h" +#import "SecAKSWrappers.h" +#include "securityd_client.h" +#import "server_entitlement_helpers.h" +#import "SecTask.h" +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "SecEntitlements.h" +#import +#import +#import +#import +#import + +static NSString* const SFKeychainItemAttributeLocalizedLabel = @"label"; +static NSString* const SFKeychainItemAttributeLocalizedDescription = @"description"; + +static NSString* const SFCredentialAttributeUsername = @"username"; +static NSString* const SFCredentialAttributePrimaryServiceIdentifier = @"primaryServiceID"; +static NSString* const SFCredentialAttributeSupplementaryServiceIdentifiers = @"supplementaryServiceIDs"; +static NSString* const SFCredentialAttributeCreationDate = @"creationDate"; +static NSString* const SFCredentialAttributeModificationDate = @"modificationDate"; +static NSString* const SFCredentialAttributeCustom = @"customAttributes"; +static NSString* const SFCredentialSecretPassword = @"password"; + +@interface SFCredential (securityd_only) + +- (instancetype)_initWithUsername:(NSString*)username primaryServiceIdentifier:(SFServiceIdentifier*)primaryServiceIdentifier supplementaryServiceIdentifiers:(nullable NSArray*)supplementaryServiceIdentifiers; + +@end + +@interface SFKeychainServerConnection () + +- (instancetype)initWithKeychain:(SecCDKeychain*)keychain xpcConnection:(NSXPCConnection*)connection; + +@end + +@implementation SecCDKeychainItemTypeCredential + ++ (instancetype)itemType +{ + static SecCDKeychainItemTypeCredential* itemType = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + itemType = [[self alloc] _initWithName:@"Credential" version:1 primaryKeys:@[SFCredentialAttributeUsername, SFCredentialAttributePrimaryServiceIdentifier] syncableKeys:nil]; + }); + + return itemType; +} + +@end + +@implementation SFKeychainServer { + SecCDKeychain* _keychain; +} + +- (instancetype)initWithStorageURL:(NSURL*)persistentStoreURL modelURL:(NSURL*)managedObjectURL encryptDatabase:(bool)encryptDatabase +{ + if (self = [super init]) { + _keychain = [[SecCDKeychain alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectURL encryptDatabase:encryptDatabase]; + } + + return self; +} + +- (BOOL)listener:(NSXPCListener*)listener shouldAcceptNewConnection:(NSXPCConnection*)newConnection +{ + NSNumber* keychainDenyEntitlement = [newConnection valueForEntitlement:(__bridge NSString*)kSecEntitlementKeychainDeny]; + if ([keychainDenyEntitlement isKindOfClass:[NSNumber class]] && keychainDenyEntitlement.boolValue == YES) { + secerror("SFKeychainServer: connection denied due to entitlement %@", kSecEntitlementKeychainDeny); + return NO; + } + + // wait a bit for shared function from SecurityFoundation to get to SDK, then addopt that + NSXPCInterface* interface = [NSXPCInterface interfaceWithProtocol:@protocol(SFKeychainServerProtocol)]; + [interface setClasses:[NSSet setWithObjects:[NSArray class], [SFServiceIdentifier class], nil] forSelector:@selector(rpcLookupCredentialsForServiceIdentifiers:reply:) argumentIndex:0 ofReply:NO]; + [interface setClasses:[NSSet setWithObjects:[NSArray class], [SFPasswordCredential class], nil] forSelector:@selector(rpcLookupCredentialsForServiceIdentifiers:reply:) argumentIndex:0 ofReply:YES]; + newConnection.exportedInterface = interface; + newConnection.exportedObject = [[SFKeychainServerConnection alloc] initWithKeychain:_keychain xpcConnection:newConnection]; + [newConnection resume]; + return YES; +} + +- (SecCDKeychain*)_keychain +{ + return _keychain; +} + +@end + +@implementation SFKeychainServerConnection { + SecCDKeychain* _keychain; + NSArray* _clientAccessGroups; +} + +@synthesize clientAccessGroups = _clientAccessGroups; + +- (instancetype)initWithKeychain:(SecCDKeychain*)keychain xpcConnection:(NSXPCConnection*)connection +{ + if (self = [super init]) { + _keychain = keychain; + + SecTaskRef task = SecTaskCreateWithAuditToken(NULL, connection.auditToken); + if (task) { + _clientAccessGroups = (__bridge_transfer NSArray*)SecTaskCopyAccessGroups(task); + } + CFReleaseNull(task); + } + + return self; +} + +- (keyclass_t)keyclassForAccessPolicy:(SFAccessPolicy*)accessPolicy +{ + if (accessPolicy.accessibility.mode == SFAccessibleAfterFirstUnlock) { + if (accessPolicy.sharingPolicy == SFSharingPolicyThisDeviceOnly) { + return key_class_cku; + } + else { + return key_class_ck; + } + } + else { + if (accessPolicy.sharingPolicy == SFSharingPolicyThisDeviceOnly) { + return key_class_aku; + } + else { + return key_class_ak; + } + } +} + +- (void)rpcAddCredential:(SFCredential*)credential withAccessPolicy:(SFAccessPolicy*)accessPolicy reply:(void (^)(NSString* persistentIdentifier, NSError* error))reply +{ + if (![credential isKindOfClass:[SFPasswordCredential class]]) { + reply(nil, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInvalidParameter userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"attempt to add credential to SFCredentialStore that is not a password credential: %@", credential]}]); + return; + } + + NSString* accessGroup = accessPolicy.accessGroup; + if (!accessGroup) { + NSError* error = nil; + accessGroup = self.clientAccessGroups.firstObject; + if (!accessGroup) { + error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorMissingAccessGroup userInfo:@{NSLocalizedDescriptionKey : @"no keychain access group found; ensure that your process has the keychain-access-groups entitlement"}]; + reply(nil, error); + return; + } + } + + SFPasswordCredential* passwordCredential = (SFPasswordCredential*)credential; + + NSError* error = nil; + NSData* primaryServiceIdentifierData = [NSKeyedArchiver archivedDataWithRootObject:passwordCredential.primaryServiceIdentifier requiringSecureCoding:YES error:&error]; + if (!primaryServiceIdentifierData) { + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + reply(nil, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSaveFailed userInfo:@{ NSLocalizedDescriptionKey : @"failed to serialize primary service identifier", NSUnderlyingErrorKey : error }]); + }); + return; + } + + NSMutableArray* serializedSupplementaryServiceIdentifiers = [[NSMutableArray alloc] initWithCapacity:passwordCredential.supplementaryServiceIdentifiers.count]; + for (SFServiceIdentifier* serviceIdentifier in passwordCredential.supplementaryServiceIdentifiers) { + NSData* serviceIdentifierData = [NSKeyedArchiver archivedDataWithRootObject:serviceIdentifier requiringSecureCoding:YES error:&error]; + if (serviceIdentifierData) { + [serializedSupplementaryServiceIdentifiers addObject:serviceIdentifierData]; + } + else { + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + reply(nil, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSaveFailed userInfo:@{ NSLocalizedDescriptionKey : @"failed to serialize supplementary service identifier", NSUnderlyingErrorKey : error }]); + }); + return; + } + } + + NSDictionary* attributes = @{ SFCredentialAttributeUsername : passwordCredential.username, + SFCredentialAttributePrimaryServiceIdentifier : primaryServiceIdentifierData, + SFCredentialAttributeSupplementaryServiceIdentifiers : serializedSupplementaryServiceIdentifiers, + SFCredentialAttributeCreationDate : [NSDate date], + SFCredentialAttributeModificationDate : [NSDate date], + SFKeychainItemAttributeLocalizedLabel : passwordCredential.localizedLabel, + SFKeychainItemAttributeLocalizedDescription : passwordCredential.localizedDescription, + SFCredentialAttributeCustom : passwordCredential.customAttributes ?: [NSDictionary dictionary] }; + + NSDictionary* secrets = @{ SFCredentialSecretPassword : passwordCredential.password }; + NSUUID* persistentID = [NSUUID UUID]; + + // lookup attributes: + // 1. primaryServiceIdentifier (always) + // 2. username (always) + // 3. label (if present) + // 4. description (if present) + // 5. each of the service identifiers by type, e.g. "domain" + // 6. any custom attributes that fit the requirements (key is string, and value is plist type) + + SecCDKeychainLookupTuple* primaryServiceIdentifierLookup = [SecCDKeychainLookupTuple lookupTupleWithKey:SFCredentialAttributePrimaryServiceIdentifier value:primaryServiceIdentifierData]; + SecCDKeychainLookupTuple* usernameLookup = [SecCDKeychainLookupTuple lookupTupleWithKey:SFCredentialAttributeUsername value:passwordCredential.username]; + SecCDKeychainLookupTuple* labelLookup = [SecCDKeychainLookupTuple lookupTupleWithKey:SFKeychainItemAttributeLocalizedLabel value:passwordCredential.localizedLabel]; + SecCDKeychainLookupTuple* descriptionLookup = [SecCDKeychainLookupTuple lookupTupleWithKey:SFKeychainItemAttributeLocalizedDescription value:passwordCredential.localizedDescription]; + NSMutableArray* lookupAttributes = [[NSMutableArray alloc] initWithObjects:primaryServiceIdentifierLookup, usernameLookup, nil]; + if (labelLookup) { + [lookupAttributes addObject:labelLookup]; + } + if (descriptionLookup) { + [lookupAttributes addObject:descriptionLookup]; + } + + SFServiceIdentifier* primaryServiceIdentifier = credential.primaryServiceIdentifier; + [lookupAttributes addObject:[SecCDKeychainLookupTuple lookupTupleWithKey:primaryServiceIdentifier.lookupKey value:primaryServiceIdentifier.serviceID]]; + for (SFServiceIdentifier* serviceIdentifier in credential.supplementaryServiceIdentifiers) { + [lookupAttributes addObject:[SecCDKeychainLookupTuple lookupTupleWithKey:serviceIdentifier.lookupKey value:serviceIdentifier.serviceID]]; + } + + [passwordCredential.customAttributes enumerateKeysAndObjectsUsingBlock:^(NSString* customKey, id value, BOOL* stop) { + if ([customKey isKindOfClass:[NSString class]]) { + SecCDKeychainLookupTuple* lookupTuple = [SecCDKeychainLookupTuple lookupTupleWithKey:customKey value:value]; + if (lookupTuple) { + [lookupAttributes addObject:lookupTuple]; + } + else { + // TODO: an error here? + } + } + }]; + + SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:accessGroup]; + keyclass_t keyclass = [self keyclassForAccessPolicy:accessPolicy]; + SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[SecCDKeychainItemTypeCredential itemType] withPersistentID:persistentID attributes:attributes lookupAttributes:lookupAttributes secrets:secrets owner:owner keyclass:keyclass]; + [_keychain insertItems:@[item] withConnection:self completionHandler:^(bool success, NSError* error) { + if (success && !error) { + reply(persistentID.UUIDString, nil); + } + else { + reply(nil, error); + } + }]; +} + +- (void)rpcFetchPasswordCredentialForPersistentIdentifier:(NSString*)persistentIdentifier reply:(void (^)(SFPasswordCredential* credential, NSString* password, NSError* error))reply +{ + // TODO: negative testing + NSUUID* persistentID = [[NSUUID alloc] initWithUUIDString:persistentIdentifier]; + if (!persistentID) { + secerror("SFKeychainServer: attempt to fetch credential with invalid persistent identifier; %@", persistentIdentifier); + reply(nil, nil, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInvalidPersistentIdentifier userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"invalid persistent identifier: %@", persistentIdentifier]}]); + return; + } + + [_keychain fetchItemForPersistentID:persistentID withConnection:self completionHandler:^(SecCDKeychainItem* item, NSError* error) { + NSError* localError = error; + SFPasswordCredential* credential = nil; + if (item && !error) { + credential = [self passwordCredentialForItem:item error:&localError]; + } + + if (credential) { + reply(credential, credential.password, nil); + } + else { + reply(nil, nil, localError); + } + }]; +} + +- (void)rpcLookupCredentialsForServiceIdentifiers:(nullable NSArray*)serviceIdentifiers reply:(void (^)(NSArray* _Nullable results, NSError* _Nullable error))reply +{ + __block NSMutableDictionary* resultsDict = [[NSMutableDictionary alloc] init]; + __block NSError* resultError = nil; + + void (^processFetchedItems)(NSArray*) = ^(NSArray* fetchedItems) { + for (SecCDKeychainItemMetadata* item in fetchedItems) { + if ([item.itemType isKindOfClass:[SecCDKeychainItemTypeCredential class]]) { + SFPasswordCredential* credential = [self passwordCredentialForItemMetadata:item error:&resultError]; + if (credential) { + resultsDict[item.persistentID] = credential; + } + else { + resultsDict = nil; // got an error + } + } + } + }; + + if (!serviceIdentifiers) { + // TODO: lookup everything + } + else { + for (SFServiceIdentifier* serviceIdentifier in serviceIdentifiers) { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + // TODO: this is lamé; make fetchItemsWithValue take an array and get rid of the semaphore crap + [_keychain fetchItemsWithValue:serviceIdentifier.serviceID forLookupKey:serviceIdentifier.lookupKey ofType:SecCDKeychainLookupValueTypeString withConnection:self completionHandler:^(NSArray* items, NSError* error) { + if (items && !error) { + processFetchedItems(items); + } + else { + resultsDict = nil; + resultError = error; + } + + dispatch_semaphore_signal(semaphore); + }]; + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + } + } + + reply(resultsDict.allValues, resultError); +} + +- (void)rpcRemoveCredentialWithPersistentIdentifier:(NSString*)persistentIdentifier reply:(void (^)(BOOL success, NSError* _Nullable error))reply +{ + NSUUID* persistentID = [[NSUUID alloc] initWithUUIDString:persistentIdentifier]; + if (!persistentID) { + secerror("SFKeychainServer: attempt to remove credential with invalid persistent identifier; %@", persistentIdentifier); + reply(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInvalidPersistentIdentifier userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"invalid persistent identifier: %@", persistentIdentifier]}]); + return; + } + + [_keychain deleteItemWithPersistentID:persistentID withConnection:self completionHandler:^(bool success, NSError* error) { + reply(success, error); + }]; +} + +- (void)rpcReplaceOldCredential:(SFCredential*)oldCredential withNewCredential:(SFCredential*)newCredential reply:(void (^)(NSString* newPersistentIdentifier, NSError* _Nullable error))reply +{ + // TODO: implement + reply(nil, nil); +} + +- (SFPasswordCredential*)passwordCredentialForItem:(SecCDKeychainItem*)item error:(NSError**)error +{ + SFPasswordCredential* credential = [self passwordCredentialForItemMetadata:item.metadata error:error]; + if (credential) { + credential.password = item.secrets[SFCredentialSecretPassword]; + if (!credential.password) { + if (error) { + *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSecureDecodeFailed userInfo:@{NSLocalizedDescriptionKey : @"failed to get password for SFCredential"}]; + } + return nil; + } + } + + return credential; +} + +- (SFPasswordCredential*)passwordCredentialForItemMetadata:(SecCDKeychainItemMetadata*)metadata error:(NSError**)error +{ + NSDictionary* attributes = metadata.attributes; + NSString* username = attributes[SFCredentialAttributeUsername]; + + NSError* localError = nil; + SFServiceIdentifier* primaryServiceIdentifier = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFServiceIdentifier class] fromData:attributes[SFCredentialAttributePrimaryServiceIdentifier] error:&localError]; + + NSArray* serializedSupplementaryServiceIdentifiers = attributes[SFCredentialAttributeSupplementaryServiceIdentifiers]; + NSMutableArray* supplementaryServiceIdentifiers = [[NSMutableArray alloc] initWithCapacity:serializedSupplementaryServiceIdentifiers.count]; + for (NSData* serializedServiceIdentifier in serializedSupplementaryServiceIdentifiers) { + if ([serializedServiceIdentifier isKindOfClass:[NSData class]]) { + SFServiceIdentifier* serviceIdentifier = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFServiceIdentifier class] fromData:serializedServiceIdentifier error:&localError]; + if (serviceIdentifier) { + [supplementaryServiceIdentifiers addObject:serviceIdentifier]; + } + else { + supplementaryServiceIdentifiers = nil; + break; + } + } + else { + supplementaryServiceIdentifiers = nil; + localError = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSecureDecodeFailed userInfo:@{NSLocalizedDescriptionKey : @"malformed supplementary service identifiers array in SecCDKeychainItem"}]; + break; + } + } + + if (username && primaryServiceIdentifier && supplementaryServiceIdentifiers) { + SFPasswordCredential* credential = [[SFPasswordCredential alloc] _initWithUsername:username primaryServiceIdentifier:primaryServiceIdentifier supplementaryServiceIdentifiers:supplementaryServiceIdentifiers]; + credential.creationDate = attributes[SFCredentialAttributeCreationDate]; + credential.modificationDate = attributes[SFCredentialAttributeModificationDate]; + credential.localizedLabel = attributes[SFKeychainItemAttributeLocalizedLabel]; + credential.localizedDescription = attributes[SFKeychainItemAttributeLocalizedDescription]; + credential.persistentIdentifier = metadata.persistentID.UUIDString; + credential.customAttributes = attributes[SFCredentialAttributeCustom]; + return credential; + } + else { + if (error) { + *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSecureDecodeFailed userInfo:@{ NSLocalizedDescriptionKey : @"failed to deserialize SFCredential", NSUnderlyingErrorKey : localError }]; + } + return nil; + } +} + +@end + +#endif // ___OBJC2__ + +void SFKeychainServerInitialize(void) +{ + static dispatch_once_t once; + static SFKeychainServer* server; + static NSXPCListener* listener; + + dispatch_once(&once, ^{ + @autoreleasepool { + NSURL* persistentStoreURL = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"CDKeychain"); + NSBundle* resourcesBundle = [NSBundle bundleWithPath:@"/System/Library/Keychain/KeychainResources.bundle"]; + NSURL* managedObjectModelURL = [resourcesBundle URLForResource:@"KeychainModel" withExtension:@"momd"]; + server = [[SFKeychainServer alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectModelURL encryptDatabase:true]; + listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSFKeychainServerServiceName)]; + listener.delegate = server; + [listener resume]; + } + }); +} + +#else // !TARGET_OS_BRIDGE + +void SFKeychainServerInitialize(void) {} + +#endif + diff --git a/OSX/sec/securityd/SOSCloudCircleServer.h b/OSX/sec/securityd/SOSCloudCircleServer.h index 81340ab4..5d49f88f 100644 --- a/OSX/sec/securityd/SOSCloudCircleServer.h +++ b/OSX/sec/securityd/SOSCloudCircleServer.h @@ -38,25 +38,21 @@ __BEGIN_DECLS bool SOSCCTryUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); bool SOSCCSetUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error); bool SOSCCSetUserCredentialsAndDSID_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); +bool SOSCCSetUserCredentialsAndDSIDWithAnalytics_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error); bool SOSCCCanAuthenticate_Server(CFErrorRef *error); bool SOSCCPurgeUserCredentials_Server(CFErrorRef *error); SOSCCStatus SOSCCThisDeviceIsInCircle_Server(CFErrorRef *error); bool SOSCCRequestToJoinCircle_Server(CFErrorRef* error); +bool SOSCCRequestToJoinCircleWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error); bool SOSCCRequestToJoinCircleAfterRestore_Server(CFErrorRef* error); -CFStringRef SOSCCCopyDeviceID_Server(CFErrorRef *error); -bool SOSCCSetDeviceID_Server(CFStringRef IDS, CFErrorRef *error); -HandleIDSMessageReason SOSCCHandleIDSMessage_Server(CFDictionaryRef messageDict, CFErrorRef* error); -bool SOSCCRequestSyncWithPeerOverKVS_Server(CFStringRef peerID, CFDataRef message, CFErrorRef *error); -bool SOSCCClearPeerMessageKeyInKVS_Server(CFStringRef peerID, CFErrorRef *error); - -bool SOSCCIDSServiceRegistrationTest_Server(CFStringRef message, CFErrorRef *error); -bool SOSCCIDSPingTest_Server(CFStringRef message, CFErrorRef *error); -bool SOSCCIDSDeviceIDIsAvailableTest_Server(CFErrorRef *error); +bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error); bool SOSCCRemoveThisDeviceFromCircle_Server(CFErrorRef* error); +bool SOSCCRemoveThisDeviceFromCircleWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error); bool SOSCCRemovePeersFromCircle_Server(CFArrayRef peers, CFErrorRef* error); +bool SOSCCRemovePeersFromCircleWithAnalytics_Server(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error); bool SOSCCLoggedOutOfAccount_Server(CFErrorRef *error); bool SOSCCBailFromCircle_Server(uint64_t limit_in_seconds, CFErrorRef* error); bool SOSCCRequestEnsureFreshParameters_Server(CFErrorRef* error); @@ -85,20 +81,19 @@ CFArrayRef SOSCCCopyEngineState_Server(CFErrorRef* error); CFArrayRef SOSCCCopyPeerPeerInfo_Server(CFErrorRef* error); CFArrayRef SOSCCCopyConcurringPeerPeerInfo_Server(CFErrorRef* error); -bool SOSCCCheckPeerAvailability_Server(CFErrorRef *error); bool SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(CFErrorRef *error); bool SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(CFErrorRef *error); bool SOSCCAccountSetToNew_Server(CFErrorRef *error); bool SOSCCResetToOffering_Server(CFErrorRef* error); bool SOSCCResetToEmpty_Server(CFErrorRef* error); +bool SOSCCResetToEmptyWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error); CFBooleanRef SOSCCPeersHaveViewsEnabled_Server(CFArrayRef viewNames, CFErrorRef *error); SOSViewResultCode SOSCCView_Server(CFStringRef view, SOSViewActionCode action, CFErrorRef *error); +bool SOSCCViewSetWithAnalytics_Server(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent); bool SOSCCViewSet_Server(CFSetRef enabledView, CFSetRef disabledViews); -SOSSecurityPropertyResultCode SOSCCSecurityProperty_Server(CFStringRef property, SOSSecurityPropertyActionCode action, CFErrorRef *error); - CFStringRef SOSCCCopyIncompatibilityInfo_Server(CFErrorRef* error); enum DepartureReason SOSCCGetLastDepartureReason_Server(CFErrorRef* error); bool SOSCCSetLastDepartureReason_Server(enum DepartureReason reason, CFErrorRef *error); @@ -107,12 +102,12 @@ bool SOSCCProcessEnsurePeerRegistration_Server(CFErrorRef* error); CF_RETURNS_RETAINED CFSetRef SOSCCProcessSyncWithPeers_Server(CFSetRef peers, CFSetRef backupPeers, CFErrorRef *error); SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers_Server(CFErrorRef* error); -bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly_Server(CFStringRef deviceID, CFErrorRef *error); SOSPeerInfoRef SOSCCSetNewPublicBackupKey_Server(CFDataRef newPublicBackup, CFErrorRef *error); bool SOSCCRegisterSingleRecoverySecret_Server(CFDataRef backupSlice, bool setupV0Only, CFErrorRef *error); bool SOSCCWaitForInitialSync_Server(CFErrorRef*); +bool SOSCCWaitForInitialSyncWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error); CFArrayRef SOSCCCopyYetToSyncViewsList_Server(CFErrorRef*); bool SOSWrapToBackupSliceKeyBagForView_Server(CFStringRef viewName, CFDataRef input, CFDataRef* output, CFDataRef* bskbEncoded, CFErrorRef* error); @@ -131,7 +126,6 @@ void SOSCCRequestSyncWithPeer(CFStringRef peerID); void SOSCCRequestSyncWithPeers(CFSetRef /*SOSPeerInfoRef/CFStringRef*/ peerIDs); void SOSCCRequestSyncWithPeersList(CFArrayRef /*CFStringRef*/ peerIDs); void SOSCCRequestSyncWithBackupPeer(CFStringRef backupPeerId); - bool SOSCCIsSyncPendingFor(CFStringRef peerID, CFErrorRef *error); void SOSCCEnsurePeerRegistration(void); @@ -148,7 +142,9 @@ CFTypeRef SOSKeychainAccountGetSharedAccount(void); // // MARK: Internal SPIs for testing // -CFStringRef CopyOSVersion(void); + +void SOSCCSetGestalt_Server(CFStringRef name, CFStringRef version, CFStringRef model, CFStringRef serial); +CFStringRef SOSCCCopyOSVersion(void); CFDataRef SOSCCCopyAccountState_Server(CFErrorRef* error); CFDataRef SOSCCCopyEngineData_Server(CFErrorRef* error); bool SOSCCDeleteEngineState_Server(CFErrorRef* error); diff --git a/OSX/sec/securityd/SOSCloudCircleServer.m b/OSX/sec/securityd/SOSCloudCircleServer.m index 877a82a7..d90097fb 100644 --- a/OSX/sec/securityd/SOSCloudCircleServer.m +++ b/OSX/sec/securityd/SOSCloudCircleServer.m @@ -23,7 +23,8 @@ #include -#include +#include +#include #include @@ -34,10 +35,10 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -48,6 +49,8 @@ #import #import #import +#import + #include #include @@ -101,7 +104,7 @@ static int64_t getTimeDifference(time_t start); CFStringRef const SOSAggdSyncCompletionKey = CFSTR("com.apple.security.sos.synccompletion"); CFStringRef const SOSAggdSyncTimeoutKey = CFSTR("com.apple.security.sos.timeout"); -typedef SOSDataSourceFactoryRef (^SOSCCAccountDataSourceFactoryBlock)(); +typedef SOSDataSourceFactoryRef (^SOSCCAccountDataSourceFactoryBlock)(void); static SOSCCAccountDataSourceFactoryBlock accountDataSourceOverride = NULL; @@ -256,59 +259,71 @@ done: // Mark: Gestalt Handling // -CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void); -CF_EXPORT CFStringRef _kCFSystemVersionBuildVersionKey; +CFStringRef SOSGestaltVersion = NULL; +CFStringRef SOSGestaltModel = NULL; +CFStringRef SOSGestaltDeviceName = NULL; -CFStringRef CopyOSVersion(void) +void +SOSCCSetGestalt_Server(CFStringRef deviceName, + CFStringRef version, + CFStringRef model, + CFStringRef serial) +{ + SOSGestaltDeviceName = CFRetainSafe(deviceName); + SOSGestaltVersion = CFRetainSafe(version); + SOSGestaltModel = CFRetainSafe(model); + SOSGestaltSerial = CFRetainSafe(serial); +} + +CFStringRef SOSCCCopyOSVersion(void) { static dispatch_once_t once; - static CFStringRef osVersion = NULL; dispatch_once(&once, ^{ -#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR - osVersion = MGCopyAnswer(kMGQBuildVersion, NULL); -#else - CFDictionaryRef versions = _CFCopySystemVersionDictionary(); - - if (versions) { - CFTypeRef versionValue = CFDictionaryGetValue(versions, _kCFSystemVersionBuildVersionKey); + if (SOSGestaltVersion == NULL) { + CFDictionaryRef versions = _CFCopySystemVersionDictionary(); + if (versions) { + CFTypeRef versionValue = CFDictionaryGetValue(versions, _kCFSystemVersionBuildVersionKey); + if (isString(versionValue)) + SOSGestaltVersion = CFRetainSafe((CFStringRef) versionValue); + } - if (isString(versionValue)) - osVersion = CFRetainSafe((CFStringRef) versionValue); + CFReleaseNull(versions); + if (SOSGestaltVersion == NULL) { + SOSGestaltVersion = CFSTR("Unknown model"); + } } - - CFReleaseNull(versions); -#endif - // What to do on MacOS. - if (osVersion == NULL) - osVersion = CFSTR("Unknown model"); }); - return CFRetainSafe(osVersion); + return CFRetainSafe(SOSGestaltVersion); } static CFStringRef CopyModelName(void) { static dispatch_once_t once; - static CFStringRef modelName = NULL; dispatch_once(&once, ^{ + if (SOSGestaltModel == NULL) { #if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR - modelName = MGCopyAnswer(kMGQDeviceName, NULL); + SOSGestaltModel = MGCopyAnswer(kMGQDeviceName, NULL); #else - modelName = ASI_CopyComputerModelName(FALSE); + SOSGestaltModel = ASI_CopyComputerModelName(FALSE); #endif - if (modelName == NULL) - modelName = CFSTR("Unknown model"); + if (SOSGestaltModel == NULL) + SOSGestaltModel = CFSTR("Unknown model"); + } }); - return CFStringCreateCopy(kCFAllocatorDefault, modelName); + return CFStringCreateCopy(kCFAllocatorDefault, SOSGestaltModel); } static CFStringRef CopyComputerName(SCDynamicStoreRef store) { - CFStringRef deviceName = SCDynamicStoreCopyComputerName(store, NULL); - if (deviceName == NULL) { - deviceName = CFSTR("Unknown name"); + if (SOSGestaltDeviceName == NULL) { + CFStringRef deviceName = SCDynamicStoreCopyComputerName(store, NULL); + if (deviceName == NULL) { + deviceName = CFSTR("Unknown name"); + } + return deviceName; } - return deviceName; + return SOSGestaltDeviceName; } static bool _EngineMessageProtocolV2Enabled(void) @@ -338,7 +353,7 @@ static CFDictionaryRef CreateDeviceGestaltDictionary(SCDynamicStoreRef store, CF { CFStringRef modelName = CopyModelName(); CFStringRef computerName = CopyComputerName(store); - CFStringRef osVersion = CopyOSVersion(); + CFStringRef osVersion = SOSCCCopyOSVersion(); SInt32 version = _EngineMessageProtocolV2Enabled() ? kEngineMessageProtocolVersion : 0; CFNumberRef protocolVersion = CFNumberCreate(0, kCFNumberSInt32Type, &version); @@ -363,7 +378,6 @@ static void SOSCCProcessGestaltUpdate(SCDynamicStoreRef store, CFArrayRef keys, if(txn.account){ CFDictionaryRef gestalt = CreateDeviceGestaltDictionary(store, keys, context); if ([txn.account.trust updateGestalt:txn.account newGestalt:gestalt]) { - // we used to notify_post(kSOSCCCircleChangedNotification); secnotice("circleOps", "Changed our peer's gestalt information. This is not a circle change."); } CFReleaseSafe(gestalt); @@ -450,11 +464,11 @@ static SOSAccount* GetSharedAccount(void) { sSharedAccount = SOSKeychainAccountCreateSharedAccount(gestalt); - SOSAccountAddChangeBlock(sSharedAccount, ^(SOSCircleRef circle, + SOSAccountAddChangeBlock(sSharedAccount, ^(SOSAccount *account, SOSCircleRef circle, CFSetRef peer_additions, CFSetRef peer_removals, CFSetRef applicant_additions, CFSetRef applicant_removals) { CFErrorRef pi_error = NULL; - SOSPeerInfoRef me = sSharedAccount.peerInfo; + SOSPeerInfoRef me = account.peerInfo; if(!me) { secinfo("circleOps", "Change block called with no peerInfo"); return; @@ -498,14 +512,14 @@ static SOSAccount* GetSharedAccount(void) { CFSetForEach(peer_removals, ^(const void *value) { CFArrayAppendValue(removed, value); }); - SOSAccountRemoveBackupPeers(sSharedAccount, removed, &localError); + SOSAccountRemoveBackupPeers(account, removed, &localError); if(localError) secerror("Had trouble removing: %@, error: %@", removed, localError); CFReleaseNull(localError); CFReleaseNull(removed); } secnotice("circleOps", "peer counts changed, posting kSOSCCCircleChangedNotification"); - notify_post(kSOSCCCircleChangedNotification); + account.notifyCircleChangeOnExit = true; } }); @@ -620,8 +634,8 @@ static bool do_with_account_if_after_first_unlock(CFErrorRef *error, bool (^acti secerror("error getting circle status on first unlock: %@", cferror); } else if (status == kSOSCCInCircle) { secnotice("secdNotify", "Notified clients of kSOSCCCircleChangedNotification && kSOSCCViewMembershipChangedNotification for in-circle initial unlock"); - notify_post(kSOSCCCircleChangedNotification); - notify_post(kSOSCCViewMembershipChangedNotification); + txn.account.notifyCircleChangeOnExit = true; + txn.account.notifyViewChangeOnExit = true; } CFReleaseNull(cferror); }); @@ -657,6 +671,12 @@ static bool do_with_account_while_unlocked(CFErrorRef *error, bool (^action)(SOS result = SecAKSDoWhileUserBagLocked(&localError, ^{ do_with_account(^(SOSAccountTransaction* txn) { + SOSAccount *account = txn.account; + if(![SOSAuthKitHelpers peerinfoHasMID: account]) { + // This is the first good opportunity to update our FullPeerInfo and + // push the resulting circle. + [SOSAuthKitHelpers updateMIDInPeerInfo: account]; + } attempted_action = true; action_result = action(txn, error); }); @@ -674,7 +694,7 @@ static bool do_with_account_while_unlocked(CFErrorRef *error, bool (^action)(SOS CFReleaseNull(localError); CFReleaseNull(statusError); - return result; + return (result && action_result); } if(attempted_action){ if (error && !*error && localError) { @@ -775,39 +795,27 @@ SOSViewResultCode SOSCCView_Server(CFStringRef viewname, SOSViewActionCode actio return status; } - -bool SOSCCViewSet_Server(CFSetRef enabledViews, CFSetRef disabledViews) { +bool SOSCCViewSetWithAnalytics_Server(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent) { __block bool status = false; - + do_with_account_if_after_first_unlock(NULL, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - status = [txn.account.trust updateViewSets:txn.account enabled:enabledViews disabled:disabledViews]; + status = [txn.account.trust updateViewSetsWithAnalytics:txn.account enabled:enabledViews disabled:disabledViews parentEvent:(__bridge NSData*)parentEvent]; return true; }); return status; } -SOSSecurityPropertyResultCode SOSCCSecurityProperty_Server(CFStringRef property, SOSSecurityPropertyActionCode action, CFErrorRef *error) { +bool SOSCCViewSet_Server(CFSetRef enabledViews, CFSetRef disabledViews) { + __block bool status = false; - __block SOSViewResultCode status = kSOSCCGeneralSecurityPropertyError; - do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - switch(action) { - case kSOSCCSecurityPropertyQuery: - status = [txn.account.trust SecurityPropertyStatus:property err:error]; - break; - case kSOSCCSecurityPropertyEnable: - case kSOSCCSecurityPropertyDisable: // fallthrough - status = [txn.account.trust UpdateSecurityProperty:txn.account property:property code:action err:error]; - break; - default: - secnotice("secprop", "Bad SOSSecurityPropertyActionCode - %d", (int) action); - return false; - break; - } + do_with_account_if_after_first_unlock(NULL, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + status = [txn.account.trust updateViewSets:txn.account enabled:enabledViews disabled:disabledViews]; return true; }); return status; } + void sync_the_last_data_to_kvs(CFTypeRef account, bool waitForeverForSynchronization){ dispatch_semaphore_t wait_for = dispatch_semaphore_create(0); @@ -913,12 +921,75 @@ done: return result; } +static bool SOSCCAssertUserCredentialsAndOptionalDSIDWithAnalytics(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, NSData* parentEvent, CFErrorRef *error) { + secnotice("updates", "Setting credentials and dsid (%@) for %@", dsid, user_label); + + NSError* localError = nil; + SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + + SFSignInAnalytics *syncAndWaitEvent = nil; + SFSignInAnalytics *flushEvent = nil; + SFSignInAnalytics *secondFlushEvent = nil; + SFSignInAnalytics *generationSignatureUpdateEvent = nil; + + bool result = do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + if (dsid != NULL && CFStringCompare(dsid, CFSTR(""), 0) != 0) { + SOSAccountAssertDSID(txn.account, dsid); + } + return true; + }); + + require_quiet(result, done); + syncAndWaitEvent = [parent newSubTaskForEvent:@"syncAndWaitEvent"]; + require_quiet(SyncKVSAndWait(error), done); // Make sure we've seen what the server has + [syncAndWaitEvent stopWithAttributes:nil]; + + flushEvent = [parent newSubTaskForEvent:@"flushEvent"]; + require_quiet(Flush(error), done); // And processed it already...before asserting + [flushEvent stopWithAttributes:nil]; + + result = do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *block_error) { + return SOSAccountAssertUserCredentials(txn.account, user_label, user_password, block_error); + }); + + require_quiet(result, done); + secondFlushEvent = [parent newSubTaskForEvent:@"secondFlushEvent"]; + require_quiet(Flush(error), done); // Process any incoming information..circles et.al. before fixing our signature + [secondFlushEvent stopWithAttributes:nil]; + + generationSignatureUpdateEvent = [parent newSubTaskForEvent:@"generationSignatureUpdateEvent"]; + result = do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + return SOSAccountGenerationSignatureUpdate(txn.account, error); + }); + [generationSignatureUpdateEvent stopWithAttributes:nil]; + + +done: + if(syncAndWaitEvent){ + [syncAndWaitEvent stopWithAttributes:nil]; + } + if(flushEvent){ + [flushEvent stopWithAttributes:nil]; + } + if(secondFlushEvent){ + [secondFlushEvent stopWithAttributes:nil]; + } + if(generationSignatureUpdateEvent){ + [generationSignatureUpdateEvent stopWithAttributes:nil]; + } + return result; +} + bool SOSCCSetUserCredentialsAndDSID_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) { // TODO: Return error if DSID is NULL to insist our callers provide one? return SOSCCAssertUserCredentialsAndOptionalDSID(user_label, user_password, dsid, error); } +bool SOSCCSetUserCredentialsAndDSIDWithAnalytics_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error) +{ + return SOSCCAssertUserCredentialsAndOptionalDSIDWithAnalytics(user_label, user_password, dsid, (__bridge NSData*)parentEvent, error); +} bool SOSCCSetUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error) { return SOSCCAssertUserCredentialsAndOptionalDSID(user_label, user_password, NULL, error); @@ -972,6 +1043,16 @@ bool SOSCCRequestToJoinCircle_Server(CFErrorRef* error) }); } +bool SOSCCRequestToJoinCircleWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error) +{ + __block bool result = true; + + return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + result = SOSAccountJoinCirclesWithAnalytics(txn, (__bridge NSData*)parentEvent, block_error); + return result; + }); +} + bool SOSCCAccountHasPublicKey_Server(CFErrorRef *error) { __block bool result = true; @@ -1016,6 +1097,31 @@ bool SOSCCRequestToJoinCircleAfterRestore_Server(CFErrorRef* error) } +bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error) +{ + __block bool result = true; + bool returned = false; + returned = do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + NSError* localError = nil; + SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:(__bridge NSData*)parentEvent error:&localError]; + + SFSignInAnalytics *ensurePeerRegistrationEvent = [parent newSubTaskForEvent:@"ensurePeerRegistrationEvent"]; + SOSAccountEnsurePeerRegistration(txn.account, block_error); + if(block_error && *block_error){ + NSError* blockError = (__bridge NSError*)*block_error; + if(blockError){ + [ensurePeerRegistrationEvent logRecoverableError:blockError]; + secerror("ensure peer registration error: %@", blockError); + } + } + [ensurePeerRegistrationEvent stopWithAttributes:nil]; + result = SOSAccountJoinCirclesAfterRestoreWithAnalytics(txn, (__bridge NSData*)parentEvent, block_error); + return result; + }); + return returned; + +} + bool SOSCCRequestEnsureFreshParameters_Server(CFErrorRef* error) { bool returned = false; @@ -1109,94 +1215,6 @@ SOSRingStatus SOSCCRingStatus_Server(CFStringRef ringName, CFErrorRef *error){ return returned; } -CFStringRef SOSCCCopyDeviceID_Server(CFErrorRef *error) -{ - __block CFStringRef result = NULL; - - (void) do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) { - result = SOSAccountCopyDeviceID(txn.account, error); - return (!isNull(result)); - }); - return result; -} - -bool SOSCCSetDeviceID_Server(CFStringRef IDS, CFErrorRef *error){ - - return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - return SOSAccountSetMyDSID(txn, IDS, block_error); - }); -} - -bool SOSCCRequestSyncWithPeerOverKVS_Server(CFStringRef peerid, CFDataRef message, CFErrorRef *error) -{ - __block bool result = NULL; - - result = do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) { - return SOSAccountSyncWithKVSPeerWithMessage(txn, peerid, message, error); - }); - return result; -} - -HandleIDSMessageReason SOSCCHandleIDSMessage_Server(CFDictionaryRef messageDict, CFErrorRef* error) -{ - if (messageDict == NULL) { - return kHandleIDSMessageDontHandle; - } - - __block HandleIDSMessageReason result = kHandleIDSMessageSuccess; - CFErrorRef action_error = NULL; - - if (!do_with_account_while_unlocked(&action_error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - result = [txn.account.ids_message_transport SOSTransportMessageIDSHandleMessage:txn.account m:messageDict err:block_error]; - return true; - })) { - if (action_error) { - if(CFErrorIsMalfunctioningKeybagError(action_error)){ - secnotice("updates", "SOSCCHandleIDSMessage_Server failed because device is locked; letting KeychainSyncingOverIDSProxy know"); - result = kHandleIDSMessageLocked; // tell KeychainSyncingOverIDSProxy to call us back when device unlock - } else { - secerror("Unexpected error: %@", action_error); - } - - if (error && *error == NULL) { - *error = action_error; - action_error = NULL; - } - CFReleaseNull(action_error); - } - } - return result; -} - -bool SOSCCClearPeerMessageKeyInKVS_Server(CFStringRef peerID, CFErrorRef *error) -{ - __block bool result = false; - - result = do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) { - return SOSAccountClearPeerMessageKey(txn, peerID, error); - }); - - return result; -} - -bool SOSCCIDSPingTest_Server(CFStringRef message, CFErrorRef *error){ - return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - return SOSAccountStartPingTest(txn.account, message, block_error); - }); -} - -bool SOSCCIDSServiceRegistrationTest_Server(CFStringRef message, CFErrorRef *error){ - return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - return SOSAccountSendIDSTestMessage(txn.account, message, block_error); - }); -} - -bool SOSCCIDSDeviceIDIsAvailableTest_Server(CFErrorRef *error){ - return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - return SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(txn.account, block_error); - }); -} - bool SOSCCAccountSetToNew_Server(CFErrorRef *error) { return do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { @@ -1226,6 +1244,23 @@ bool SOSCCResetToEmpty_Server(CFErrorRef* error) } +bool SOSCCResetToEmptyWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error) +{ + return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + if (!SOSAccountHasPublicKey(txn.account, error)) + return false; + return [txn.account.trust resetAccountToEmptyWithAnalytics:txn.account transport:txn.account.circle_transport parentEvent:(__bridge NSData*)parentEvent err:block_error]; + }); + +} + +bool SOSCCRemoveThisDeviceFromCircleWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error) +{ + return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + return [txn.account.trust leaveCircleWithAccount:txn.account withAnalytics:(__bridge NSData*)parentEvent err:error]; + }); +} + bool SOSCCRemoveThisDeviceFromCircle_Server(CFErrorRef* error) { return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { @@ -1240,6 +1275,12 @@ bool SOSCCRemovePeersFromCircle_Server(CFArrayRef peers, CFErrorRef* error) }); } +bool SOSCCRemovePeersFromCircleWithAnalytics_Server(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error) +{ + return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + return SOSAccountRemovePeersFromCircleWithAnalytics(txn.account, peers, (__bridge NSData*)parentEvent, block_error); + }); +} bool SOSCCLoggedOutOfAccount_Server(CFErrorRef *error) { @@ -1405,6 +1446,101 @@ static uint64_t initialSyncTimeoutFromDefaultsWrite(void) return timeout; } +bool SOSCCWaitForInitialSyncWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error) { + __block dispatch_semaphore_t inSyncSema = NULL; + __block bool result = false; + __block bool synced = false; + bool timed_out = false; + __block CFStringRef inSyncCallID = NULL; + __block time_t start; + __block CFBooleanRef shouldUseInitialSyncV0 = false; + SFSignInAnalytics* syncingEvent = nil; + + NSError* localError = nil; + SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:(__bridge NSData*)parentEvent error:&localError]; + + secnotice("initial sync", "Wait for initial sync start!"); + + result = do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + shouldUseInitialSyncV0 = (CFBooleanRef)SOSAccountGetValue(txn.account, kSOSInitialSyncTimeoutV0, error); + bool alreadyInSync = (SOSAccountHasCompletedInitialSync(txn.account)); + + if (!alreadyInSync) { + txn.account.isInitialSyncing = true; + start = time(NULL); + inSyncSema = dispatch_semaphore_create(0); + + SFSignInAnalytics* callWhenInSyncEvent = [parent newSubTaskForEvent:@"callWhenInSync"]; + inSyncCallID = SOSAccountCallWhenInSync(txn.account, ^bool(SOSAccount* mightBeSynced) { + synced = true; + + if(inSyncSema){ + dispatch_semaphore_signal(inSyncSema); + NSDictionary* attributes = @{@"finishedSyncing" : @YES}; + [syncingEvent stopWithAttributes:attributes]; + } + return true; + }); + NSDictionary* attributes = @{}; + [callWhenInSyncEvent stopWithAttributes:attributes]; + } + else{ + synced = true; + } + return true; + }); + + require_quiet(result, fail); + + + if(inSyncSema){ + syncingEvent = [parent newSubTaskForEvent:@"initialSyncEvent"]; + if(shouldUseInitialSyncV0){ + secnotice("piggy","setting initial sync timeout to 5 minutes"); + timed_out = dispatch_semaphore_wait(inSyncSema, dispatch_time(DISPATCH_TIME_NOW, 300ull * NSEC_PER_SEC)); + } + else{ + uint64_t timeoutFromDefaultsWrite = initialSyncTimeoutFromDefaultsWrite(); + secnotice("piggy","setting initial sync timeout to %llu seconds", timeoutFromDefaultsWrite); + timed_out = dispatch_semaphore_wait(inSyncSema, dispatch_time(DISPATCH_TIME_NOW, timeoutFromDefaultsWrite * NSEC_PER_SEC)); + } + } + if (timed_out && shouldUseInitialSyncV0) { + do_with_account(^(SOSAccountTransaction* txn) { + if (SOSAccountUnregisterCallWhenInSync(txn.account, inSyncCallID)) { + if(inSyncSema){ + inSyncSema = NULL; // We've canceled the timeout so we must be the last. + } + } + }); + NSError* error = [NSError errorWithDomain:@"securityd" code:errSecTimedOut userInfo:@{NSLocalizedDescriptionKey: @"timed out waiting for initial sync"}]; + [syncingEvent logUnrecoverableError:error]; + NSDictionary* attributes = @{@"finishedSyncing" : @NO, @"legacyPiggybacking" : @YES}; + [syncingEvent stopWithAttributes:attributes]; + } + + require_quiet(result, fail); + + if(result) + { + SecADClientPushValueForDistributionKey(SOSAggdSyncCompletionKey, getTimeDifference(start)); + } + else if(!result) + { + SecADAddValueForScalarKey(SOSAggdSyncTimeoutKey, 1); + } + + (void)do_with_account(^(SOSAccountTransaction *txn) { + txn.account.isInitialSyncing = false; + }); + + secnotice("initial sync", "Finished!: %d", result); + +fail: + CFReleaseNull(inSyncCallID); + return result; +} + bool SOSCCWaitForInitialSync_Server(CFErrorRef* error) { __block dispatch_semaphore_t inSyncSema = NULL; @@ -1849,62 +1985,6 @@ CFStringRef SOSCCCopyIncompatibilityInfo_Server(CFErrorRef* error) return result; } -bool SOSCCCheckPeerAvailability_Server(CFErrorRef *error) -{ - __block bool pingedPeersInCircle = false; - __block dispatch_semaphore_t peerSemaphore = NULL; - __block bool peerIsAvailable = false; - - static dispatch_queue_t time_out; - static dispatch_once_t once; - dispatch_once(&once, ^{ - time_out = dispatch_queue_create("peersAvailableTimeout", DISPATCH_QUEUE_SERIAL); - }); - __block int token = -1; - - bool result = do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - - peerSemaphore = dispatch_semaphore_create(0); - notify_register_dispatch(kSOSCCPeerAvailable, &token, time_out, ^(int token) { - if(peerSemaphore != NULL){ - dispatch_semaphore_signal(peerSemaphore); - peerIsAvailable = true; - notify_cancel(token); - } - }); - - pingedPeersInCircle = SOSAccountCheckPeerAvailability(txn.account, block_error); - return pingedPeersInCircle; - }); - - if (result) { - dispatch_semaphore_wait(peerSemaphore, dispatch_time(DISPATCH_TIME_NOW, 7ull * NSEC_PER_SEC)); - } - - if(time_out != NULL && peerSemaphore != NULL){ - dispatch_sync(time_out, ^{ - if(!peerIsAvailable){ - peerSemaphore = NULL; - notify_cancel(token); - secnotice("peer available", "checking peer availability timed out, releasing semaphore"); - } - }); - } - if(!peerIsAvailable){ - CFStringRef errorMessage = CFSTR("There are no peers in the circle currently available"); - CFDictionaryRef userInfo = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kCFErrorLocalizedDescriptionKey, errorMessage, NULL); - if(error != NULL){ - *error =CFErrorCreate(kCFAllocatorDefault, CFSTR("com.apple.security.ids.error"), kSecIDSErrorNoPeersAvailable, userInfo); - secerror("%@", *error); - } - CFReleaseNull(userInfo); - return false; - } - else - return true; -} - - bool SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(CFErrorRef *error) { bool result = do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { return SOSAccountIsLastBackupPeer(txn.account, block_error); @@ -1912,8 +1992,6 @@ bool SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(CFErrorRef *error) { return result; } - - enum DepartureReason SOSCCGetLastDepartureReason_Server(CFErrorRef* error) { __block enum DepartureReason result = kSOSDepartureReasonError; @@ -1995,13 +2073,6 @@ void SOSCCRequestSyncWithPeer(CFStringRef peerID) { CFReleaseNull(peers); } -bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly_Server(CFStringRef deviceID, CFErrorRef *error) -{ - return do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) { - return SOSAccountSyncWithKVSUsingIDSID(txn.account, deviceID, error); - }); -} - void SOSCCRequestSyncWithPeers(CFSetRef /*SOSPeerInfoRef/CFStringRef*/ peerIDs) { CFMutableArrayRef peerIDArray = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); @@ -2025,7 +2096,7 @@ void SOSCCRequestSyncWithPeersList(CFArrayRef /*CFStringRef*/ peerIDs) { os_activity_initiate("CloudCircle RequestSyncWithPeersList", OS_ACTIVITY_FLAG_DEFAULT, ^(void) { CFArrayRef empty = CFArrayCreateForCFTypes(kCFAllocatorDefault, NULL); - CFStringArrayPerfromWithDescription(peerIDs, ^(CFStringRef description) { + CFStringArrayPerformWithDescription(peerIDs, ^(CFStringRef description) { secnotice("syncwith", "Request Sync With: %@", description); }); @@ -2040,7 +2111,7 @@ void SOSCCRequestSyncWithBackupPeer(CFStringRef backupPeerId) { CFArrayRef empty = CFArrayCreateForCFTypes(kCFAllocatorDefault, NULL); CFArrayRef backupPeerList = CFArrayCreateForCFTypes(kCFAllocatorDefault, backupPeerId, NULL); - CFStringArrayPerfromWithDescription(backupPeerList, ^(CFStringRef description) { + CFStringArrayPerformWithDescription(backupPeerList, ^(CFStringRef description) { secnotice("syncwith", "Request backup sync With: %@", description); }); diff --git a/OSX/sec/securityd/SecCAIssuerCache.c b/OSX/sec/securityd/SecCAIssuerCache.c index 3481cf58..5921de5b 100644 --- a/OSX/sec/securityd/SecCAIssuerCache.c +++ b/OSX/sec/securityd/SecCAIssuerCache.c @@ -47,6 +47,7 @@ #include #include +#include static const char expireSQL[] = "DELETE FROM issuers WHERE expiresinsertIssuer, 1, @@ -290,9 +336,14 @@ static void _SecCAIssuerCacheAddCertificate(SecCAIssuerCacheRef this, if (!s3e) s3e = sqlite3_bind_double(this->insertIssuer, 2, expires); /* issuer.certificate */ - if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->insertIssuer, 3, - SecCertificateGetBytePtr(certificate), - SecCertificateGetLength(certificate), SQLITE_TRANSIENT); + require_action(certsData = convertArrayOfCertsToData(certificates), errOut, + s3e = SQLITE_NOMEM); + if (!s3e) { + s3e = sqlite3_bind_blob_wrapper(this->insertIssuer, 3, + CFDataGetBytePtr(certsData), + CFDataGetLength(certsData), SQLITE_TRANSIENT); + } + CFReleaseNull(certsData); /* Execute the insert statement. */ if (!s3e) s3e = sqlite3_step(this->insertIssuer); @@ -306,9 +357,9 @@ errOut: } } -static SecCertificateRef _SecCAIssuerCacheCopyMatching(SecCAIssuerCacheRef this, +static CFArrayRef _SecCAIssuerCacheCopyMatching(SecCAIssuerCacheRef this, CFURLRef uri) { - SecCertificateRef certificate = NULL; + CFArrayRef certificates = NULL; int s3e = SQLITE_OK; CFDataRef uriData = NULL; @@ -325,7 +376,7 @@ static SecCertificateRef _SecCAIssuerCacheCopyMatching(SecCAIssuerCacheRef this, const void *respData = sqlite3_column_blob(this->selectIssuer, 0); int respLen = sqlite3_column_bytes(this->selectIssuer, 0); - certificate = SecCertificateCreateWithBytes(NULL, respData, respLen); + certificates = convertDataToArrayOfCerts((uint8_t *)respData, respLen); } require_noerr(s3e = sec_sqlite3_reset(this->selectIssuer, s3e), errOut); @@ -338,15 +389,14 @@ errOut: /* TODO: Blow away the cache and create a new db. */ } - if (certificate) { - CFRelease(certificate); - certificate = NULL; + if (certificates) { + CFRelease(certificates); + certificates = NULL; } } - secdebug("caissuercache", "returning %s for %@", (certificate ? "cached response" : "NULL"), uri); - - return certificate; + secdebug("caissuercache", "returning %s for %@", (certificates ? "cached response" : "NULL"), uri); + return certificates; } static void _SecCAIssuerCacheGC(void *context) { @@ -384,7 +434,7 @@ static void _SecCAIssuerCacheFlush(void *context) { /* Public API */ -void SecCAIssuerCacheAddCertificate(SecCertificateRef certificate, +void SecCAIssuerCacheAddCertificates(CFArrayRef certificates, CFURLRef uri, CFAbsoluteTime expires) { dispatch_once(&kSecCAIssuerCacheOnce, ^{ SecCAIssuerCacheInit(); @@ -393,20 +443,21 @@ void SecCAIssuerCacheAddCertificate(SecCertificateRef certificate, return; dispatch_sync(kSecCAIssuerCache->queue, ^{ - _SecCAIssuerCacheAddCertificate(kSecCAIssuerCache, certificate, uri, expires); + _SecCAIssuerCacheAddCertificates(kSecCAIssuerCache, certificates, uri, expires); + _SecCAIssuerCacheFlush(kSecCAIssuerCache); }); } -SecCertificateRef SecCAIssuerCacheCopyMatching(CFURLRef uri) { +CFArrayRef SecCAIssuerCacheCopyMatching(CFURLRef uri) { dispatch_once(&kSecCAIssuerCacheOnce, ^{ SecCAIssuerCacheInit(); }); - __block SecCertificateRef cert = NULL; + __block CFArrayRef certs = NULL; if (kSecCAIssuerCache) dispatch_sync(kSecCAIssuerCache->queue, ^{ - cert = _SecCAIssuerCacheCopyMatching(kSecCAIssuerCache, uri); + certs = _SecCAIssuerCacheCopyMatching(kSecCAIssuerCache, uri); }); - return cert; + return certs; } /* This should be called on a normal non emergency exit. This function @@ -428,11 +479,3 @@ void SecCAIssuerCacheGC(void) { _SecCAIssuerCacheGC(kSecCAIssuerCache); }); } - -/* Call this periodically or perhaps when we are exiting due to low memory. */ -void SecCAIssuerCacheFlush(void) { - if (kSecCAIssuerCache) - dispatch_sync(kSecCAIssuerCache->queue, ^{ - _SecCAIssuerCacheFlush(kSecCAIssuerCache); - }); -} diff --git a/OSX/sec/securityd/SecCAIssuerCache.h b/OSX/sec/securityd/SecCAIssuerCache.h index d22fd6b4..152035d8 100644 --- a/OSX/sec/securityd/SecCAIssuerCache.h +++ b/OSX/sec/securityd/SecCAIssuerCache.h @@ -39,17 +39,14 @@ __BEGIN_DECLS -void SecCAIssuerCacheAddCertificate(SecCertificateRef certificate, +void SecCAIssuerCacheAddCertificates(CFArrayRef certificates, CFURLRef uri, CFAbsoluteTime expires); -SecCertificateRef SecCAIssuerCacheCopyMatching(CFURLRef uri); +CFArrayRef SecCAIssuerCacheCopyMatching(CFURLRef uri); /* This should be called on a normal non emergency exit. */ void SecCAIssuerCacheGC(void); -/* Call this periodically or perhaps when we are exiting due to low memory. */ -void SecCAIssuerCacheFlush(void); - __END_DECLS #endif /* _SECURITY_SECCAISSUERCACHE_H_ */ diff --git a/OSX/sec/securityd/SecCAIssuerRequest.c b/OSX/sec/securityd/SecCAIssuerRequest.c deleted file mode 100644 index b187a965..00000000 --- a/OSX/sec/securityd/SecCAIssuerRequest.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) 2009-2018 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@ - */ - -/* - * SecCAIssuerRequest.c - asynchronous CAIssuer request fetching engine. - */ - - -#include "SecCAIssuerRequest.h" -#include "SecCAIssuerCache.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_CA_ISSUERS 3 -#define CA_ISSUERS_REQUEST_THRESHOLD 10 - - -/* CA Issuer lookup code. */ - -typedef struct SecCAIssuerRequest *SecCAIssuerRequestRef; -struct SecCAIssuerRequest { - asynchttp_t http; /* Must be first field. */ - SecCertificateRef certificate; - CFArrayRef issuers; /* NONRETAINED */ - CFIndex issuerIX; - void *context; - void (*callback)(void *, CFArrayRef); -}; - -static void SecCAIssuerRequestRelease(SecCAIssuerRequestRef request) { - CFRelease(request->certificate); - asynchttp_free(&request->http); - free(request); -} - -static bool SecCAIssuerRequestIssue(SecCAIssuerRequestRef request) { - CFIndex count = CFArrayGetCount(request->issuers); - if (count >= CA_ISSUERS_REQUEST_THRESHOLD) { - secnotice("caissuer", "too many caIssuer entries (%ld)", (long)count); - request->callback(request->context, NULL); - SecCAIssuerRequestRelease(request); - return true; - } - - SecPathBuilderRef builder = (SecPathBuilderRef)request->context; - TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); - - while (request->issuerIX < count && request->issuerIX < MAX_CA_ISSUERS) { - CFURLRef issuer = CFArrayGetValueAtIndex(request->issuers, - request->issuerIX++); - CFStringRef scheme = CFURLCopyScheme(issuer); - if (scheme) { - if (CFEqual(CFSTR("http"), scheme)) { - CFHTTPMessageRef msg = CFHTTPMessageCreateRequest(kCFAllocatorDefault, - CFSTR("GET"), issuer, kCFHTTPVersion1_1); - if (msg) { - secinfo("caissuer", "%@", msg); - bool done = asynchttp_request(msg, 0, &request->http); - if (analytics) { - /* Count each http request we made */ - analytics->ca_issuer_fetches++; - } - CFRelease(msg); - if (done == false) { - CFRelease(scheme); - return done; - } - } - secdebug("caissuer", "failed to get %@", issuer); - } else { - secnotice("caissuer", "skipping unsupported uri %@", issuer); - } - CFRelease(scheme); - } - } - - /* No more issuers left to try, we're done. */ - secdebug("caissuer", "no request issued"); - request->callback(request->context, NULL); - SecCAIssuerRequestRelease(request); - return true; -} - -/* Releases parent unconditionally, and return a CFArrayRef containing - parent if the normalized subject of parent matches the normalized issuer - of certificate. */ -static CF_RETURNS_RETAINED CFArrayRef SecCAIssuerConvertToParents(SecCertificateRef certificate, - SecCertificateRef CF_CONSUMED parent) { - CFDataRef nic = SecCertificateGetNormalizedIssuerContent(certificate); - CFArrayRef parents = NULL; - if (parent) { - CFDataRef parent_nic = SecCertificateGetNormalizedSubjectContent(parent); - if (nic && parent_nic && CFEqual(nic, parent_nic)) { - const void *ventry = parent; - parents = CFArrayCreate(NULL, &ventry, 1, &kCFTypeArrayCallBacks); - } - CFRelease(parent); - } - return parents; -} - -#define SECONDS_PER_DAY (86400.0) -static void SecCAIssuerRequestCompleted(asynchttp_t *http, - CFTimeInterval maxAge) { - /* Cast depends on http being first field in struct SecCAIssuerRequest. */ - SecCAIssuerRequestRef request = (SecCAIssuerRequestRef)http; - - SecPathBuilderRef builder = (SecPathBuilderRef)request->context; - TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); - if (analytics) { - /* Add the time this fetch took to complete to the total time */ - analytics->ca_issuer_fetch_time += (mach_absolute_time() - http->start_time); - } - - CFDataRef data = (request->http.response ? - CFHTTPMessageCopyBody(request->http.response) : NULL); - if (data) { - /* RFC5280 4.2.2.1: - "accessLocation MUST be a uniformResourceIdentifier and the URI - MUST point to either a single DER encoded certificate as speci- - fied in [RFC2585] or a collection of certificates in a BER or - DER encoded "certs-only" CMS message as specified in [RFC2797]." */ - - /* DER-encoded certificate */ - SecCertificateRef parent = SecCertificateCreateWithData(NULL, data); - - /* "certs-only" CMS Message */ - if (!parent) { - CFArrayRef certificates = NULL; - certificates = SecCMSCertificatesOnlyMessageCopyCertificates(data); - /* @@@ Technically these can have more than one certificate */ - if (certificates && CFArrayGetCount(certificates) >= 1) { - parent = CFRetainSafe((SecCertificateRef)CFArrayGetValueAtIndex(certificates, 0)); - } else if (certificates && CFArrayGetCount(certificates) > 1) { - if (analytics) { - /* Indicate that this trust evaluation encountered a CAIssuer fetch with multiple certs */ - analytics->ca_issuer_multiple_certs = true; - } - } - CFReleaseNull(certificates); - } - - /* Retry in case the certificate is in PEM format. Some CAs - incorrectly return a PEM encoded cert, despite RFC 5280 4.2.2.1 */ - if (!parent) { - parent = SecCertificateCreateWithPEM(NULL, data); - } - CFRelease(data); - if (parent) { - /* We keep responses in the cache for at least 7 days, or longer - if the http response tells us to keep it around for more. */ - if (maxAge < SECONDS_PER_DAY * 7) - maxAge = SECONDS_PER_DAY * 7; - CFAbsoluteTime expires = CFAbsoluteTimeGetCurrent() + maxAge; - CFURLRef issuer = CFArrayGetValueAtIndex(request->issuers, - request->issuerIX - 1); - SecCAIssuerCacheAddCertificate(parent, issuer, expires); - CFArrayRef parents = SecCAIssuerConvertToParents( - request->certificate, parent); /* note: this releases parent */ - if (parents) { - secdebug("caissuer", "response: %@ good", http->response); - request->callback(request->context, parents); - CFRelease(parents); - SecCAIssuerRequestRelease(request); - return; - } - } else if (analytics) { - /* We failed to create a SecCertificateRef from the data we got */ - analytics->ca_issuer_unsupported_data = true; - } - } else if (analytics) { - /* We didn't get any data back, so the fetch failed */ - analytics->ca_issuer_fetch_failed++; - } - - secdebug("caissuer", "response: %@ not parent, trying next caissuer", - http->response); - /* We're re-using this http object, so we need to free all the old memory. */ - asynchttp_free(&request->http); - SecCAIssuerRequestIssue(request); -} - -static CFArrayRef SecCAIssuerRequestCacheCopyParents(SecCertificateRef cert, - CFArrayRef issuers) { - CFIndex ix = 0, ex = CFArrayGetCount(issuers); - for (;ix < ex; ++ix) { - CFURLRef issuer = CFArrayGetValueAtIndex(issuers, ix); - CFStringRef scheme = CFURLCopyScheme(issuer); - if (scheme) { - if (CFEqual(CFSTR("http"), scheme)) { - CFArrayRef parents = SecCAIssuerConvertToParents(cert, - SecCAIssuerCacheCopyMatching(issuer)); - if (parents) { - secdebug("caissuer", "cache hit, for %@ no request issued", issuer); - CFRelease(scheme); - return parents; - } - } - CFRelease(scheme); - } - } - return NULL; -} - -bool SecCAIssuerCopyParents(SecCertificateRef certificate, dispatch_queue_t queue, - void *context, void (*callback)(void *, CFArrayRef)) { - CFArrayRef issuers = SecCertificateGetCAIssuers(certificate); - if (!issuers) { - /* certificate has no caissuer urls, we're done. */ - callback(context, NULL); - return true; - } - - SecPathBuilderRef builder = (SecPathBuilderRef)context; - TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); - CFArrayRef parents = SecCAIssuerRequestCacheCopyParents(certificate, issuers); - if (parents) { - if (analytics) { - /* We found parents in the cache */ - analytics->ca_issuer_cache_hit = true; - } - callback(context, parents); - CFReleaseSafe(parents); - return true; - } - if (analytics) { - /* We're going to have to make a network call */ - analytics->ca_issuer_network = true; - } - - /* Cache miss, let's issue a network request. */ - SecCAIssuerRequestRef request = - (SecCAIssuerRequestRef)calloc(1, sizeof(*request)); - request->http.queue = queue; - request->http.completed = SecCAIssuerRequestCompleted; - CFRetain(certificate); - request->certificate = certificate; - request->issuers = issuers; - request->issuerIX = 0; - request->context = context; - request->callback = callback; - - return SecCAIssuerRequestIssue(request); -} - diff --git a/OSX/sec/securityd/SecCAIssuerRequest.h b/OSX/sec/securityd/SecCAIssuerRequest.h index 01034021..61ea4dc4 100644 --- a/OSX/sec/securityd/SecCAIssuerRequest.h +++ b/OSX/sec/securityd/SecCAIssuerRequest.h @@ -26,5 +26,4 @@ #include #include -bool SecCAIssuerCopyParents(SecCertificateRef certificate, - dispatch_queue_t queue, void *context, void (*callback)(void *, CFArrayRef)); +bool SecCAIssuerCopyParents(SecCertificateRef certificate, void *context, void (*callback)(void *, CFArrayRef)); diff --git a/OSX/sec/securityd/SecCAIssuerRequest.m b/OSX/sec/securityd/SecCAIssuerRequest.m new file mode 100644 index 00000000..b7b31d41 --- /dev/null +++ b/OSX/sec/securityd/SecCAIssuerRequest.m @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2009-2018 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@ + */ + +/* + * SecCAIssuerRequest.m - asynchronous CAIssuer request fetching engine. + */ + + +#include "SecCAIssuerRequest.h" +#include "SecCAIssuerCache.h" + +#import +#import +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_CA_ISSUERS 3 +#define CA_ISSUERS_REQUEST_THRESHOLD 10 + +typedef void (*CompletionHandler)(void *context, CFArrayRef parents); + +/* CA Issuer lookup code. */ +@interface CAIssuerDelegate: TrustURLSessionDelegate +@property (assign) CompletionHandler callback; +@end + +static NSArray *certificatesFromData(NSData *data) { + /* RFC5280 4.2.2.1: + "accessLocation MUST be a uniformResourceIdentifier and the URI + MUST point to either a single DER encoded certificate as speci- + fied in [RFC2585] or a collection of certificates in a BER or + DER encoded "certs-only" CMS message as specified in [RFC2797]." */ + + /* DER-encoded certificate */ + SecCertificateRef parent = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data); + if (parent) { + NSArray *result = @[(__bridge id)parent]; + CFReleaseNull(parent); + return result; + } + + /* "certs-only" CMS Message */ + CFArrayRef certificates = SecCMSCertificatesOnlyMessageCopyCertificates((__bridge CFDataRef)data); + if (certificates) { + return CFBridgingRelease(certificates); + } + + /* Retry in case the certificate is in PEM format. Some CAs + incorrectly return a PEM encoded cert, despite RFC 5280 4.2.2.1 */ + parent = SecCertificateCreateWithPEM(NULL, (__bridge CFDataRef)data); + if (parent) { + NSArray *result = @[(__bridge id)parent]; + CFReleaseNull(parent); + return result; + } + return nil; +} + +@implementation CAIssuerDelegate +- (BOOL)fetchNext:(NSURLSession *)session { + SecPathBuilderRef builder = (SecPathBuilderRef)self.context; + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + + BOOL result = false; + if (!(result = [super fetchNext:session]) && analytics) { + analytics->ca_issuer_fetches++; + } + return result; +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { + /* call the superclass's method to set taskTime and expiration */ + [super URLSession:session task:task didCompleteWithError:error]; + + __block SecPathBuilderRef builder =(SecPathBuilderRef)self.context; + if (!builder) { + /* We already returned to the PathBuilder state machine. */ + return; + } + + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + __block NSArray *parents = nil; + if (error) { + /* Log the error */ + secnotice("caissuer", "Failed to download issuer %@, with error %@", task.originalRequest.URL, error); + if (analytics) { + analytics->ca_issuer_fetch_failed++; + } + } else if (self.response) { + /* Get the parent cert from the data */ + parents = certificatesFromData(self.response); + if (analytics && !parents) { + analytics->ca_issuer_unsupported_data = true; + } else if (analytics && [parents count] > 1) { + analytics->ca_issuer_multiple_certs = true; + } + } + + if (parents) { + /* Found some parents, add to cache, close session, and return to SecPathBuilder */ + secdebug("caissuer", "found parents for %@", task.originalRequest.URL); + SecCAIssuerCacheAddCertificates((__bridge CFArrayRef)parents, (__bridge CFURLRef)task.originalRequest.URL, self.expiration); + self.context = nil; // set the context to NULL before we call back because the callback may free the builder + [session invalidateAndCancel]; + dispatch_async(SecPathBuilderGetQueue(builder), ^{ + self.callback(builder, (__bridge CFArrayRef)parents); + }); + } else { + secdebug("caissuer", "no parents for %@", task.originalRequest.URL); + if ([self fetchNext:session]) { // Try the next CAIssuer URI + /* no fetch scheduled, close this session and jump back into the state machine on the builder's queue */ + secdebug("caissuer", "no more fetches. returning to builder"); + self.context = nil; // set the context to NULL before we call back because the callback may free the builder + [session invalidateAndCancel]; + dispatch_async(SecPathBuilderGetQueue(builder), ^{ + self.callback(builder, NULL); + }); + } + } +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)taskMetrics { + secdebug("caissuer", "got metrics with task interval %f", taskMetrics.taskInterval.duration); + SecPathBuilderRef builder =(SecPathBuilderRef)self.context; + if (builder) { + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + if (analytics) { + analytics->ca_issuer_fetch_time += (uint64_t)(taskMetrics.taskInterval.duration * NSEC_PER_SEC); + } + } +} +@end + +/* Releases parent unconditionally, and return a CFArrayRef containing + parent if the normalized subject of parent matches the normalized issuer + of certificate. */ +static CF_RETURNS_RETAINED CFArrayRef SecCAIssuerConvertToParents(SecCertificateRef certificate, CFArrayRef CF_CONSUMED putativeParents) { + CFDataRef nic = SecCertificateGetNormalizedIssuerContent(certificate); + NSMutableArray *parents = [NSMutableArray array]; + NSArray *possibleParents = CFBridgingRelease(putativeParents); + for (id parent in possibleParents) { + CFDataRef parent_nic = SecCertificateGetNormalizedSubjectContent((__bridge SecCertificateRef)parent); + if (nic && parent_nic && CFEqual(nic, parent_nic)) { + [parents addObject:parent]; + } + } + + if ([parents count] > 0) { + return CFBridgingRetain(parents); + } else { + return nil; + } +} + +static CFArrayRef SecCAIssuerRequestCacheCopyParents(SecCertificateRef cert, + CFArrayRef issuers) { + CFIndex ix = 0, ex = CFArrayGetCount(issuers); + for (;ix < ex; ++ix) { + CFURLRef issuer = CFArrayGetValueAtIndex(issuers, ix); + CFStringRef scheme = CFURLCopyScheme(issuer); + if (scheme) { + if (CFEqual(CFSTR("http"), scheme)) { + CFArrayRef parents = SecCAIssuerConvertToParents(cert, + SecCAIssuerCacheCopyMatching(issuer)); + if (parents) { + secdebug("caissuer", "cache hit, for %@. no request issued", issuer); + CFRelease(scheme); + return parents; + } + } + CFRelease(scheme); + } + } + return NULL; +} + +bool SecCAIssuerCopyParents(SecCertificateRef certificate, void *context, void (*callback)(void *, CFArrayRef)) { + @autoreleasepool { + CFArrayRef issuers = CFRetainSafe(SecCertificateGetCAIssuers(certificate)); + NSArray *nsIssuers = CFBridgingRelease(issuers); + if (!issuers) { + /* certificate has no caissuer urls, we're done. */ + callback(context, NULL); + return true; + } + + SecPathBuilderRef builder = (SecPathBuilderRef)context; + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + CFArrayRef parents = SecCAIssuerRequestCacheCopyParents(certificate, (__bridge CFArrayRef)nsIssuers); + if (parents) { + if (analytics) { + /* We found parents in the cache */ + analytics->ca_issuer_cache_hit = true; + } + callback(context, parents); + CFReleaseSafe(parents); + return true; + } + if (analytics) { + /* We're going to have to make a network call */ + analytics->ca_issuer_network = true; + } + + NSInteger count = [nsIssuers count]; + if (count >= CA_ISSUERS_REQUEST_THRESHOLD) { + secnotice("caissuer", "too many caIssuer entries (%ld)", (long)count); + callback(context, NULL); + return true; + } + + NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + config.timeoutIntervalForResource = TrustURLSessionGetResourceTimeout(); + config.HTTPAdditionalHeaders = @{@"User-Agent" : @"com.apple.trustd/2.0"}; + + NSData *auditToken = CFBridgingRelease(SecPathBuilderCopyClientAuditToken(builder)); + if (auditToken) { + config._sourceApplicationAuditTokenData = auditToken; + } + + CAIssuerDelegate *delegate = [[CAIssuerDelegate alloc] init]; + delegate.context = context; + delegate.callback = callback; + delegate.URIs = nsIssuers; + delegate.URIix = 0; + + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; + + NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:queue]; + secdebug("caissuer", "created URLSession for %@", certificate); + + bool result = false; + if ((result = [delegate fetchNext:session])) { + /* no fetch scheduled, close the session */ + [session invalidateAndCancel]; + } + return result; + } +} + diff --git a/OSX/sec/securityd/SecCertificateServer.c b/OSX/sec/securityd/SecCertificateServer.c index ea49d9b0..0236ca49 100644 --- a/OSX/sec/securityd/SecCertificateServer.c +++ b/OSX/sec/securityd/SecCertificateServer.c @@ -276,11 +276,20 @@ struct SecCertificatePathVC { bool pathValidated; + /* If checkedIssuers is true, then the value of unknownCAIndex contains + * the index of the first CA which violates known-only constraints, or + * -1 if all CA certificates are either known or not constrained. */ + bool checkedIssuers; + CFIndex unknownCAIndex; + /* Enumerated value to determine whether CT is required for the leaf * certificate (because a CA in the path has a require-ct constraint). * If non-zero, CT is required; value indicates overridable status. */ SecPathCTPolicy requiresCT; + /* Issuance time, as determined by earliest SCT timestamp for leaf. */ + CFAbsoluteTime issuanceTime; + SecCertificateVCRef certificates[]; }; CFGiblisWithHashFor(SecCertificatePathVC) @@ -291,7 +300,7 @@ static void SecCertificatePathVCPrunePolicyTree(SecCertificatePathVCRef certific } } -static void SecCertificatePathVCDeleteRVCs(SecCertificatePathVCRef path) { +void SecCertificatePathVCDeleteRVCs(SecCertificatePathVCRef path) { if (path->rvcs) { CFIndex certIX, certCount = path->rvcCount; for (certIX = 0; certIX < certCount; ++certIX) { @@ -648,11 +657,7 @@ SecKeyRef SecCertificatePathVCCopyPublicKeyAtIndex( SecCertificatePathVCRef certificatePath, CFIndex ix) { SecCertificateRef certificate = SecCertificatePathVCGetCertificateAtIndex(certificatePath, ix); -#if TARGET_OS_OSX - return SecCertificateCopyPublicKey_ios(certificate); -#else - return SecCertificateCopyPublicKey(certificate); -#endif + return SecCertificateCopyKey(certificate); } CFArrayRef SecCertificatePathVCGetUsageConstraintsAtIndex( @@ -924,6 +929,22 @@ void SecCertificatePathVCSetRevocationRequiredForCertificateAtIndex(SecCertifica cvc->require_revocation_response = true; } +bool SecCertificatePathVCCheckedIssuers(SecCertificatePathVCRef certificatePath) { + return certificatePath->checkedIssuers; +} + +void SecCertificatePathVCSetCheckedIssuers(SecCertificatePathVCRef certificatePath, bool checked) { + certificatePath->checkedIssuers = checked; +} + +CFIndex SecCertificatePathVCUnknownCAIndex(SecCertificatePathVCRef certificatePath) { + return certificatePath->unknownCAIndex; +} + +void SecCertificatePathVCSetUnknownCAIndex(SecCertificatePathVCRef certificatePath, CFIndex index) { + certificatePath->unknownCAIndex = index; +} + bool SecCertificatePathVCIsPathValidated(SecCertificatePathVCRef certificatePath) { if (!certificatePath) { return false; } return certificatePath->pathValidated; @@ -968,6 +989,15 @@ void SecCertificatePathVCSetRequiresCT(SecCertificatePathVCRef certificatePath, certificatePath->requiresCT = requiresCT; } +CFAbsoluteTime SecCertificatePathVCIssuanceTime(SecCertificatePathVCRef certificatePath) { + if (!certificatePath) { return 0; } + return certificatePath->issuanceTime; +} + +void SecCertificatePathVCSetIssuanceTime(SecCertificatePathVCRef certificatePath, CFAbsoluteTime issuanceTime) { + certificatePath->issuanceTime = issuanceTime; +} + bool SecCertificatePathVCIsAllowlisted(SecCertificatePathVCRef certificatePath) { if (!certificatePath) { return false; } return certificatePath->is_allowlisted; diff --git a/OSX/sec/securityd/SecCertificateServer.h b/OSX/sec/securityd/SecCertificateServer.h index 7be3affa..879e08a3 100644 --- a/OSX/sec/securityd/SecCertificateServer.h +++ b/OSX/sec/securityd/SecCertificateServer.h @@ -124,6 +124,7 @@ void SecCertificatePathVCSetScore(SecCertificatePathVCRef certificatePath, CFInd void SecCertificatePathVCResetScore(SecCertificatePathVCRef certificatePath); // reset score to 0 /* Revocation */ +void SecCertificatePathVCDeleteRVCs(SecCertificatePathVCRef path); bool SecCertificatePathVCIsRevocationDone(SecCertificatePathVCRef certificatePath); void SecCertificatePathVCAllocateRVCs(SecCertificatePathVCRef certificatePath, CFIndex certCount); CFAbsoluteTime SecCertificatePathVCGetEarliestNextUpdate(SecCertificatePathVCRef path); @@ -133,6 +134,11 @@ bool SecCertificatePathVCIsRevocationRequiredForCertificateAtIndex(SecCertificat void SecCertificatePathVCSetRevocationRequiredForCertificateAtIndex(SecCertificatePathVCRef certificatePath, CFIndex ix); +bool SecCertificatePathVCCheckedIssuers(SecCertificatePathVCRef certificatePath); +void SecCertificatePathVCSetCheckedIssuers(SecCertificatePathVCRef certificatePath, bool checked); +CFIndex SecCertificatePathVCUnknownCAIndex(SecCertificatePathVCRef certificatePath); +void SecCertificatePathVCSetUnknownCAIndex(SecCertificatePathVCRef certificatePath, CFIndex index); + /* Did we already validate this path (setting EV, CT, RVC, etc.) */ bool SecCertificatePathVCIsPathValidated(SecCertificatePathVCRef certificatePath); void SecCertificatePathVCSetPathValidated(SecCertificatePathVCRef certificatePath); @@ -153,6 +159,8 @@ bool SecCertificatePathVCIsCT(SecCertificatePathVCRef certificatePath); void SecCertificatePathVCSetIsCT(SecCertificatePathVCRef certificatePath, bool isCT); SecPathCTPolicy SecCertificatePathVCRequiresCT(SecCertificatePathVCRef certificatePath); void SecCertificatePathVCSetRequiresCT(SecCertificatePathVCRef certificatePath, SecPathCTPolicy requiresCT); +CFAbsoluteTime SecCertificatePathVCIssuanceTime(SecCertificatePathVCRef certificatePath); +void SecCertificatePathVCSetIssuanceTime(SecCertificatePathVCRef certificatePath, CFAbsoluteTime issuanceTime); /* Allowlist */ bool SecCertificatePathVCIsAllowlisted(SecCertificatePathVCRef certificatePath); diff --git a/OSX/sec/securityd/SecCertificateSource.c b/OSX/sec/securityd/SecCertificateSource.c index 37c2a788..393dd7f3 100644 --- a/OSX/sec/securityd/SecCertificateSource.c +++ b/OSX/sec/securityd/SecCertificateSource.c @@ -234,8 +234,7 @@ static CF_RETURNS_RETAINED CFArrayRef _Nullable SecItemCertificateSourceResultsP return result; } -static bool SecItemCertificateSourceCopyParents( - SecCertificateSourceRef source, SecCertificateRef certificate, +static bool SecItemCertificateSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate, void *context, SecCertificateSourceParents callback) { SecItemCertificateSourceRef msource = (SecItemCertificateSourceRef)source; CFDataRef normalizedIssuer = SecCertificateGetNormalizedIssuerContent(certificate); @@ -261,13 +260,8 @@ static bool SecItemCertificateSourceContains(SecCertificateSourceRef source, /* Look up a certificate by issuer and serial number. */ CFDataRef normalizedIssuer = SecCertificateGetNormalizedIssuerContent(certificate); CFRetainSafe(normalizedIssuer); - CFDataRef serialNumber = -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - SecCertificateCopySerialNumber(certificate, NULL); -#else - SecCertificateCopySerialNumber(certificate); -#endif CFErrorRef localError = NULL; + CFDataRef serialNumber = SecCertificateCopySerialNumberData(certificate, &localError); bool result = SecItemCertificateExists(normalizedIssuer, serialNumber, msource->accessGroups, &localError); if (localError) { if (CFErrorGetCode(localError) != errSecItemNotFound) { @@ -302,8 +296,7 @@ void SecItemCertificateSourceDestroy(SecCertificateSourceRef source) { *********** SecSystemAnchorSource object ************ ********************************************************/ -static bool SecSystemAnchorSourceCopyParents( - SecCertificateSourceRef source, SecCertificateRef certificate, +static bool SecSystemAnchorSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate, void *context, SecCertificateSourceParents callback) { //#ifndef SECITEM_SHIM_OSX CFArrayRef parents = NULL; @@ -488,8 +481,7 @@ struct SecMemoryCertificateSource { }; typedef struct SecMemoryCertificateSource *SecMemoryCertificateSourceRef; -static bool SecMemoryCertificateSourceCopyParents( - SecCertificateSourceRef source, SecCertificateRef certificate, +static bool SecMemoryCertificateSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate, void *context, SecCertificateSourceParents callback) { SecMemoryCertificateSourceRef msource = (SecMemoryCertificateSourceRef)source; @@ -529,8 +521,7 @@ static void dictAddValueToArrayForKey(CFMutableDictionaryRef dict, CFArrayAppendValue(values, value); } -static void SecMemoryCertificateSourceApplierFunction(const void *value, - void *context) { +static void SecMemoryCertificateSourceApplierFunction(const void *value, void *context) { SecMemoryCertificateSourceRef msource = (SecMemoryCertificateSourceRef)context; SecCertificateRef certificate = (SecCertificateRef)value; @@ -576,8 +567,7 @@ void SecMemoryCertificateSourceDestroy(SecCertificateSourceRef source) { /******************************************************** ********* SecCAIssuerCertificateSource object ********** ********************************************************/ -static bool SecCAIssuerCertificateSourceCopyParents( - SecCertificateSourceRef source, SecCertificateRef certificate, +static bool SecCAIssuerCertificateSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate, void *context, SecCertificateSourceParents callback) { /* Some expired certs have dead domains. Let's not check them. */ SecPathBuilderRef builder = (SecPathBuilderRef)context; @@ -587,11 +577,10 @@ static bool SecCAIssuerCertificateSourceCopyParents( callback(context, NULL); return true; } - return SecCAIssuerCopyParents(certificate, SecPathBuilderGetQueue(builder), context, callback); + return SecCAIssuerCopyParents(certificate, context, callback); } -static bool SecCAIssuerCertificateSourceContains( - SecCertificateSourceRef source, SecCertificateRef certificate) { +static bool SecCAIssuerCertificateSourceContains(SecCertificateSourceRef source, SecCertificateRef certificate) { return false; } @@ -611,8 +600,7 @@ const SecCertificateSourceRef kSecCAIssuerSource = &_kSecCAIssuerSource; ********** SecLegacyCertificateSource object *********** ********************************************************/ -static bool SecLegacyCertificateSourceCopyParents( - SecCertificateSourceRef source, SecCertificateRef certificate, +static bool SecLegacyCertificateSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate, void *context, SecCertificateSourceParents callback) { CFArrayRef parents = SecItemCopyParentCertificates_osx(certificate, NULL); callback(context, parents); @@ -620,8 +608,7 @@ static bool SecLegacyCertificateSourceCopyParents( return true; } -static bool SecLegacyCertificateSourceContains( - SecCertificateSourceRef source, SecCertificateRef certificate) { +static bool SecLegacyCertificateSourceContains(SecCertificateSourceRef source, SecCertificateRef certificate) { SecCertificateRef cert = SecItemCopyStoredCertificate(certificate, NULL); bool result = (cert) ? true : false; CFReleaseSafe(cert); diff --git a/OSX/sec/securityd/SecDbKeychainItem.m b/OSX/sec/securityd/SecDbKeychainItem.m index 1530fd05..63e99e31 100644 --- a/OSX/sec/securityd/SecDbKeychainItem.m +++ b/OSX/sec/securityd/SecDbKeychainItem.m @@ -46,6 +46,7 @@ #include #include #import "SecDbKeychainItemV7.h" +#import "sec_action.h" #if USE_KEYSTORE #include @@ -286,6 +287,21 @@ bool ks_encrypt_data_legacy(keybag_handle_t keybag, SecAccessControlRef access_c return ok; } +static void +ks_warn_non_device_keybag(void) +{ + static dispatch_once_t once; + static sec_action_t action; + + dispatch_once(&once, ^{ + action = sec_action_create("non-device keybag", 2); + sec_action_set_handler(action, ^{ + secwarning("ks_encrypt_data: called with non-device keybag - call should be rerouted to ks_encrypt_data_legacy"); + }); + }); + sec_action_perform(action); +} + bool ks_encrypt_data(keybag_handle_t keybag, SecAccessControlRef access_control, CFDataRef acm_context, CFDictionaryRef secretData, CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, bool useDefaultIV, CFErrorRef *error) { if (CFDictionaryGetCount(secretData) == 0) { @@ -293,7 +309,7 @@ bool ks_encrypt_data(keybag_handle_t keybag, SecAccessControlRef access_control, } if (keybag != KEYBAG_DEVICE) { - secwarning("ks_encrypt_data: called with non-device keybag - call should be rerouted to ks_encrypt_data_legacy"); + ks_warn_non_device_keybag(); CFMutableDictionaryRef allAttributes = CFDictionaryCreateMutableCopy(NULL, CFDictionaryGetCount(secretData) + CFDictionaryGetCount(attributes), attributes); CFDictionaryForEach(secretData, ^(const void *key, const void *value) { diff --git a/OSX/sec/securityd/SecDbKeychainItemV7.m b/OSX/sec/securityd/SecDbKeychainItemV7.m index c2f4c238..d30cd30f 100644 --- a/OSX/sec/securityd/SecDbKeychainItemV7.m +++ b/OSX/sec/securityd/SecDbKeychainItemV7.m @@ -343,6 +343,7 @@ typedef NS_ENUM(uint32_t, SecDbKeychainAKSWrappedKeyType) { - (SFAESKey*)keyForKeyclass:(keyclass_t)keyClass keybag:(keybag_handle_t)keybag keySpecifier:(SFAESKeySpecifier*)keySpecifier + createKeyIfMissing:(bool)createIfMissing overwriteCorruptKey:(bool)overwriteCorruptKey error:(NSError**)error; @end @@ -478,6 +479,7 @@ static void initializeSharedMetadataStoreQueue(void) { - (SFAESKey*)keyForKeyclass:(keyclass_t)keyclass keybag:(keybag_handle_t)keybag keySpecifier:(SFAESKeySpecifier*)keySpecifier + createKeyIfMissing:(bool)createIfMissing overwriteCorruptKey:(bool)overwriteCorruptKey error:(NSError**)error { @@ -503,6 +505,9 @@ static void initializeSharedMetadataStoreQueue(void) { // if we think we're locked, it's possible AKS will still give us access to keys, such as during backup, // but we should force AKS to be the truth and not used cached class A keys while locked bool allowKeyCaching = [SecDbKeychainMetadataKeyStore cachingEnabled]; + + // However, we must not cache a newly-created key, just in case someone above us in the stack rolls back our database transaction and the stored key is lost. + __block bool keyIsNewlyCreated = false; #if 0 // Fix keychain lock state check to be both secure and fast for EDU mode if (![SecDbKeychainItemV7 isKeychainUnlocked]) { @@ -515,7 +520,7 @@ static void initializeSharedMetadataStoreQueue(void) { if (!key) { __block bool ok = true; __block bool metadataKeyDoesntAuthenticate = false; - ok &= kc_with_dbt_non_item_tables(true, &cfError, ^bool(SecDbConnectionRef dbt) { + ok &= kc_with_dbt_non_item_tables(createIfMissing, &cfError, ^bool(SecDbConnectionRef dbt) { __block NSString* sql = [NSString stringWithFormat:@"SELECT data, actualKeyclass FROM metadatakeys WHERE keyclass = %d", keyclass]; ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &cfError, ^(sqlite3_stmt *stmt) { ok &= SecDbStep(dbt, stmt, &cfError, ^(bool *stop) { @@ -529,6 +534,10 @@ static void initializeSharedMetadataStoreQueue(void) { ok &= [SecDbKeychainItemV7 aksDecryptWithKeybag:keybag keyclass:keyclassForUnwrapping wrappedKeyData:wrappedKeyData outKeyclass:NULL unwrappedKey:unwrappedKeyData error:&nsErrorLocal]; if (ok) { key = [[SFAESKey alloc] initWithData:unwrappedKeyData specifier:keySpecifier error:&nsErrorLocal]; + + if(!key) { + os_log_fault(secLogObjForScope("SecDbKeychainItemV7"), "Metadata class key (%d) decrypted, but didn't become a key: %@", keyclass, nsErrorLocal); + } if (actualKeyclass == 0) { actualKeyclassToWriteBackToDB = keyclassForUnwrapping; @@ -548,6 +557,11 @@ static void initializeSharedMetadataStoreQueue(void) { if (ok) { secerror("SecDbKeychainItemV7: successfully decrypted metadata key using keyrolled keyclass %d", keyrolledKeyclass); key = [[SFAESKey alloc] initWithData:unwrappedKeyData specifier:keySpecifier error:&retryError]; + + if(!key) { + os_log_fault(secLogObjForScope("SecDbKeychainItemV7"), "Metadata class key (%d) decrypted using keyrolled keyclass %d, but didn't become a key: %@", keyclass, keyrolledKeyclass, retryError); + nsErrorLocal = retryError; + } } else { secerror("SecDbKeychainItemV7: failed to decrypt metadata key with keyrolled keyclass %d; error: %@", keyrolledKeyclass, retryError); @@ -555,7 +569,7 @@ static void initializeSharedMetadataStoreQueue(void) { } #endif - if (ok) { + if (ok && key) { if (actualKeyclassToWriteBackToDB > 0) { // check if we have updated this keyclass or not already static NSMutableDictionary* updated = NULL; @@ -582,10 +596,13 @@ static void initializeSharedMetadataStoreQueue(void) { }); sec_action_perform(kclockedaction); } else { - secerror("SecDbKeychainItemV7: failed to decrypt metadata key for class %d; error: %@", keyclass, nsErrorLocal); + secerror("SecDbKeychainItemV7: failed to decrypt and create metadata key for class %d; error: %@", keyclass, nsErrorLocal); // If this error is errSecDecode, then it's failed authentication and likely will forever. Other errors are scary. metadataKeyDoesntAuthenticate = [nsErrorLocal.domain isEqualToString:NSOSStatusErrorDomain] && nsErrorLocal.code == errSecDecode; + if(metadataKeyDoesntAuthenticate) { + os_log_fault(secLogObjForScope("SecDbKeychainItemV7"), "Metadata class key (%d) failed to decrypt: %@", keyclass, nsErrorLocal); + } } } }); @@ -594,7 +611,7 @@ static void initializeSharedMetadataStoreQueue(void) { bool keyNotYetCreated = ok && !key; bool forceOverwriteBadKey = !key && metadataKeyDoesntAuthenticate && overwriteCorruptKey; - if (keyNotYetCreated || forceOverwriteBadKey) { + if (createIfMissing && (keyNotYetCreated || forceOverwriteBadKey)) { // we completed the database query, but no key exists or it's broken - we should create one if(forceOverwriteBadKey) { secerror("SecDbKeychainItemV7: metadata key is irreparably corrupt; throwing away forever"); @@ -604,9 +621,11 @@ static void initializeSharedMetadataStoreQueue(void) { ok = true; // Reset 'ok': we have a second chance key = [[SFAESKey alloc] initRandomKeyWithSpecifier:keySpecifier error:&nsErrorLocal]; + keyIsNewlyCreated = true; + if (key) { NSMutableData* wrappedKey = [NSMutableData dataWithLength:key.keyData.length + 40]; - keyclass_t outKeyclass; + keyclass_t outKeyclass = keyclass; ok &= [SecDbKeychainItemV7 aksEncryptWithKeybag:keybag keyclass:keyclass keyData:key.keyData outKeyclass:&outKeyclass wrappedKey:wrappedKey error:&nsErrorLocal]; if (ok) { secinfo("SecDbKeychainItemV7", "attempting to save new metadata key for keyclass %d with actualKeyclass %d", keyclass, outKeyclass); @@ -634,13 +653,21 @@ static void initializeSharedMetadataStoreQueue(void) { else { ok = false; } + } else if(!key) { + // No key, but we're not supposed to make one. Make an error if one doesn't yet exist. + ok = false; + if(!nsErrorLocal) { + nsErrorLocal = [NSError errorWithDomain:(id)kSecErrorDomain code:errSecDecode userInfo:@{NSLocalizedDescriptionKey: @"Unable to find or create a suitable metadata key"}]; + } } return ok; }); if (ok && key) { - if (allowKeyCaching) { + // We can't cache a newly-created key, just in case this db transaction is rolled back and we lose the persisted key. + // Don't worry, we'll cache it as soon as it's used again. + if (allowKeyCaching && !keyIsNewlyCreated) { self->_keysDict[@(keyclass)] = key; __weak __typeof(self) weakSelf = self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60 * 5 * NSEC_PER_SEC)), self->_queue, ^{ @@ -697,10 +724,13 @@ static void initializeSharedMetadataStoreQueue(void) { return result; } +// bring back with +#if 0 + (bool)isKeychainUnlocked { return kc_is_unlocked(); } +#endif - (instancetype)initWithData:(NSData*)data decryptionKeybag:(keybag_handle_t)decryptionKeybag error:(NSError**)error { @@ -778,6 +808,7 @@ static void initializeSharedMetadataStoreQueue(void) { { if (!_metadataAttributes) { SFAESKey* metadataClassKey = [self metadataClassKeyWithKeybag:_keybag + createKeyIfMissing:false overwriteCorruptKey:false error:error]; if (metadataClassKey) { @@ -928,6 +959,7 @@ static void initializeSharedMetadataStoreQueue(void) { SFAuthenticatedCiphertext* ciphertext = [encryptionOperation encrypt:metadata withKey:key error:error]; SFAESKey* metadataClassKey = [self metadataClassKeyWithKeybag:keybag + createKeyIfMissing:true overwriteCorruptKey:true error:error]; if (metadataClassKey) { @@ -965,12 +997,14 @@ static void initializeSharedMetadataStoreQueue(void) { } - (SFAESKey*)metadataClassKeyWithKeybag:(keybag_handle_t)keybag + createKeyIfMissing:(bool)createIfMissing overwriteCorruptKey:(bool)force error:(NSError**)error { return [[SecDbKeychainMetadataKeyStore sharedStore] keyForKeyclass:_keyclass keybag:keybag keySpecifier:[self.class keySpecifier] + createKeyIfMissing:(bool)createIfMissing overwriteCorruptKey:force error:error]; } diff --git a/OSX/sec/securityd/SecDbQuery.c b/OSX/sec/securityd/SecDbQuery.c index 81780ed1..886a3e4f 100644 --- a/OSX/sec/securityd/SecDbQuery.c +++ b/OSX/sec/securityd/SecDbQuery.c @@ -599,7 +599,8 @@ static void query_add_return(const void *key, const void *value, Query *q) */ static void query_add_use(const void *key, const void *value, Query *q) { - if (CFEqual(key, kSecUseItemList)) { + // Gotta use a string literal because we just outlawed this symbol on iOS + if (CFEqual(key, CFSTR("u_ItemList"))) { /* TODO: Add sanity checking when we start using this. */ q->q_use_item_list = value; } else if (CFEqual(key, kSecUseTombstones)) { diff --git a/OSX/sec/securityd/SecItemDb.c b/OSX/sec/securityd/SecItemDb.c index 47a32045..54b6f794 100644 --- a/OSX/sec/securityd/SecItemDb.c +++ b/OSX/sec/securityd/SecItemDb.c @@ -78,11 +78,11 @@ const SecDbAttr *SecDbAttrWithKey(const SecDbClass *c, return NULL; } -bool kc_transaction(SecDbConnectionRef dbt, CFErrorRef *error, bool(^perform)()) { +bool kc_transaction(SecDbConnectionRef dbt, CFErrorRef *error, bool(^perform)(void)) { return kc_transaction_type(dbt, kSecDbExclusiveTransactionType, error, perform); } -bool kc_transaction_type(SecDbConnectionRef dbt, SecDbTransactionType type, CFErrorRef *error, bool(^perform)()) { +bool kc_transaction_type(SecDbConnectionRef dbt, SecDbTransactionType type, CFErrorRef *error, bool(^perform)(void)) { __block bool ok = true; return ok && SecDbTransaction(dbt, type, error, ^(bool *commit) { ok = *commit = perform(); @@ -148,9 +148,13 @@ static void SecDbAppendCreateTableWithClass(CFMutableStringRef sql, const SecDbC CFStringAppend(sql, CFSTR(");")); - // Create indicies + // Create indices SecDbForEachAttrWithMask(c,desc, kSecDbIndexFlag | kSecDbInFlag) { - CFStringAppendFormat(sql, 0, CFSTR("CREATE INDEX %@%@ ON %@(%@);"), c->name, desc->name, c->name, desc->name); + if (desc->kind == kSecDbSyncAttr) { + CFStringAppendFormat(sql, 0, CFSTR("CREATE INDEX %@%@0 ON %@(%@) WHERE %@=0;"), c->name, desc->name, c->name, desc->name, desc->name); + } else { + CFStringAppendFormat(sql, 0, CFSTR("CREATE INDEX %@%@ ON %@(%@);"), c->name, desc->name, c->name, desc->name); + } } } diff --git a/OSX/sec/securityd/SecItemSchema.c b/OSX/sec/securityd/SecItemSchema.c index f3605330..53dbea4c 100644 --- a/OSX/sec/securityd/SecItemSchema.c +++ b/OSX/sec/securityd/SecItemSchema.c @@ -81,7 +81,7 @@ SECDB_ATTR(v6cdat, "cdat", CreationDate, SecDbFlags( ,L, , ,A, , ,C,H, , , , , SECDB_ATTR(v6mdat, "mdat",ModificationDate,SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), SecDbKeychainItemCopyCurrentDate, NULL); SECDB_ATTR(v6labl, "labl", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6data, "data", EncryptedData, SecDbFlags( ,L, , , , , , , ,B, , , , , , ), SecDbKeychainItemCopyEncryptedData, NULL); -SECDB_ATTR(v6agrp, "agrp", String, SecDbFlags(P,L, , ,A, , , ,H, , , ,N,U,V0,Y), NULL, NULL); +SECDB_ATTR(v6agrp, "agrp", String, SecDbFlags(P,L,I, ,A, , , ,H, , , ,N,U,V0,Y), NULL, NULL); SECDB_ATTR(v6pdmn, "pdmn", Access, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6sync, "sync", Sync, SecDbFlags(P,L,I, ,A, , , ,H, ,Z, ,N,U,V0, ), NULL, NULL); SECDB_ATTR(v6tomb, "tomb", Tomb, SecDbFlags( ,L, , , , , , ,H, ,Z, ,N,U, ,Y), NULL, NULL); @@ -89,8 +89,8 @@ SECDB_ATTR(v6sha1, "sha1", SHA1, SecDbFlags( ,L,I, ,A, ,R, , , , , , , SECDB_ATTR(v6accc, "accc", AccessControl, SecDbFlags( , , , ,A, , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v6v_Data, "v_Data", Data, SecDbFlags( , , , , ,D, ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6v_pk, "v_pk", PrimaryKey, SecDbFlags( , , , , , , , , , , , , , , , ), SecDbKeychainItemCopyPrimaryKey, NULL); -SECDB_ATTR(v7vwht, "vwht", String, SecDbFlags(P,L, , ,A, , , ,H, , , , ,U,V2,Y), NULL, NULL); -SECDB_ATTR(v7tkid, "tkid", String, SecDbFlags(P,L, , ,A, , , ,H, , , , ,U,V2,Y), NULL, NULL); +SECDB_ATTR(v7vwht, "vwht", String, SecDbFlags(P,L,I, ,A, , , ,H, , , , ,U,V2,Y), NULL, NULL); +SECDB_ATTR(v7tkid, "tkid", String, SecDbFlags(P,L,I, ,A, , , ,H, , , , ,U,V2,Y), NULL, NULL); SECDB_ATTR(v7utomb, "u_Tomb", UTomb, SecDbFlags( , , , , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v8musr, "musr", UUID, SecDbFlags(P,L,I, , , , , , , , , ,N,U, ,Y), NULL, NULL); // genp and inet and keys | | | | | | | | | | | | | | | | @@ -99,29 +99,29 @@ SECDB_ATTR(v6alis, "alis", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , // genp and inet | | | | | | | | | | | | | | | | SECDB_ATTR(v6desc, "desc", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6icmt, "icmt", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL); -SECDB_ATTR(v6type, "type", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); +SECDB_ATTR(v6type, "type", Number, SecDbFlags( ,L,I, ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6invi, "invi", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6nega, "nega", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6cusi, "cusi", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6prot, "prot", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6scrp, "scrp", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); -SECDB_ATTR(v6acct, "acct", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6acct, "acct", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); // genp only | | | | | | | | | | | | | | | | -SECDB_ATTR(v6svce, "svce", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6svce, "svce", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); SECDB_ATTR(v6gena, "gena", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL); // inet only | | | | | | | | | | | | | | | | -SECDB_ATTR(v6sdmn, "sdmn", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6srvr, "srvr", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6ptcl, "ptcl", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6atyp, "atyp", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6port, "port", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6path, "path", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6sdmn, "sdmn", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6srvr, "srvr", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6ptcl, "ptcl", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6atyp, "atyp", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6port, "port", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6path, "path", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); // cert only | | | | | | | | | | | | | | | | -SECDB_ATTR(v6ctyp, "ctyp", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6ctyp, "ctyp", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); SECDB_ATTR(v6cenc, "cenc", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6subj, "subj", Data, SecDbFlags( ,L,I,S,A, , ,C,H, , , , , , ,Y), NULL, NULL); -SECDB_ATTR(v6issr, "issr", Data, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6slnr, "slnr", Data, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6issr, "issr", Data, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6slnr, "slnr", Data, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); SECDB_ATTR(v6skid, "skid", Data, SecDbFlags( ,L,I,S,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6pkhh, "pkhh", Data, SecDbFlags( ,L,I, ,A, , ,C,H, , , , , , ,Y), NULL, NULL); // cert attributes that share names with common ones but have different flags @@ -132,11 +132,11 @@ SECDB_ATTR(v6perm, "perm", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , SECDB_ATTR(v6priv, "priv", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6modi, "modi", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6klbl, "klbl", Data, SecDbFlags(P,L,I, ,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6atag, "atag", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6bsiz, "bsiz", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6esiz, "esiz", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6sdat, "sdat", Date, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6edat, "edat", Date, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6atag, "atag", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6bsiz, "bsiz", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6esiz, "esiz", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6sdat, "sdat", Date, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6edat, "edat", Date, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); SECDB_ATTR(v6sens, "sens", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6asen, "asen", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6extr, "extr", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); @@ -151,32 +151,32 @@ SECDB_ATTR(v6vyrc, "vyrc", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , SECDB_ATTR(v6wrap, "wrap", Number, SecDbFlags( ,L,I, ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v6unwp, "unwp", Number, SecDbFlags( ,L,I, ,A, , ,C,H, , , , , , ,Y), NULL, NULL); // keys attributes that share names with common ones but have different flags -SECDB_ATTR(v6keytype, "type", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); -SECDB_ATTR(v6keycrtr, "crtr", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6keytype, "type", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); +SECDB_ATTR(v6keycrtr, "crtr", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL); // | | | | | | | | | | | | | | | -SECDB_ATTR(v6version, "version", Number, SecDbFlags(P,L, , , , , , , , , , ,N, , ,Y), NULL, NULL); +SECDB_ATTR(v6version, "version", Number, SecDbFlags(P,L,I, , , , , , , , , ,N, , ,Y), NULL, NULL); SECDB_ATTR(v91minor, "minor", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N, , ,Y), NULL, NULL); SECDB_ATTR(v10_1pcsservice, "pcss", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v10_1pcspublickey, "pcsk", Blob, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); SECDB_ATTR(v10_1pcspublicidentity,"pcsi", Blob, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL); -SECDB_ATTR(v10itemuuid, "UUID", String, SecDbFlags( ,L, , , , , , , , , , , ,U, , ), NULL, NULL); -SECDB_ATTR(v10syncuuid, "UUID", String, SecDbFlags(P,L, , , , , , , , , , , ,U, , ), NULL, NULL); -SECDB_ATTR(v10parentKeyUUID, "parentKeyUUID", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v10itemuuid, "UUID", String, SecDbFlags( ,L,I, , , , , , , , , , ,U, , ), NULL, NULL); +SECDB_ATTR(v10syncuuid, "UUID", String, SecDbFlags(P,L,I, , , , , , , , , , ,U, , ), NULL, NULL); +SECDB_ATTR(v10parentKeyUUID, "parentKeyUUID", String, SecDbFlags( ,L,I, , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10currentKeyUUID,"currentKeyUUID",String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10wrappedkey, "wrappedkey", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10encrypteditem, "encitem", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10gencount, "gencount", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N, , , ), NULL, NULL); -SECDB_ATTR(v10action, "action", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); -SECDB_ATTR(v10state, "state", String, SecDbFlags(P,L, , , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v10action, "action", String, SecDbFlags( ,L,I, , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v10state, "state", String, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10waituntiltime, "waituntil", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10encodedCKRecord, "ckrecord", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10_1wasCurrent, "wascurrent", Number, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); -SECDB_ATTR(v10accessgroup, "accessgroup", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); -SECDB_ATTR(v10keyclass, "keyclass", String, SecDbFlags(P,L, , , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v10accessgroup, "accessgroup", String, SecDbFlags( ,L,I, , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v10keyclass, "keyclass", String, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10currentkey, "currentkey", Number, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); -SECDB_ATTR(v10ckzone, "ckzone", String, SecDbFlags(P,L, , , , , , , , , , ,N,U, , ), NULL, NULL); +SECDB_ATTR(v10ckzone, "ckzone", String, SecDbFlags(P,L,I, , , , , , , , , ,N,U, , ), NULL, NULL); SECDB_ATTR(v10ckzonecreated, "ckzonecreated", Number, SecDbFlags( ,L, , , , , , , , ,Z, , ,N, , ), NULL, NULL); SECDB_ATTR(v10ckzonesubscribed,"ckzonesubscribed", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N, , , ), NULL, NULL); SECDB_ATTR(v10ratelimiter, "ratelimiter", Blob, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); @@ -186,8 +186,8 @@ SECDB_ATTR(v10itempersistentref,"persistref", UUID, SecDbFlags( ,L, , , , , , SECDB_ATTR(v10sysbound, "sysb", Number, SecDbFlags( ,L, , ,A, , ,C,H, ,Z, , , , , ), NULL, NULL); SECDB_ATTR(v10encryptionver, "encver", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N,U, , ), NULL, NULL); -SECDB_ATTR(v10primaryKey, "primaryKey", String, SecDbFlags(P,L, , ,A, , , , , , , ,N,U, , ), NULL, NULL); -SECDB_ATTR(v10publickeyHash, "publickeyHash", Blob, SecDbFlags(P,L, , , , , , , , , , ,N,U, , ), NULL, NULL); +SECDB_ATTR(v10primaryKey, "primaryKey", String, SecDbFlags(P,L,I, ,A, , , , , , , ,N,U, , ), NULL, NULL); +SECDB_ATTR(v10publickeyHash, "publickeyHash", Blob, SecDbFlags(P,L,I, , , , , , , , , ,N,U, , ), NULL, NULL); SECDB_ATTR(v10publickey, "publickey", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10backupData, "backupData", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); @@ -202,8 +202,8 @@ SECDB_ATTR(v10_2futureData, "futureData", Blob, SecDbFlags( ,L, , , , , , SECDB_ATTR(v10_2schema, "schema", Blob, SecDbFlags( ,L, , , , , , , , , , ,N,U, , ), NULL, NULL); SECDB_ATTR(v10_1encRecord, "ckrecord", Blob, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); -SECDB_ATTR(v10_1keyArchiveHash, "key_archive_hash", String, SecDbFlags(P,L, , , , , , , , , , ,N, , , ), NULL, NULL); -SECDB_ATTR(v10_1keyArchive, "key_archive", String, SecDbFlags(P,L, , , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v10_1keyArchiveHash, "key_archive_hash", String, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v10_1keyArchive, "key_archive", String, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10_1archivedKey, "archived_key", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10_1keyArchiveName, "keyarchive_name", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); SECDB_ATTR(v10_1optionalEncodedCKRecord, "ckrecord", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); @@ -211,11 +211,11 @@ SECDB_ATTR(v10_1archiveEscrowID,"archive_escrowid", String, SecDbFlags( ,L, , , SECDB_ATTR(v10_1itempersistentref,"persistref", UUID, SecDbFlags( ,L,I, , , , , , , , , ,N,U, , ), NULL, NULL); -SECDB_ATTR(v10_1currentItemUUID,"currentItemUUID",String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL); +SECDB_ATTR(v10_1currentItemUUID,"currentItemUUID",String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10_4currentItemUUID,"currentItemUUID",String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); -SECDB_ATTR(v10_1currentPtrIdentifier,"identifier",String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL); +SECDB_ATTR(v10_1currentPtrIdentifier,"identifier",String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL); -SECDB_ATTR(v10_2device, "device", String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL); +SECDB_ATTR(v10_2device, "device", String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10_2peerid, "peerid", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10_2circleStatus,"circlestatus", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10_2keyState, "keystate", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); @@ -225,8 +225,8 @@ SECDB_ATTR(v10_2currentClassC,"currentClassC",String, SecDbFlags( ,L, , , , SECDB_ATTR(v10_4lastFixup, "lastfixup", Number, SecDbFlags( ,L, , , , , , , , ,Z, , ,N, , ), NULL, NULL); -SECDB_ATTR(v10_5senderPeerID,"senderpeerid", String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL); -SECDB_ATTR(v10_5recvPeerID, "recvpeerid", String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL); +SECDB_ATTR(v10_5senderPeerID,"senderpeerid", String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL); +SECDB_ATTR(v10_5recvPeerID, "recvpeerid", String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10_5recvPubKey, "recvpubenckey", Blob, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10_5curve, "curve", Number, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10_5poisoned, "poisoned", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N, , , ), NULL, NULL); @@ -939,6 +939,76 @@ const SecDbClass v_identity_class = { }, }; +/* + * Version 11.4 (Add some more indexes) + */ +const SecDbSchema v11_4_schema = { + .majorVersion = 11, + .minorVersion = 4, + .classes = { + &v10_1_genp_class, + &v10_1_inet_class, + &v10_1_cert_class, + &v10_1_keys_class, + &v10_0_tversion_class, + &v10_2_outgoing_queue_class, + &v10_2_incoming_queue_class, + &v10_0_sync_key_class, + &v10_1_ckmirror_class, + &v10_0_current_key_class, + &v10_4_ckstate_class, + &v10_0_item_backup_class, + &v10_0_backup_keybag_class, + &v10_2_ckmanifest_class, + &v10_2_pending_manifest_class, + &v10_1_ckmanifest_leaf_class, + &v10_1_backup_keyarchive_class, + &v10_1_current_keyarchive_class, + &v10_1_current_archived_keys_class, + &v10_1_pending_manifest_leaf_class, + &v10_4_current_item_class, + &v11_1_ckdevicestate_class, + &v10_5_tlkshare_class, + &v11_2_metadatakeys_class, + 0 + } +}; + +/* + * Version 11.3 (no changes, restores the use of indexes in upgrade code. Gotta go fast!) + */ +const SecDbSchema v11_3_schema = { + .majorVersion = 11, + .minorVersion = 3, + .classes = { + &v10_1_genp_class, + &v10_1_inet_class, + &v10_1_cert_class, + &v10_1_keys_class, + &v10_0_tversion_class, + &v10_2_outgoing_queue_class, + &v10_2_incoming_queue_class, + &v10_0_sync_key_class, + &v10_1_ckmirror_class, + &v10_0_current_key_class, + &v10_4_ckstate_class, + &v10_0_item_backup_class, + &v10_0_backup_keybag_class, + &v10_2_ckmanifest_class, + &v10_2_pending_manifest_class, + &v10_1_ckmanifest_leaf_class, + &v10_1_backup_keyarchive_class, + &v10_1_current_keyarchive_class, + &v10_1_current_archived_keys_class, + &v10_1_pending_manifest_leaf_class, + &v10_4_current_item_class, + &v11_1_ckdevicestate_class, + &v10_5_tlkshare_class, + &v11_2_metadatakeys_class, + 0 + } +}; + /* * Version 11.2 */ @@ -2448,6 +2518,8 @@ static const SecDbSchema v5_schema = { SecDbSchema const * const * kc_schemas = NULL; const SecDbSchema *v10_kc_schemas[] = { + &v11_4_schema, + &v11_3_schema, &v11_2_schema, &v11_1_schema, &v11_schema, diff --git a/OSX/sec/securityd/SecItemServer.c b/OSX/sec/securityd/SecItemServer.c index 8aafa63a..5520e70d 100644 --- a/OSX/sec/securityd/SecItemServer.c +++ b/OSX/sec/securityd/SecItemServer.c @@ -83,6 +83,8 @@ #include #endif +#include "Analytics/Clients/LocalKeychainAnalytics.h" + /* Changed the name of the keychain changed notification, for testing */ static const char *g_keychain_changed_notification = kSecServerKeychainChangedNotification; @@ -123,7 +125,7 @@ bool SecKeychainDbGetVersion(SecDbConnectionRef dbt, int *version, CFErrorRef *e ok &= SecDbPrepare(dbt, CFSTR("SELECT name FROM sqlite_master WHERE type='table' AND name='tversion'"), &localError, ^(sqlite3_stmt *stmt) { ok = SecDbStep(dbt, stmt, NULL, ^(bool *stop) { found = true; - *stop = 1; + *stop = true; }); }); require_action(ok, out, SecDbError(SQLITE_CORRUPT, error, CFSTR("Failed to read sqlite_master table: %@"), localError)); @@ -245,11 +247,19 @@ static bool ShouldRenameTable(const SecDbClass* class1, const SecDbClass* class2 return oldTableVersion < 10 || !DBClassesAreEqual(class1, class2); } +#define SCHEMA_VERSION(schema) ((((schema)->minorVersion) << 8) | ((schema)->majorVersion)) +#define VERSION_MAJOR(version) ((version) & 0xff) +#define VERSION_MINOR(version) (((version) >> 8) & 0xff) +#define VERSION_NEW(version) ((version) & 0xffff) +#define VERSION_OLD(version) (((version) >> 16) & 0xffff) + // Goes through all tables represented by old_schema and tries to migrate all items from them into new (current version) tables. static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSchema, CFErrorRef *error) { - __block bool ok = true; + int oldVersion = SCHEMA_VERSION(oldSchema); const SecDbSchema *newSchema = current_schema(); + int newVersion = SCHEMA_VERSION(newSchema); + __block bool ok = true; SecDbClass const *const *oldClass; SecDbClass const *const *newClass; SecDbQueryRef query = NULL; @@ -291,22 +301,28 @@ static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSc } if(CFStringGetLength(sql) > 0) { - require_quiet(ok &= SecDbExec(dbt, sql, error), out); + require_action_quiet(ok &= SecDbExec(dbt, sql, error), out, + LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1AlterTables, error ? *error : NULL)); } CFReleaseNull(sql); // Drop indices that that new schemas will use sql = CFStringCreateMutable(NULL, 0); for (newClass = newSchema->classes; *newClass != NULL; newClass++) { - SecDbForEachAttrWithMask((*newClass),desc, kSecDbIndexFlag | kSecDbInFlag) { + SecDbForEachAttrWithMask((*newClass), desc, kSecDbIndexFlag | kSecDbInFlag) { CFStringAppendFormat(sql, 0, CFSTR("DROP INDEX IF EXISTS %@%@;"), (*newClass)->name, desc->name); + if (desc->kind == kSecDbSyncAttr) { + CFStringAppendFormat(sql, 0, CFSTR("DROP INDEX IF EXISTS %@%@0;"), (*newClass)->name, desc->name); + } } } - require_quiet(ok &= SecDbExec(dbt, sql, error), out); + require_action_quiet(ok &= SecDbExec(dbt, sql, error), out, + LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1DropIndices, error ? *error : NULL)); CFReleaseNull(sql); // Create tables for new schema. - require_quiet(ok &= SecItemDbCreateSchema(dbt, newSchema, classIndexesForNewTables, false, error), out); + require_action_quiet(ok &= SecItemDbCreateSchema(dbt, newSchema, classIndexesForNewTables, false, error), out, + LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1CreateSchema, error ? *error : NULL)); // Go through all classes of current schema to transfer all items to new tables. for (oldClass = oldSchema->classes, newClass = newSchema->classes; *oldClass != NULL && *newClass != NULL; oldClass++, newClass++) { @@ -413,9 +429,11 @@ static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSc } *stop = !ok; + }); - require_quiet(ok, out); + require_action_quiet(ok, out, + LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1Items, error ? *error : NULL)); } else { // This table does not contain secdb items, and must be transferred without using SecDbItemSelect. // For now, this code does not support removing or renaming any columns, or adding any new non-null columns. @@ -436,7 +454,8 @@ static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSc CFStringAppendFormat(sql, NULL, CFSTR("INSERT OR REPLACE INTO %@ (%@) SELECT %@ FROM %@;"), (*newClass)->name, columns, columns, renamedOldClass->name); CFReleaseNull(columns); - require_quiet(ok &= SecDbExec(dbt, sql, error), out); + require_action_quiet(ok &= SecDbExec(dbt, sql, error), out, + LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1NonItems, error ? *error : NULL)); } } @@ -453,7 +472,8 @@ static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSc } if(CFStringGetLength(sql) > 0) { - require_quiet(ok &= SecDbExec(dbt, sql, error), out); + require_action_quiet(ok &= SecDbExec(dbt, sql, error), out, + LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1DropOld, error ? *error : NULL)); } out: #if TARGET_OS_EMBEDDED @@ -473,10 +493,9 @@ out: } __thread SecDbConnectionRef dbt = NULL; -__thread bool isUnlocked = false; // Goes through all tables represented by old_schema and tries to migrate all items from them into new (current version) tables. -static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, CFErrorRef *error) { +static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, int oldVersion, CFErrorRef *error) { SecDbConnectionRef oldDbt = dbt; dbt = inDbt; __block bool ok = true; @@ -490,6 +509,7 @@ static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, CFErro // Go through all classes in new schema const SecDbSchema *newSchema = current_schema(); + int newVersion = SCHEMA_VERSION(newSchema); for (const SecDbClass *const *class = newSchema->classes; *class != NULL && !*inProgress; class++) { if(!((*class)->itemclass)) { //Don't try to decrypt non-item 'classes' @@ -564,6 +584,7 @@ static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, CFErro // remember that DB still needs phase2 migration to be run next time a connection is made. Also // stop iterating next items, it would be just waste of time because the whole iteration will be run // next time when this phase2 will be rerun. + LKAReportKeychainUpgradeOutcome(oldVersion, newVersion, LKAKeychainUpgradeOutcomeLocked); *inProgress = true; *stop = true; ok = true; @@ -605,7 +626,7 @@ static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, CFErro *stop = *stop || !ok; }); - require(ok, out); + require_action(ok, out, LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase2, error ? *error : NULL)); } #if TARGET_OS_EMBEDDED @@ -620,12 +641,6 @@ out: return ok; } -#define SCHEMA_VERSION(schema) ((((schema)->minorVersion) << 8) | ((schema)->majorVersion)) -#define VERSION_MAJOR(version) ((version) & 0xff) -#define VERSION_MINOR(version) (((version) >> 8) & 0xff) -#define VERSION_NEW(version) ((version) & 0xffff) -#define VERSION_OLD(version) (((version) >> 16) & 0xffff) - static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, bool *inProgress, CFErrorRef *error) { __block bool didPhase2 = false; __block bool ok = true; @@ -635,9 +650,11 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, *error = NULL; const SecDbSchema *newSchema = current_schema(); + int newVersion = SCHEMA_VERSION(newSchema); + bool skipped_upgrade = false; // If DB schema is the one we want, we are done. - require_quiet(SCHEMA_VERSION(newSchema) != version, out); + require_action_quiet(SCHEMA_VERSION(newSchema) != version, out, skipped_upgrade = true); // Check if the schema of the database on disk is the same major, but newer version then what we have // in code, lets just skip this since a newer version of the OS have upgrade it. Since its the same @@ -647,15 +664,6 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, goto out; } - if (VERSION_MAJOR(version) < 6) { - // Pre v6 keychains need to have WAL enabled, since SecDb only does this at db creation time. - // NOTE: This has to be run outside of a transaction. - require_action_quiet(ok = (SecDbExec(dbt, CFSTR("PRAGMA auto_vacuum = FULL"), &localError) && - SecDbExec(dbt, CFSTR("PRAGMA journal_mode = WAL"), &localError)), - out, secerror("upgrade: unable to enable WAL or auto vacuum, marking DB as corrupt: %@", - localError)); - } - ok &= SecDbTransaction(dbt, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { CFStringRef sql = NULL; bool didPhase1 = false; @@ -669,7 +677,8 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, require_quiet(SCHEMA_VERSION(newSchema) != version2, out); // If this is empty database, just create table according to schema and be done with it. - require_action_quiet(version2 != 0, out, ok = SecItemDbCreateSchema(dbt, newSchema, NULL, true, &localError)); + require_action_quiet(version2 != 0, out, ok = SecItemDbCreateSchema(dbt, newSchema, NULL, true, &localError); + LKAReportKeychainUpgradeOutcomeWithError(version2, newVersion, LKAKeychainUpgradeOutcomeNewDb, localError)); int oldVersion = VERSION_OLD(version2); version2 = VERSION_NEW(version2); @@ -677,7 +686,8 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, require_action_quiet(version2 == SCHEMA_VERSION(newSchema) || oldVersion == 0, out, ok = SecDbError(SQLITE_CORRUPT, &localError, CFSTR("Half migrated but obsolete DB found: found 0x%x(0x%x) but 0x%x is needed"), - version2, oldVersion, SCHEMA_VERSION(newSchema))); + version2, oldVersion, SCHEMA_VERSION(newSchema)); + LKAReportKeychainUpgradeOutcome(version2, newVersion, LKAKeychainUpgradeOutcomeObsoleteDb)); // Check whether we have both old and new tables in the DB. if (oldVersion == 0) { @@ -697,11 +707,11 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, // If we are attempting to upgrade from a version for which we have no schema, fail. require_action_quiet(oldSchema != NULL, out, ok = SecDbError(SQLITE_CORRUPT, &localError, CFSTR("no schema for version: 0x%x"), oldVersion); - secerror("no schema for version 0x%x", oldVersion)); + secerror("no schema for version 0x%x", oldVersion); + LKAReportKeychainUpgradeOutcome(version2, newVersion, LKAKeychainUpgradeOutcomeNoSchema)); secnotice("upgr", "Upgrading from version 0x%x to 0x%x", oldVersion, SCHEMA_VERSION(newSchema)); SecSignpostStart(SecSignpostUpgradePhase1); - require_action(ok = UpgradeSchemaPhase1(dbt, oldSchema, &localError), out, secerror("upgrade: Upgrade phase1 failed: %@", localError)); SecSignpostStop(SecSignpostUpgradePhase1); @@ -716,7 +726,7 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, // Lets try to go through non-D-class items in new tables and apply decode/encode on them // If this fails the error will be ignored after doing a phase1 since but not in the second // time when we are doing phase2. - ok = UpgradeItemPhase2(dbt, inProgress, &phase2Error); + ok = UpgradeItemPhase2(dbt, inProgress, version2, &phase2Error); if (!ok) { if (didPhase1) { *inProgress = true; @@ -803,6 +813,38 @@ out: SecADSetValueForScalarKey(CFSTR("com.apple.keychain.migration-failure"), 1); #endif } + } else { + // Things seemed to go okay! + if (didPhase2) { + LKAReportKeychainUpgradeOutcome(version, newVersion, LKAKeychainUpgradeOutcomeSuccess); + } + + //If we're done here, we should opportunistically re-add all indices (just in case) + if(skipped_upgrade || didPhase2) { + // Create indices, ignoring all errors + for (SecDbClass const* const* newClass = newSchema->classes; *newClass; ++newClass) { + SecDbForEachAttrWithMask((*newClass), desc, kSecDbIndexFlag | kSecDbInFlag) { + CFStringRef sql = NULL; + CFErrorRef localError = NULL; + bool localOk = true; + + if (desc->kind == kSecDbSyncAttr) { + // Replace the complete sync index with a partial index for sync=0. Most items are sync=1, so the complete index isn't helpful for sync=1 queries. + sql = CFStringCreateWithFormat(NULL, NULL, CFSTR("DROP INDEX IF EXISTS %@%@; CREATE INDEX IF NOT EXISTS %@%@0 on %@(%@) WHERE %@=0;"), + (*newClass)->name, desc->name, (*newClass)->name, desc->name, (*newClass)->name, desc->name, desc->name); + } else { + sql = CFStringCreateWithFormat(NULL, NULL, CFSTR("CREATE INDEX IF NOT EXISTS %@%@ ON %@(%@);"), (*newClass)->name, desc->name, (*newClass)->name, desc->name); + } + localOk &= SecDbExec(dbt, sql, &localError); + CFReleaseNull(sql); + + if(!localOk) { + secerror("upgrade: unable to opportunistically create index (%@,%@): %@", (*newClass)->name, desc->name, localError); + } + CFReleaseNull(localError); + } + } + } } if (localError) { if (error) { @@ -1041,7 +1083,9 @@ CFStringRef __SecKeychainCopyPath(void) { SecDbRef SecKeychainDbCreate(CFStringRef path, CFErrorRef* error) { __block CFErrorRef localerror = NULL; - SecDbRef kc = SecDbCreate(path, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) { + SecDbRef kc = SecDbCreate(path, 0600, true, true, true, true, kSecDbMaxIdleHandles, + ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) + { // Upgrade from version 0 means create the schema in empty db. int version = 0; bool ok = true; @@ -1145,19 +1189,6 @@ void SecKeychainDbReset(dispatch_block_t inbetween) }); } -static bool checkIsUnlocked() -{ - CFErrorRef aksError = NULL; - bool locked = true; - - if(!SecAKSGetIsLocked(&locked, &aksError)) { - secerror("error querying lock state: %@", aksError); - CFReleaseNull(aksError); - } - - return !locked; -} - static bool kc_acquire_dbt(bool writeAndRead, SecDbConnectionRef* dbconn, CFErrorRef *error) { SecDbRef db = kc_dbhandle(error); if (db == NULL) { @@ -1210,21 +1241,14 @@ bool kc_with_custom_db(bool writeAndRead, bool usesItemTables, SecDbRef db, CFEr } bool ok = false; - if (kc_acquire_dbt(writeAndRead, &dbt, error)) { - isUnlocked = checkIsUnlocked(); + if (kc_acquire_dbt(writeAndRead, &dbt, error)) { ok = perform(dbt); SecDbConnectionRelease(dbt); dbt = NULL; - isUnlocked = false; } return ok; } -bool kc_is_unlocked() -{ - return isUnlocked || checkIsUnlocked(); -} - static bool items_matching_issuer_parent(SecDbConnectionRef dbt, CFArrayRef accessGroups, CFDataRef musrView, CFDataRef issuer, CFArrayRef issuers, int recurse) @@ -1471,8 +1495,6 @@ out: **************** Beginning of Externally Callable Interface **************** ****************************************************************************/ -void (*SecTaskDiagnoseEntitlements)(CFArrayRef accessGroups) = NULL; - static bool SecEntitlementError(OSStatus status, CFErrorRef *error) { #if TARGET_OS_OSX @@ -1526,8 +1548,6 @@ SecItemServerCopyMatching(CFDictionaryRef query, CFTypeRef *result, CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { - if (SecTaskDiagnoseEntitlements) - SecTaskDiagnoseEntitlements(accessGroups); return SecEntitlementError(errSecMissingEntitlement, error); } @@ -1639,6 +1659,21 @@ SecItemSynchronizable(CFDictionaryRef query) } #endif +static CFArrayRef +SecurityClientCopyWritableAccessGroups(SecurityClient *client) { + if (client == NULL || client->accessGroups == NULL) { + return NULL; + } + CFIndex count = CFArrayGetCount(client->accessGroups); + if (CFArrayContainsValue(client->accessGroups, CFRangeMake(0, count), kSecAttrAccessGroupToken)) { + CFMutableArrayRef writableGroups = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, client->accessGroups); + CFArrayRemoveAllValue(writableGroups, kSecAttrAccessGroupToken); + return writableGroups; + } else { + return CFRetainSafe(client->accessGroups); + } +} + /* AUDIT[securityd](done): attributes (ok) is a caller provided dictionary, only its cf type has @@ -1647,13 +1682,12 @@ SecItemSynchronizable(CFDictionaryRef query) bool _SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *result, CFErrorRef *error) { - CFArrayRef accessGroups = client->accessGroups; + CFArrayRef accessGroups = SecurityClientCopyWritableAccessGroups(client); bool ok = true; CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { - if (SecTaskDiagnoseEntitlements) - SecTaskDiagnoseEntitlements(accessGroups); + CFReleaseNull(accessGroups); return SecEntitlementError(errSecMissingEntitlement, error); } @@ -1667,7 +1701,7 @@ _SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *resul /* Having the special accessGroup "*" allows access to all accessGroups. */ if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*"))) - accessGroups = NULL; + CFReleaseNull(accessGroups); if (agrp) { /* The user specified an explicit access group, validate it. */ @@ -1682,10 +1716,6 @@ _SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *resul query_add_attribute(kSecAttrAccessGroup, agrp, q); } - if (CFEqual(agrp, kSecAttrAccessGroupToken)) { - ok = SecError(errSecParam, error, CFSTR("storing items into kSecAttrAccessGroupToken is not allowed")); - } - if (SecPLShouldLogRegisteredEvent(CFSTR("SecItem"))) { CFDictionaryRef dict = CFDictionaryCreateForCFTypes(NULL, CFSTR("operation"), CFSTR("add"), CFSTR("AccessGroup"), agrp, NULL); if (dict) { @@ -1741,6 +1771,7 @@ _SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *resul SecSignpostStop(SecSignpostSecItemAdd); + CFReleaseNull(accessGroups); return ok; } @@ -1752,12 +1783,11 @@ bool _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, SecurityClient *client, CFErrorRef *error) { - CFArrayRef accessGroups = client->accessGroups; + CFArrayRef accessGroups = SecurityClientCopyWritableAccessGroups(client); CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { - if (SecTaskDiagnoseEntitlements) - SecTaskDiagnoseEntitlements(accessGroups); + CFReleaseNull(accessGroups); return SecEntitlementError(errSecMissingEntitlement, error); } @@ -1774,7 +1804,7 @@ _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*"))) { /* Having the special accessGroup "*" allows access to all accessGroups. */ - accessGroups = NULL; + CFReleaseNull(accessGroups); } bool ok = true; @@ -1820,9 +1850,6 @@ _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, if (agrp) { /* The user is attempting to modify the access group column, validate it to make sure the new value is allowable. */ - if (CFEqual(agrp, kSecAttrAccessGroupToken)) { - ok = SecError(errSecParam, error, CFSTR("storing items into kSecAttrAccessGroupToken is not allowed")); - } if (!accessGroupsAllows(accessGroups, agrp, client)) { ok = SecError(errSecNoAccessForItem, error, CFSTR("accessGroup %@ not in %@"), agrp, accessGroups); } @@ -1842,6 +1869,7 @@ _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, SecSignpostStop(SecSignpostSecItemUpdate); + CFReleaseNull(accessGroups); return ok; } @@ -1852,12 +1880,11 @@ _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, bool _SecItemDelete(CFDictionaryRef query, SecurityClient *client, CFErrorRef *error) { - CFArrayRef accessGroups = client->accessGroups; + CFArrayRef accessGroups = SecurityClientCopyWritableAccessGroups(client); CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { - if (SecTaskDiagnoseEntitlements) - SecTaskDiagnoseEntitlements(accessGroups); + CFReleaseNull(accessGroups); return SecEntitlementError(errSecMissingEntitlement, error); } @@ -1874,7 +1901,7 @@ _SecItemDelete(CFDictionaryRef query, SecurityClient *client, CFErrorRef *error) if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*"))) { /* Having the special accessGroup "*" allows access to all accessGroups. */ - accessGroups = NULL; + CFReleaseNull(accessGroups); } Query *q = query_create_with_limit(query, client->musr, kSecMatchUnlimited, error); @@ -1919,6 +1946,7 @@ _SecItemDelete(CFDictionaryRef query, SecurityClient *client, CFErrorRef *error) SecSignpostStop(SecSignpostSecItemDelete); + CFReleaseNull(accessGroups); return ok; } @@ -1973,8 +2001,6 @@ bool _SecItemUpdateTokenItems(CFStringRef tokenID, CFArrayRef items, SecurityCli CFArrayRef accessGroups = client->accessGroups; CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { - if (SecTaskDiagnoseEntitlements) - SecTaskDiagnoseEntitlements(accessGroups); return SecEntitlementError(errSecMissingEntitlement, error); } @@ -2486,14 +2512,12 @@ _SecAddSharedWebCredential(CFDictionaryRef attributes, if (creator) { CFDictionarySetValue(query, kSecAttrCreator, creator); CFReleaseSafe(creator); - ok = true; - } - else { - // confirm the add - // (per rdar://16680019, we won't prompt here in the normal case) - ok = /*approved ||*/ swca_confirm_operation(swca_add_request_id, clientAuditToken, query, error, - ^void (CFStringRef fqdn) { _SecAddNegativeWebCredential(client, fqdn, appID, false); }); } + + // confirm the add + ok = swca_confirm_operation(swca_add_request_id, clientAuditToken, query, error, ^void (CFStringRef fqdn) { + _SecAddNegativeWebCredential(client, fqdn, appID, false); + }); } if (ok) { ok = _SecItemAdd(query, &swcclient, result, error); @@ -3227,6 +3251,8 @@ _SecServerCopyInitialSyncCredentials(uint32_t flags, CFErrorRef *error) if (flags & SecServerInitialSyncCredentialFlagBluetoothMigration) { require_action(InitialSyncItems(items, false, CFSTR("com.apple.nanoregistry.migration"), NULL, genp_class(), error), fail, secerror("failed to collect com.apple.nanoregistry.migration-genp item: %@", error ? *error : NULL)); + require_action(InitialSyncItems(items, false, CFSTR("com.apple.nanoregistry.migration2"), NULL, genp_class(), error), fail, + secerror("failed to collect com.apple.nanoregistry.migration2-genp item: %@", error ? *error : NULL)); require_action(InitialSyncItems(items, false, CFSTR("com.apple.bluetooth"), CFSTR("BluetoothLESync"), genp_class(), error), fail, secerror("failed to collect com.apple.bluetooth-genp item: %@", error ? *error : NULL)); diff --git a/OSX/sec/securityd/SecItemServer.h b/OSX/sec/securityd/SecItemServer.h index f3e147b6..9755d77c 100644 --- a/OSX/sec/securityd/SecItemServer.h +++ b/OSX/sec/securityd/SecItemServer.h @@ -59,7 +59,6 @@ bool _SecServerBackupKeybagDelete(CFDictionaryRef attributes, bool deleteAll, CF bool _SecItemUpdateTokenItems(CFStringRef tokenID, CFArrayRef items, SecurityClient *client, CFErrorRef *error); CF_RETURNS_RETAINED CFArrayRef _SecServerKeychainSyncUpdateMessage(CFDictionaryRef updates, CFErrorRef *error); -bool _SecServerKeychainSyncUpdateIDSMessage(CFDictionaryRef updates, CFErrorRef *error); CF_RETURNS_RETAINED CFDictionaryRef _SecServerBackupSyncable(CFDictionaryRef backup, CFDataRef keybag, CFDataRef password, CFErrorRef *error); int SecServerKeychainTakeOverBackupFD(CFStringRef backupName, CFErrorRef *error); @@ -86,7 +85,6 @@ SecDbRef SecKeychainDbInitialize(SecDbRef db); bool kc_with_dbt(bool writeAndRead, CFErrorRef *error, bool (^perform)(SecDbConnectionRef dbt)); bool kc_with_dbt_non_item_tables(bool writeAndRead, CFErrorRef* error, bool (^perform)(SecDbConnectionRef dbt)); // can be used when only tables which don't store 'items' are accessed - avoids invoking SecItemDataSourceFactoryGetDefault() bool kc_with_custom_db(bool writeAndRead, bool usesItemTables, SecDbRef db, CFErrorRef *error, bool (^perform)(SecDbConnectionRef dbt)); -bool kc_is_unlocked(void); /* For whitebox testing only */ @@ -137,8 +135,6 @@ bool accessGroupsAllows(CFArrayRef accessGroups, CFStringRef accessGroup, Securi bool itemInAccessGroup(CFDictionaryRef item, CFArrayRef accessGroups); void SecKeychainChanged(void); -extern void (*SecTaskDiagnoseEntitlements)(CFArrayRef accessGroups); - __END_DECLS #endif /* _SECURITYD_SECITEMSERVER_H_ */ diff --git a/OSX/sec/securityd/SecOCSPCache.c b/OSX/sec/securityd/SecOCSPCache.c index 1aaf7abf..bc7e55df 100644 --- a/OSX/sec/securityd/SecOCSPCache.c +++ b/OSX/sec/securityd/SecOCSPCache.c @@ -67,12 +67,12 @@ // MARK: SecOCSPCacheDb static SecDbRef SecOCSPCacheDbCreate(CFStringRef path) { - return SecDbCreate(path, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) { - __block bool ok; - ok = (SecDbExec(dbconn, CFSTR("PRAGMA auto_vacuum = FULL"), error) && - SecDbExec(dbconn, CFSTR("PRAGMA journal_mode = WAL"), error)); + return SecDbCreate(path, 0600, true, true, true, true, 1, + ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) { + __block bool ok = true; + CFErrorRef localError = NULL; - if (ok && !SecDbWithSQL(dbconn, selectHashAlgorithmSQL /* expireSQL */, &localError, NULL) && CFErrorGetCode(localError) == SQLITE_ERROR) { + if (!SecDbWithSQL(dbconn, selectHashAlgorithmSQL /* expireSQL */, &localError, NULL) && CFErrorGetCode(localError) == SQLITE_ERROR) { /* SecDbWithSQL returns SQLITE_ERROR if the table we are preparing the above statement for doesn't exist. */ ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, error, ^(bool *commit) { ok &= SecDbExec(dbconn, @@ -299,16 +299,6 @@ static void _SecOCSPCacheReplaceResponse(SecOCSPCacheRef this, TrustdHealthAnalyticsLogErrorCodeForDatabase(TAOCSPCache, TAOperationWrite, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); CFReleaseNull(localError); - } else { - // force a vacuum when we modify the database - ok &= SecDbPerformWrite(this->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbExec(dbconn, CFSTR("VACUUM"), &localError); - if (!ok) { - secerror("_SecOCSPCacheAddResponse VACUUM failed: %@", localError); - TrustdHealthAnalyticsLogErrorCodeForDatabase(TAOCSPCache, TAOperationWrite, TAFatalError, - localError ? CFErrorGetCode(localError) : errSecInternalComponent); - } - }); } CFReleaseSafe(localError); } @@ -324,11 +314,7 @@ static SecOCSPResponseRef _SecOCSPCacheCopyMatching(SecOCSPCacheRef this, require(publicKey = SecCertificateGetPublicKeyData(request->issuer), errOut); require(issuer = SecCertificateCopyIssuerSequence(request->certificate), errOut); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - require(serial = SecCertificateCopySerialNumber(request->certificate, NULL), errOut); -#else - require(serial = SecCertificateCopySerialNumber(request->certificate), errOut); -#endif + require(serial = SecCertificateCopySerialNumberData(request->certificate, NULL), errOut); ok &= SecDbPerformRead(this->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbWithSQL(dbconn, selectHashAlgorithmSQL, &localError, ^bool(sqlite3_stmt *selectHash) { diff --git a/OSX/sec/securityd/SecOCSPRequest.c b/OSX/sec/securityd/SecOCSPRequest.c index c9add9ad..d7081b83 100644 --- a/OSX/sec/securityd/SecOCSPRequest.c +++ b/OSX/sec/securityd/SecOCSPRequest.c @@ -94,11 +94,7 @@ static CFDataRef _SecOCSPRequestCopyDEREncoding(SecOCSPRequestRef this) { and call SecDigestCreate here instead. */ issuerNameDigest = SecCertificateCopyIssuerSHA1Digest(this->certificate); issuerPubKeyDigest = SecCertificateCopyPublicKeySHA1Digest(this->issuer); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - serial = SecCertificateCopySerialNumber(this->certificate, NULL); -#else - serial = SecCertificateCopySerialNumber(this->certificate); -#endif + serial = SecCertificateCopySerialNumberData(this->certificate, NULL); /* build the CertID from those components */ certId->issuerNameHash.Length = CC_SHA1_DIGEST_LENGTH; diff --git a/OSX/sec/securityd/SecOCSPResponse.c b/OSX/sec/securityd/SecOCSPResponse.c index ba5634d9..2a38dfab 100644 --- a/OSX/sec/securityd/SecOCSPResponse.c +++ b/OSX/sec/securityd/SecOCSPResponse.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009,2012-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2008-2009,2012-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -329,8 +329,9 @@ exit: SecOCSPResponseRef SecOCSPResponseCreateWithID(CFDataRef ocspResponse, int64_t responseID) { SecAsn1OCSPResponse topResp = {}; - SecOCSPResponseRef this; + SecOCSPResponseRef this = NULL; + require(ocspResponse, errOut); require(this = (SecOCSPResponseRef)calloc(1, sizeof(struct __SecOCSPResponse)), errOut); require_noerr(SecAsn1CoderCreate(&this->coder), errOut); @@ -429,7 +430,7 @@ fini: errOut: #ifdef DEBUG { - CFStringRef hexResp = CFDataCopyHexString(this->data); + CFStringRef hexResp = (this) ? CFDataCopyHexString(this->data) : NULL; secdebug("ocsp", "bad ocsp response: %@", hexResp); CFReleaseSafe(hexResp); } @@ -531,11 +532,7 @@ SecOCSPSingleResponseRef SecOCSPResponseCopySingleResponse( if (!request) { return sr; } CFDataRef issuer = SecCertificateCopyIssuerSequence(request->certificate); const DERItem *publicKey = SecCertificateGetPublicKeyData(request->issuer); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - CFDataRef serial = SecCertificateCopySerialNumber(request->certificate, NULL); -#else - CFDataRef serial = SecCertificateCopySerialNumber(request->certificate); -#endif + CFDataRef serial = SecCertificateCopySerialNumberData(request->certificate, NULL); CFDataRef issuerNameHash = NULL; CFDataRef issuerPubKeyHash = NULL; SecAsn1Oid *algorithm = NULL; @@ -650,11 +647,7 @@ static bool SecOCSPResponseIsIssuer(SecOCSPResponseRef this, } if (shouldBeSigner) { -#if TARGET_OS_IPHONE - SecKeyRef key = SecCertificateCopyPublicKey(issuer); -#else - SecKeyRef key = SecCertificateCopyPublicKey_ios(issuer); -#endif + SecKeyRef key = SecCertificateCopyKey(issuer); if (key) { shouldBeSigner = SecOCSPResponseVerifySignature(this, key); ocspdDebug("ocsp response signature %sok", shouldBeSigner ? "" : "not "); diff --git a/OSX/sec/securityd/SecOCSPResponse.h b/OSX/sec/securityd/SecOCSPResponse.h index 63585a6a..1434439b 100644 --- a/OSX/sec/securityd/SecOCSPResponse.h +++ b/OSX/sec/securityd/SecOCSPResponse.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2009,2012-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2009,2012-2018 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, @@ -17,7 +17,7 @@ * 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@ */ diff --git a/OSX/sec/securityd/SecPinningDb.m b/OSX/sec/securityd/SecPinningDb.m index b2cc73e7..78df4780 100644 --- a/OSX/sec/securityd/SecPinningDb.m +++ b/OSX/sec/securityd/SecPinningDb.m @@ -30,6 +30,7 @@ #import #import #import +#import #if !TARGET_OS_BRIDGE #import @@ -75,6 +76,8 @@ const CFStringRef kSecPinningDbKeyRules = CFSTR("PinningRules"); @property (assign) SecDbRef db; @property dispatch_queue_t queue; @property NSURL *dbPath; +@property (assign) os_unfair_lock regexCacheLock; +@property NSMutableDictionary *regexCache; - (instancetype) init; - ( NSDictionary * _Nullable ) queryForDomain:(NSString *)domain; - ( NSDictionary * _Nullable ) queryForPolicyName:(NSString *)policyName; @@ -326,6 +329,8 @@ static inline bool isNSDictionary(id nsType) { ok &= SecDbPerformWrite(self->_db, &error, ^(SecDbConnectionRef dbconn) { ok &= [self updateDb:dbconn error:&error pinningList:pinningList updateSchema:NO updateContent:YES]; }); + /* We changed the database, so clear the database cache */ + [self clearCache]; }); if (!ok || error) { @@ -408,7 +413,7 @@ static inline bool isNSDictionary(id nsType) { #endif CFStringRef path = CFStringCreateWithCString(NULL, [_dbPath fileSystemRepresentation], kCFStringEncodingUTF8); - SecDbRef result = SecDbCreateWithOptions(path, mode, readWrite, readWrite, false, + SecDbRef result = SecDbCreate(path, mode, readWrite, readWrite, false, false, 1, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) { if (!SecOTAPKIIsSystemTrustd()) { /* Non-owner process can't update the db, but it should get a db connection. @@ -506,6 +511,8 @@ static void verify_create_path(const char *path) - (instancetype) init { if (self = [super init]) { _queue = dispatch_queue_create("Pinning DB Queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + _regexCache = [NSMutableDictionary dictionary]; + _regexCacheLock = OS_UNFAIR_LOCK_INIT; [self initializedDb]; } return self; @@ -515,6 +522,55 @@ static void verify_create_path(const char *path) CFReleaseNull(_db); } +/* MARK: DB Cache + * The cache is represented a dictionary defined as { suffix : { regex : resultsDictionary } } */ +- (void) clearCache { + os_unfair_lock_lock(&_regexCacheLock); + self.regexCache = [NSMutableDictionary dictionary]; + os_unfair_lock_unlock(&_regexCacheLock); +} + +- (void) addSuffixToCache:(NSString *)suffix entry:(NSDictionary *)entry { + os_unfair_lock_lock(&_regexCacheLock); + secinfo("SecPinningDb", "adding %llu entries for %@ to cache", (unsigned long long)[entry count], suffix); + self.regexCache[suffix] = entry; + os_unfair_lock_unlock(&_regexCacheLock); +} + +/* Because we iterate over all DB entries for a suffix, even if we find a match, we guarantee + * that the cache, if the cache has an entry for a suffix, it has all the entries for that suffix */ +- (BOOL) queryCacheForSuffix:(NSString *)suffix firstLabel:(NSString *)firstLabel results:(NSDictionary * __autoreleasing *)results{ + __block BOOL foundSuffix = NO; + os_unfair_lock_lock(&_regexCacheLock); + NSDictionary *cacheEntry; + if (NULL != (cacheEntry = self.regexCache[suffix])) { + foundSuffix = YES; + for (NSRegularExpression *regex in cacheEntry) { + NSUInteger numMatches = [regex numberOfMatchesInString:firstLabel + options:0 + range:NSMakeRange(0, [firstLabel length])]; + if (numMatches == 0) { + continue; + } + secinfo("SecPinningDb", "found matching rule in cache for %@.%@", firstLabel, suffix); + NSDictionary *resultDictionary = [cacheEntry objectForKey:regex]; + + /* Check the policyName for no-pinning settings */ + if ([self isPinningDisabled:resultDictionary[(__bridge NSString *)kSecPinningDbKeyPolicyName]]) { + continue; + } + + /* Return the pinning rules */ + if (results) { + *results = resultDictionary; + } + } + } + os_unfair_lock_unlock(&_regexCacheLock); + + return foundSuffix; +} + - (BOOL) isPinningDisabled:(NSString * _Nullable)policy { static dispatch_once_t once; static sec_action_t action; @@ -549,7 +605,7 @@ static void verify_create_path(const char *path) return pinningDisabled; } -- ( NSDictionary * _Nullable ) queryForDomain:(NSString *)domain { +- (NSDictionary * _Nullable) queryForDomain:(NSString *)domain { if (!_queue) { (void)[self init]; } if (!_db) { [self initializedDb]; } @@ -564,49 +620,66 @@ static void verify_create_path(const char *path) __block NSString *firstLabel = [domain substringToIndex:firstDot.location]; __block NSString *suffix = [domain substringFromIndex:(firstDot.location + 1)]; - /* Perform SELECT */ + /* Search cache */ + NSDictionary *cacheResult = nil; + if ([self queryCacheForSuffix:suffix firstLabel:firstLabel results:&cacheResult]) { + return cacheResult; + } + + /* Cache miss. Perform SELECT */ __block bool ok = true; __block CFErrorRef error = NULL; __block NSMutableArray *resultRules = [NSMutableArray array]; __block NSString *resultName = nil; + __block NSMutableDictionary *newCacheEntry = [NSMutableDictionary dictionary]; ok &= SecDbPerformRead(_db, &error, ^(SecDbConnectionRef dbconn) { ok &= SecDbWithSQL(dbconn, selectDomainSQL, &error, ^bool(sqlite3_stmt *selectDomain) { ok &= SecDbBindText(selectDomain, 1, [suffix UTF8String], [suffix length], SQLITE_TRANSIENT, &error); ok &= SecDbStep(dbconn, selectDomain, &error, ^(bool *stop) { - /* Match the labelRegex */ - const uint8_t *regex = sqlite3_column_text(selectDomain, 0); - if (!regex) { return; } - NSString *regexStr = [NSString stringWithUTF8String:(const char *)regex]; - if (!regexStr) { return; } - NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regexStr - options:NSRegularExpressionCaseInsensitive - error:nil]; - if (!regularExpression) { return; } - NSUInteger numMatches = [regularExpression numberOfMatchesInString:firstLabel - options:0 - range:NSMakeRange(0, [firstLabel length])]; - if (numMatches == 0) { - return; + @autoreleasepool { + /* Get the data from the entry */ + // First Label Regex + const uint8_t *regex = sqlite3_column_text(selectDomain, 0); + verify_action(regex, return); + NSString *regexStr = [NSString stringWithUTF8String:(const char *)regex]; + verify_action(regexStr, return); + NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regexStr + options:NSRegularExpressionCaseInsensitive + error:nil]; + verify_action(regularExpression, return); + // Policy name + const uint8_t *policyName = sqlite3_column_text(selectDomain, 1); + NSString *policyNameStr = [NSString stringWithUTF8String:(const char *)policyName]; + // Policies + NSData *xmlPolicies = [NSData dataWithBytes:sqlite3_column_blob(selectDomain, 2) length:sqlite3_column_bytes(selectDomain, 2)]; + verify_action(xmlPolicies, return); + id policies = [NSPropertyListSerialization propertyListWithData:xmlPolicies options:0 format:nil error:nil]; + verify_action(isNSArray(policies), return); + + /* Add to cache entry */ + [newCacheEntry setObject:@{(__bridge NSString*)kSecPinningDbKeyPolicyName:policyNameStr, + (__bridge NSString*)kSecPinningDbKeyRules:policies} + forKey:regularExpression]; + + /* Match the labelRegex */ + NSUInteger numMatches = [regularExpression numberOfMatchesInString:firstLabel + options:0 + range:NSMakeRange(0, [firstLabel length])]; + if (numMatches == 0) { + return; + } + secinfo("SecPinningDb", "found matching rule in DB for %@.%@", firstLabel, suffix); + + /* Check the policyName for no-pinning settings */ + if ([self isPinningDisabled:policyNameStr]) { + return; + } + + /* Add return data + * @@@ Assumes there is only one rule with matching suffix/label pairs. */ + [resultRules addObjectsFromArray:(NSArray *)policies]; + resultName = policyNameStr; } - secdebug("SecPinningDb", "found matching rule for %@.%@", firstLabel, suffix); - - /* Check the policyName for no-pinning settings */ - const uint8_t *policyName = sqlite3_column_text(selectDomain, 1); - NSString *policyNameStr = [NSString stringWithUTF8String:(const char *)policyName]; - if ([self isPinningDisabled:policyNameStr]) { - return; - } - - /* Deserialize the policies and return. - * @@@ Assumes there is only one rule with matching suffix/label pairs. */ - NSData *xmlPolicies = [NSData dataWithBytes:sqlite3_column_blob(selectDomain, 2) length:sqlite3_column_bytes(selectDomain, 2)]; - if (!xmlPolicies) { return; } - id policies = [NSPropertyListSerialization propertyListWithData:xmlPolicies options:0 format:nil error:nil]; - if (!isNSArray(policies)) { - return; - } - [resultRules addObjectsFromArray:(NSArray *)policies]; - resultName = policyNameStr; }); return ok; }); @@ -623,6 +696,12 @@ static void verify_create_path(const char *path) CFReleaseNull(error); } + /* Add new cache entry to cache. */ + if ([newCacheEntry count] > 0) { + [self addSuffixToCache:suffix entry:newCacheEntry]; + } + + /* Return results if found */ if ([resultRules count] > 0) { NSDictionary *results = @{(__bridge NSString*)kSecPinningDbKeyRules:resultRules, (__bridge NSString*)kSecPinningDbKeyPolicyName:resultName}; @@ -655,16 +734,18 @@ static void verify_create_path(const char *path) ok &= SecDbWithSQL(dbconn, selectPolicyNameSQL, &error, ^bool(sqlite3_stmt *selectPolicyName) { ok &= SecDbBindText(selectPolicyName, 1, [policyName UTF8String], [policyName length], SQLITE_TRANSIENT, &error); ok &= SecDbStep(dbconn, selectPolicyName, &error, ^(bool *stop) { - secdebug("SecPinningDb", "found matching rule for %@ policy", policyName); - - /* Deserialize the policies and return */ - NSData *xmlPolicies = [NSData dataWithBytes:sqlite3_column_blob(selectPolicyName, 0) length:sqlite3_column_bytes(selectPolicyName, 0)]; - if (!xmlPolicies) { return; } - id policies = [NSPropertyListSerialization propertyListWithData:xmlPolicies options:0 format:nil error:nil]; - if (!isNSArray(policies)) { - return; + @autoreleasepool { + secinfo("SecPinningDb", "found matching rule for %@ policy", policyName); + + /* Deserialize the policies and return */ + NSData *xmlPolicies = [NSData dataWithBytes:sqlite3_column_blob(selectPolicyName, 0) length:sqlite3_column_bytes(selectPolicyName, 0)]; + if (!xmlPolicies) { return; } + id policies = [NSPropertyListSerialization propertyListWithData:xmlPolicies options:0 format:nil error:nil]; + if (!isNSArray(policies)) { + return; + } + [resultRules addObjectsFromArray:(NSArray *)policies]; } - [resultRules addObjectsFromArray:(NSArray *)policies]; }); return ok; }); diff --git a/OSX/sec/securityd/SecPolicyServer.c b/OSX/sec/securityd/SecPolicyServer.c index ccdce836..03366feb 100644 --- a/OSX/sec/securityd/SecPolicyServer.c +++ b/OSX/sec/securityd/SecPolicyServer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2008-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -53,8 +52,6 @@ #include #include #include -#include -#include #include #include #include @@ -722,12 +719,7 @@ static void SecPolicyCheckBlackListedLeaf(SecPVCRef pvc, (0 == memcmp(UTN_USERFirst_Hardware_Normalized_Issuer, CFDataGetBytePtr(issuer), UTN_USERFirst_Hardware_Normalized_Issuer_len))) { - #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - CFDataRef serial = SecCertificateCopySerialNumber(cert, NULL); - #else - CFDataRef serial = SecCertificateCopySerialNumber(cert); - #endif - + CFDataRef serial = SecCertificateCopySerialNumberData(cert, NULL); if (serial) { CFIndex serial_length = CFDataGetLength(serial); const uint8_t *serial_ptr = CFDataGetBytePtr(serial); @@ -1052,10 +1044,6 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc, /* Prepare for Next Cert */ /* (a) (b) Done by SecCertificatePathVCVerifyPolicyTree */ /* (c)(d)(e)(f) Done by SecPathBuilderGetNext and SecCertificatePathVCVerify */ - //working_issuer_name = SecCertificateGetNormalizedSubjectContent(cert); - //working_public_key = SecCertificateCopyPublicKey(cert); - //working_public_key_parameters = SecCertificateCopyPublicKeyParameters(cert); - //working_public_key_algorithm = SecCertificateCopyPublicKeyAlgorithm(cert); #if POLICY_SUBTREES /* (g) If a name constraints extension is included in the certificate, modify the permitted_subtrees and excluded_subtrees state variables. */ @@ -1116,13 +1104,10 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc, /* Wrap up */ /* (a) (b) done by SecCertificatePathVCVerifyPolicyTree */ /* (c) */ - //working_public_key = SecCertificateCopyPublicKey(cert); /* (d) */ /* If the subjectPublicKeyInfo field of the certificate contains an algorithm field with null parameters or parameters are omitted, compare the certificate subjectPublicKey algorithm to the working_public_key_algorithm. If the certificate subjectPublicKey algorithm and the working_public_key_algorithm are different, set the working_public_key_parameters to null. */ - //working_public_key_parameters = SecCertificateCopyPublicKeyParameters(cert); /* (e) */ - //working_public_key_algorithm = SecCertificateCopyPublicKeyAlgorithm(cert); /* (f) Recognize and process any other critical extension present in the certificate n. Process any other recognized non-critical extension present in certificate n that is relevant to path processing. */ if (SecCertificateHasUnknownCriticalExtension(cert)) { /* Certificate contains one or more unknown critical extensions. */ @@ -1607,7 +1592,8 @@ static void SecPolicyCheckCT(SecPVCRef pvc) CFDataRef precertEntry = copy_precert_entry_from_chain(pvc); CFDataRef x509Entry = copy_x509_entry_from_chain(pvc); __block uint32_t trustedSCTCount = 0; - __block CFIndex totalSCTSize = 0; + __block CFAbsoluteTime issuanceTime = SecPVCGetVerifyTime(pvc); + TA_CTFailureReason failureReason = TA_CTNoFailure; // This eventually contain list of logs who validated the SCT. CFMutableDictionaryRef currentLogsValidatingScts = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -1617,10 +1603,23 @@ static void SecPolicyCheckCT(SecPVCRef pvc) __block bool at_least_one_currently_valid_external = 0; __block bool at_least_one_currently_valid_embedded = 0; + __block bool unknown_log = 0; + __block bool disqualified_log = 0; require(logsValidatingEmbeddedScts, out); require(currentLogsValidatingScts, out); + /* Skip if there are no SCTs. */ + require_action((embeddedScts && CFArrayGetCount(embeddedScts) > 0) || + (builderScts && CFArrayGetCount(builderScts) > 0) || + (ocspScts && CFArrayGetCount(ocspScts) > 0), + out, + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(pvc->builder); + if (analytics) { + analytics->ct_failure_reason = TA_CTNoSCTs; + } + ); + if(trustedLogs) { // Don't bother trying to validate SCTs if we don't have any trusted logs. if(embeddedScts && precertEntry) { // Don't bother if we could not get the precert. CFArrayForEach(embeddedScts, ^(const void *value){ @@ -1632,9 +1631,12 @@ static void SecPolicyCheckCT(SecPVCRef pvc) addValidatingLog(currentLogsValidatingScts, log, sct_at); at_least_one_currently_valid_embedded = true; trustedSCTCount++; + } else { + disqualified_log = true; } + } else { + unknown_log = true; } - totalSCTSize += CFDataGetLength(value); }); } @@ -1646,8 +1648,9 @@ static void SecPolicyCheckCT(SecPVCRef pvc) addValidatingLog(currentLogsValidatingScts, log, sct_at); at_least_one_currently_valid_external = true; trustedSCTCount++; + } else { + unknown_log = true; } - totalSCTSize += CFDataGetLength(value); }); } @@ -1659,10 +1662,13 @@ static void SecPolicyCheckCT(SecPVCRef pvc) addValidatingLog(currentLogsValidatingScts, log, sct_at); at_least_one_currently_valid_external = true; trustedSCTCount++; + } else { + unknown_log = true; } - totalSCTSize += CFDataGetLength(value); }); } + } else { + failureReason = TA_CTMissingLogs; } @@ -1679,15 +1685,12 @@ static void SecPolicyCheckCT(SecPVCRef pvc) */ - SecCertificatePathVCSetIsCT(SecPathBuilderGetPath(pvc->builder), false); - - if(at_least_one_currently_valid_external && CFDictionaryGetCount(currentLogsValidatingScts)>=2) { - SecCertificatePathVCSetIsCT(SecPathBuilderGetPath(pvc->builder), true); - } else if(at_least_one_currently_valid_embedded) { - __block CFAbsoluteTime issuanceTime = SecPVCGetVerifyTime(pvc); - __block int lifetime; // in Months - __block unsigned once_or_current_qualified_embedded = 0; + bool hasValidExternalSCT = (at_least_one_currently_valid_external && CFDictionaryGetCount(currentLogsValidatingScts)>=2); + bool hasValidEmbeddedSCT = (at_least_one_currently_valid_embedded); + SecCertificatePathVCRef path = SecPathBuilderGetPath(pvc->builder); + SecCertificatePathVCSetIsCT(path, false); + if (hasValidEmbeddedSCT) { /* Calculate issuance time based on timestamp of SCTs from current logs */ CFDictionaryForEach(currentLogsValidatingScts, ^(const void *key, const void *value) { CFDictionaryRef log = key; @@ -1700,8 +1703,19 @@ static void SecPolicyCheckCT(SecPVCRef pvc) } } }); + SecCertificatePathVCSetIssuanceTime(path, issuanceTime); + } + if (hasValidExternalSCT) { + /* Note: since external SCT validates this cert, we do not need to + override issuance time here. If the cert also has a valid embedded + SCT, issuanceTime will be calculated and set in the block above. */ + SecCertificatePathVCSetIsCT(path, true); + } else if (hasValidEmbeddedSCT) { + __block int lifetime; // in Months + __block unsigned once_or_current_qualified_embedded = 0; /* Count Logs */ + __block bool failed_once_check = false; CFDictionaryForEach(logsValidatingEmbeddedScts, ^(const void *key, const void *value) { CFDictionaryRef log = key; CFDateRef ts = value; @@ -1712,6 +1726,8 @@ static void SecPolicyCheckCT(SecPVCRef pvc) issuanceTime < CFDateGetAbsoluteTime(expiry)) { // at the time of issuance.) once_or_current_qualified_embedded++; trustedSCTCount++; + } else { + failed_once_check = true; } }); @@ -1737,7 +1753,32 @@ static void SecPolicyCheckCT(SecPVCRef pvc) } if(once_or_current_qualified_embedded >= requiredEmbeddedSctsCount){ - SecCertificatePathVCSetIsCT(SecPathBuilderGetPath(pvc->builder), true); + SecCertificatePathVCSetIsCT(path, true); + } else { + /* Not enough "once or currently qualified" SCTs */ + if (failed_once_check) { + failureReason = TA_CTEmbeddedNotEnoughDisqualified; + } else if (unknown_log) { + failureReason = TA_CTEmbeddedNotEnoughUnknown; + } else { + failureReason = TA_CTEmbeddedNotEnough; + } + } + } else if (!at_least_one_currently_valid_embedded && !at_least_one_currently_valid_external) { + /* No currently valid SCTs */ + if (disqualified_log) { + failureReason = TA_CTNoCurrentSCTsDisqualifiedLog; + } else if (unknown_log) { + failureReason = TA_CTNoCurrentSCTsUnknownLog; + } + } else if (at_least_one_currently_valid_external) { + /* One presented current SCT but failed total current check */ + if (disqualified_log) { + failureReason = TA_CTPresentedNotEnoughDisqualified; + } else if (unknown_log) { + failureReason = TA_CTPresentedNotEnoughUnknown; + } else { + failureReason = TA_CTPresentedNotEnough; } } @@ -1760,11 +1801,14 @@ static void SecPolicyCheckCT(SecPVCRef pvc) } /* Report how many of those SCTs were once or currently qualified */ analytics->number_trusted_scts = trustedSCTCount; - /* Report the total number of bytes in the SCTs */ - analytics->total_sct_size = totalSCTSize; /* Report how many SCTs we got */ analytics->number_scts = sctCount; - + /* Why we failed */ + analytics->ct_failure_reason = failureReason; + /* Only one current SCT -- close to failure */ + if (CFDictionaryGetCount(currentLogsValidatingScts) == 1) { + analytics->ct_one_current = true; + } out: CFReleaseSafe(logsValidatingEmbeddedScts); CFReleaseSafe(currentLogsValidatingScts); @@ -2064,7 +2108,7 @@ __PC_ADD_CHECK_##PATHCHECK(NAME) ********************************************************/ void SecPVCInit(SecPVCRef pvc, SecPathBuilderRef builder, CFArrayRef policies) { - secdebug("alloc", "%p", pvc); + secdebug("alloc", "pvc %p", pvc); // Weird logging policies crashes. //secdebug("policy", "%@", policies); @@ -2085,7 +2129,7 @@ void SecPVCInit(SecPVCRef pvc, SecPathBuilderRef builder, CFArrayRef policies) { } void SecPVCDelete(SecPVCRef pvc) { - secdebug("alloc", "%p", pvc); + secdebug("alloc", "delete pvc %p", pvc); CFReleaseNull(pvc->policies); CFReleaseNull(pvc->details); CFReleaseNull(pvc->leafDetails); @@ -3040,6 +3084,70 @@ static bool SecPVCIsSSLServerAuthenticationPolicy(SecPVCRef pvc) { return false; } +/* ASSUMPTIONS: + 1. SecPVCCheckRequireCTConstraints must be called after SecPolicyCheckCT, + so earliest issuance time has already been obtained from SCTs. + 2. If the issuance time value is 0 (i.e. 2001-01-01) or earlier, we + assume it was not set, and thus we did not have CT info. +*/ +static void SecPVCCheckRequireCTConstraints(SecPVCRef pvc) { + SecCertificatePathVCRef path = (pvc) ? SecPathBuilderGetPath(pvc->builder) : NULL; + if (!path) { + return; + } + /* If we are evaluating for a SSL server authentication policy, make sure + SCT issuance time is prior to the earliest not-after date constraint. + Note that CT will already be required if there is a not-after date + constraint present (set in SecRVCProcessValidDateConstraints). + */ + if (SecPVCIsSSLServerAuthenticationPolicy(pvc)) { + CFIndex ix, certCount = SecCertificatePathVCGetCount(path); + SecCertificateRef certificate = SecPathBuilderGetCertificateAtIndex(pvc->builder, 0); + CFAbsoluteTime earliestNotAfter = 31556908800.0; /* default: 3001-01-01 00:00:00-0000 */ + CFAbsoluteTime issuanceTime = SecCertificatePathVCIssuanceTime(path); + if (issuanceTime <= 0) { + /* if not set (or prior to 2001-01-01), use leaf's not-before time. */ + issuanceTime = SecCertificateNotValidBefore(certificate); + } + for (ix = 0; ix < certCount; ix++) { + SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, ix); + if (!rvc || !rvc->valid_info || !rvc->valid_info->hasDateConstraints || !rvc->valid_info->notAfterDate) { + continue; + } + /* Found CA certificate with a not-after date constraint. */ + CFAbsoluteTime caNotAfter = CFDateGetAbsoluteTime(rvc->valid_info->notAfterDate); + if (caNotAfter < earliestNotAfter) { + earliestNotAfter = caNotAfter; + } + if (issuanceTime > earliestNotAfter) { + /* Issuance time violates the not-after date constraint. */ + secnotice("rvc", "certificate issuance time (%f) is later than allowed value (%f)", + issuanceTime, earliestNotAfter); + SecRVCSetValidDeterminedErrorResult(rvc); + break; + } + } + } + /* If path is CT validated, nothing further to do here. */ + if (SecCertificatePathVCIsCT(path)) { + return; + } + + /* Path is not CT validated, so check if CT was required. */ + SecPathCTPolicy ctp = SecCertificatePathVCRequiresCT(path); + if (ctp <= kSecPathCTNotRequired || !SecPVCIsSSLServerAuthenticationPolicy(pvc)) { + return; + } + /* CT was required. Error is always set on leaf certificate. */ + SecPVCSetResultForced(pvc, kSecPolicyCheckCTRequired, + 0, kCFBooleanFalse, true); + if (ctp != kSecPathCTRequiredOverridable) { + /* Normally kSecPolicyCheckCTRequired is recoverable, + so need to manually change trust result here. */ + pvc->result = kSecTrustResultFatalTrustFailure; + } +} + /* AUDIT[securityd](done): policy->_options is a caller provided dictionary, only its cf type has been checked. @@ -3105,19 +3213,10 @@ void SecPVCPathChecks(SecPVCRef pvc) { } /* Check that this path meets CT constraints. */ - if (!SecCertificatePathVCIsCT(path)) { - SecPathCTPolicy ctp = SecCertificatePathVCRequiresCT(path); - if (ctp > kSecPathCTNotRequired && SecPVCIsSSLServerAuthenticationPolicy(pvc)) { - /* CT was required. Error is always set on leaf certificate. */ - SecPVCSetResultForced(pvc, kSecPolicyCheckCTRequired, - 0, kCFBooleanFalse, true); - if (ctp != kSecPathCTRequiredOverridable) { - /* Normally kSecPolicyCheckCTRequired is recoverable, - so need to manually change trust result here. */ - pvc->result = kSecTrustResultFatalTrustFailure; - } - } - } + SecPVCCheckRequireCTConstraints(pvc); + + /* Check that this path meets known-intermediate constraints. */ + SecPathBuilderCheckKnownIntermediateConstraints(pvc->builder); secdebug("policy", "end %strusted path: %@", (SecPVCIsOkResult(pvc) ? "" : "not "), SecPathBuilderGetPath(pvc->builder)); @@ -3150,7 +3249,7 @@ void SecPVCPathCheckRevocationResponsesReceived(SecPVCRef pvc) { } /* Do we have a definitive Valid revocation result for this cert? */ if (SecRVCHasDefinitiveValidInfo(rvc) && SecRVCHasRevokedValidInfo(rvc)) { - SecRVCSetRevokedResult(rvc); + SecRVCSetValidDeterminedErrorResult(rvc); } } } diff --git a/OSX/sec/securityd/SecRevocationDb.c b/OSX/sec/securityd/SecRevocationDb.c index be54506d..24f0084d 100644 --- a/OSX/sec/securityd/SecRevocationDb.c +++ b/OSX/sec/securityd/SecRevocationDb.c @@ -27,7 +27,6 @@ */ #include -#include #include #include #include @@ -39,12 +38,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include "utilities/debugging.h" @@ -64,13 +65,14 @@ #include #include #include +#include #include #include #include -static CFStringRef kValidUpdateProdServer = CFSTR("valid.apple.com"); -static CFStringRef kValidUpdateCarryServer = CFSTR("valid.apple.com/carry"); +const CFStringRef kValidUpdateProdServer = CFSTR("valid.apple.com"); +const CFStringRef kValidUpdateCarryServer = CFSTR("valid.apple.com/carry"); static CFStringRef kSecPrefsDomain = CFSTR("com.apple.security"); static CFStringRef kUpdateServerKey = CFSTR("ValidUpdateServer"); @@ -93,6 +95,7 @@ typedef CF_OPTIONS(CFOptionFlags, SecValidInfoFlags) { kSecValidInfoDateConstraints = 1u << 7, kSecValidInfoNameConstraints = 1u << 8, kSecValidInfoPolicyConstraints = 1u << 9, + kSecValidInfoNoCAv2Check = 1u << 10, }; /* minimum update interval */ @@ -111,20 +114,23 @@ typedef CF_OPTIONS(CFOptionFlags, SecValidInfoFlags) { #define isDbOwner SecOTAPKIIsSystemTrustd +#define kSecRevocationDbChanged "com.apple.trustd.valid.db-changed" + /* database schema version v1 = initial version v2 = fix for group entry transitions v3 = handle optional entries in update dictionaries v4 = add db_format and db_source entries v5 = add date constraints table, with updated group flags + v6 = explicitly set autovacuum and journal modes at db creation Note: kSecRevocationDbMinSchemaVersion is the lowest version whose results can be used. This allows revocation results to be obtained from an existing db before the next update interval occurs, at which time we'll update to the current version (kSecRevocationDbSchemaVersion). */ -#define kSecRevocationDbSchemaVersion 5 /* current version we support */ -#define kSecRevocationDbMinSchemaVersion 5 /* minimum version we can use */ +#define kSecRevocationDbSchemaVersion 6 /* current version we support */ +#define kSecRevocationDbMinSchemaVersion 6 /* minimum version we can use */ /* update file format */ @@ -137,22 +143,51 @@ CF_ENUM(CFIndex) { #define kSecRevocationDbUpdateFormat 3 /* current version we support */ #define kSecRevocationDbMinUpdateFormat 2 /* minimum version we can use */ +#define kSecRevocationDbCacheSize 100 + +typedef struct __SecRevocationDb *SecRevocationDbRef; +struct __SecRevocationDb { + SecDbRef db; + dispatch_queue_t update_queue; + bool updateInProgress; + bool unsupportedVersion; + bool changed; + CFMutableArrayRef info_cache_list; + CFMutableDictionaryRef info_cache; + os_unfair_lock info_cache_lock; +}; + +typedef struct __SecRevocationDbConnection *SecRevocationDbConnectionRef; +struct __SecRevocationDbConnection { + SecRevocationDbRef db; + SecDbConnectionRef dbconn; + CFIndex precommitVersion; + CFIndex precommitDbVersion; + bool fullUpdate; +}; + bool SecRevocationDbVerifyUpdate(void *update, CFIndex length); -CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion); -void SecRevocationDbApplyUpdate(CFDictionaryRef update, CFIndex version); +bool SecRevocationDbIngestUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef update, CFIndex chunkVersion, CFIndex *outVersion, CFErrorRef *error); +bool _SecRevocationDbApplyUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef update, CFIndex version, CFErrorRef *error); CFAbsoluteTime SecRevocationDbComputeNextUpdateTime(CFIndex updateInterval); -bool SecRevocationDbSetVersion(CFIndex version); -bool SecRevocationDbSetSchemaVersion(CFIndex dbversion); -bool SecRevocationDbUpdateSchema(void); +bool SecRevocationDbUpdateSchema(SecRevocationDbRef rdb); CFIndex SecRevocationDbGetUpdateFormat(void); -void SecRevocationDbSetUpdateFormat(CFIndex dbformat); -void SecRevocationDbSetUpdateSource(CFStringRef source); +bool _SecRevocationDbSetUpdateSource(SecRevocationDbConnectionRef dbc, CFStringRef source, CFErrorRef *error); +bool SecRevocationDbSetUpdateSource(SecRevocationDbRef rdb, CFStringRef source); CFStringRef SecRevocationDbCopyUpdateSource(void); -void SecRevocationDbSetNextUpdateTime(CFAbsoluteTime nextUpdate); +bool SecRevocationDbSetNextUpdateTime(CFAbsoluteTime nextUpdate, CFErrorRef *error); CFAbsoluteTime SecRevocationDbGetNextUpdateTime(void); dispatch_queue_t SecRevocationDbGetUpdateQueue(void); -void SecRevocationDbRemoveAllEntries(void); +bool _SecRevocationDbRemoveAllEntries(SecRevocationDbConnectionRef dbc, CFErrorRef *error); void SecRevocationDbReleaseAllConnections(void); +static void SecRevocationDbWith(void(^dbJob)(SecRevocationDbRef db)); +static bool SecRevocationDbPerformWrite(SecRevocationDbRef rdb, CFErrorRef *error, bool(^writeJob)(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError)); +static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbConnectionRef dbc, int64_t groupId, SecValidInfoFlags *flags, CFDataRef *data, CFErrorRef *error); +static bool _SecRevocationDbSetVersion(SecRevocationDbConnectionRef dbc, CFIndex version, CFErrorRef *error); +static int64_t _SecRevocationDbGetVersion(SecRevocationDbConnectionRef dbc, CFErrorRef *error); +static int64_t _SecRevocationDbGetSchemaVersion(SecRevocationDbRef rdb, SecRevocationDbConnectionRef dbc, CFErrorRef *error); +static void SecRevocationDbResetCaches(void); +static SecRevocationDbConnectionRef SecRevocationDbConnectionInit(SecRevocationDbRef db, SecDbConnectionRef dbconn, CFErrorRef *error); static CFDataRef copyInflatedData(CFDataRef data) { @@ -198,64 +233,6 @@ static CFDataRef copyInflatedData(CFDataRef data) { return (CFDataRef)outData; } -static CFDataRef copyInflatedDataToFile(CFDataRef data, char *fileName) { - if (!data) { - return NULL; - } - z_stream zs; - memset(&zs, 0, sizeof(zs)); - /* 32 is a magic value which enables automatic header detection - of gzip or zlib compressed data. */ - if (inflateInit2(&zs, 32+MAX_WBITS) != Z_OK) { - return NULL; - } - zs.next_in = (UInt8 *)(CFDataGetBytePtr(data)); - zs.avail_in = (uInt)CFDataGetLength(data); - - (void)remove(fileName); /* We need an empty file to start */ - int fd; - off_t off; - fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 0644); - if (fd < 0 || (off = lseek(fd, 0, SEEK_SET)) < 0) { - secerror("unable to open %s (errno %d)", fileName, errno); - if (fd >= 0) { - close(fd); - } - return NULL; - } - - CFIndex buf_sz = malloc_good_size(zs.avail_in ? zs.avail_in : 1024 * 4); - unsigned char *buf = malloc(buf_sz); - int rc; - do { - zs.next_out = (Bytef*)buf; - zs.avail_out = (uInt)buf_sz; - rc = inflate(&zs, 0); - if (off < (int64_t)zs.total_out) { - off = write(fd, buf, (size_t)zs.total_out - (size_t)off); - } - } while (rc == Z_OK); - close(fd); - - inflateEnd(&zs); - - if (buf) { - free(buf); - } - if (rc != Z_STREAM_END) { - (void)remove(fileName); - return NULL; - } - - /* Now return an mmapped version of that data */ - CFDataRef outData = NULL; - if ((rc = readValidFile(fileName, &outData)) != 0) { - secerror("unable to read and map %s (errno %d)", fileName, rc); - CFReleaseNull(outData); - } - return outData; -} - static CFDataRef copyDeflatedData(CFDataRef data) { if (!data) { return NULL; @@ -348,17 +325,6 @@ errOut: return rtn; } -static void unmapData(CFDataRef CF_CONSUMED data) { - if (data) { - int rtn = munmap((void *)CFDataGetBytePtr(data), CFDataGetLength(data)); - if (rtn != 0) { - secerror("unable to unmap %ld bytes at %p (error %d)", CFDataGetLength(data), CFDataGetBytePtr(data), rtn); - } - - } - CFReleaseNull(data); -} - static bool removeFileWithSuffix(const char *basepath, const char *suffix) { bool result = false; char *path = NULL; @@ -379,6 +345,25 @@ static bool removeFileWithSuffix(const char *basepath, const char *suffix) { return result; } +static CFDataRef CF_RETURNS_RETAINED cfToHexData(CFDataRef data, bool prependWildcard) { + if (!isData(data)) { return NULL; } + CFIndex len = CFDataGetLength(data) * 2; + CFMutableStringRef hex = CFStringCreateMutable(NULL, len+1); + static const char* digits[]={ + "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; + if (prependWildcard) { + CFStringAppendCString(hex, "%", 1); + } + const uint8_t* p = CFDataGetBytePtr(data); + for (CFIndex i = 0; i < CFDataGetLength(data); i++) { + CFStringAppendCString(hex, digits[p[i] >> 4], 1); + CFStringAppendCString(hex, digits[p[i] & 0xf], 1); + } + CFDataRef result = CFStringCreateExternalRepresentation(NULL, hex, kCFStringEncodingUTF8, 0); + CFReleaseSafe(hex); + return result; +} + // MARK: - // MARK: SecValidUpdate @@ -404,11 +389,12 @@ static CFIndex gLastVersion = 0; Note: the difference between g2 and g3 format is the addition of the 4-byte count in (2a). */ -static bool SecValidUpdateProcessData(CFIndex format, CFDataRef updateData) { +static bool SecValidUpdateProcessData(SecRevocationDbConnectionRef dbc, CFIndex format, CFDataRef updateData, CFErrorRef *error) { + bool result = false; if (!updateData || format < 2) { - return false; + SecError(errSecParam, error, CFSTR("SecValidUpdateProcessData: invalid update format")); + return result; } - bool result = false; CFIndex version = 0; CFIndex interval = 0; const UInt8* p = CFDataGetBytePtr(updateData); @@ -416,6 +402,7 @@ static bool SecValidUpdateProcessData(CFIndex format, CFDataRef updateData) { /* make sure there is enough data to contain length and count */ if (bytesRemaining < ((CFIndex)sizeof(uint32_t) * 2)) { secinfo("validupdate", "Skipping property list creation (length %ld is too short)", (long)bytesRemaining); + SecError(errSecParam, error, CFSTR("SecValidUpdateProcessData: data length is too short")); return result; } /* get length of signed data */ @@ -435,10 +422,13 @@ static bool SecValidUpdateProcessData(CFIndex format, CFDataRef updateData) { if (dataLength > bytesRemaining) { secinfo("validupdate", "Skipping property list creation (dataLength=%ld, bytesRemaining=%ld)", (long)dataLength, (long)bytesRemaining); + SecError(errSecParam, error, CFSTR("SecValidUpdateProcessData: data longer than expected")); return result; } /* process each chunked plist */ + bool ok = true; + CFErrorRef localError = NULL; uint32_t plistProcessed = 0; while (plistCount > 0 && bytesRemaining > 0) { CFPropertyListRef propertyList = NULL; @@ -451,10 +441,6 @@ static bool SecValidUpdateProcessData(CFIndex format, CFDataRef updateData) { --plistCount; ++plistProcessed; - /* We're about to use a lot of memory for the plist -- go active so we don't get jetsammed */ - os_transaction_t transaction; - transaction = os_transaction_create("com.apple.trustd.valid"); - if (plistLength <= bytesRemaining) { CFDataRef data = CFDataCreateWithBytesNoCopy(NULL, p, plistLength, kCFAllocatorNull); propertyList = CFPropertyListCreateWithData(NULL, data, kCFPropertyListImmutable, NULL, NULL); @@ -463,9 +449,10 @@ static bool SecValidUpdateProcessData(CFIndex format, CFDataRef updateData) { if (isDictionary(propertyList)) { secdebug("validupdate", "Ingesting plist chunk %u of %u, length: %u", plistProcessed, plistTotal, plistLength); - CFIndex curVersion = SecRevocationDbIngestUpdate((CFDictionaryRef)propertyList, version); + CFIndex curVersion = -1; + ok = ok && SecRevocationDbIngestUpdate(dbc, (CFDictionaryRef)propertyList, version, &curVersion, &localError); if (plistProcessed == 1) { - version = curVersion; + dbc->precommitVersion = version = curVersion; // get server-provided interval CFTypeRef value = (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)propertyList, CFSTR("check-again")); @@ -473,26 +460,26 @@ static bool SecValidUpdateProcessData(CFIndex format, CFDataRef updateData) { CFNumberGetValue((CFNumberRef)value, kCFNumberCFIndexType, &interval); } } - if (curVersion < 0) { + if (ok && curVersion < 0) { plistCount = 0; // we already had this version; skip remaining plists result = true; } } else { secinfo("validupdate", "Failed to deserialize update chunk %u of %u", plistProcessed, plistTotal); + SecError(errSecParam, error, CFSTR("SecValidUpdateProcessData: failed to get update chunk")); if (plistProcessed == 1) { gNextUpdate = SecRevocationDbComputeNextUpdateTime(0); } } /* All finished with this property list */ CFReleaseSafe(propertyList); - os_release(transaction); bytesRemaining -= plistLength; p += plistLength; } - if (version > 0) { + if (ok && version > 0) { secdebug("validupdate", "Update received: v%ld", (long)version); gLastVersion = version; gNextUpdate = SecRevocationDbComputeNextUpdateTime(interval); @@ -500,9 +487,7 @@ static bool SecValidUpdateProcessData(CFIndex format, CFDataRef updateData) { result = true; } - // remember next update time in case of restart - SecRevocationDbSetNextUpdateTime(gNextUpdate); - + (void) CFErrorPropagate(localError, error); return result; } @@ -512,65 +497,95 @@ void SecValidUpdateVerifyAndIngest(CFDataRef updateData, CFStringRef updateServe return; } /* Verify CMS signature on signed data */ - if (SecRevocationDbVerifyUpdate((void *)CFDataGetBytePtr(updateData), CFDataGetLength(updateData))) { - CFStringRef dbSource = SecRevocationDbCopyUpdateSource(); - if (dbSource && updateServer && (kCFCompareEqualTo != CFStringCompare(dbSource, updateServer, - kCFCompareCaseInsensitive))) { - secnotice("validupdate", "switching db source from \"%@\" to \"%@\"", dbSource, updateServer); - } - CFReleaseNull(dbSource); - if (fullUpdate) { - /* Must completely replace existing database contents */ - SecRevocationDbRemoveAllEntries(); - SecRevocationDbSetUpdateSource(updateServer); - } - bool result = SecValidUpdateProcessData(kSecValidUpdateFormatG3, updateData); - if (!result) { - // Try g2 update format as a fallback if we failed to read g3 - result = SecValidUpdateProcessData(kSecValidUpdateFormatG2, updateData); - } - if (!result) { - secerror("failed to process valid update"); - TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, errSecDecode); - } else { - TrustdHealthAnalyticsLogSuccess(TAEventValidUpdate); - } - } else { + if (!SecRevocationDbVerifyUpdate((void *)CFDataGetBytePtr(updateData), CFDataGetLength(updateData))) { secerror("failed to verify valid update"); TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, errSecVerifyFailed); + return; } -} + /* Read current update source from database. */ + CFStringRef dbSource = SecRevocationDbCopyUpdateSource(); + if (dbSource && updateServer && (kCFCompareEqualTo != CFStringCompare(dbSource, updateServer, + kCFCompareCaseInsensitive))) { + secnotice("validupdate", "switching db source from \"%@\" to \"%@\"", dbSource, updateServer); + } + CFReleaseNull(dbSource); -static bool SecValidDatabaseFromCompressed(CFDataRef CF_CONSUMED data) { - if (!data) { return false; } + /* Ingest the update. This is now performed under a single immediate write transaction, + so other writers are blocked (but not other readers), and the changes can be rolled back + in their entirety if any error occurs. */ + __block bool ok = true; + __block CFErrorRef localError = NULL; + __block SecRevocationDbConnectionRef dbc = NULL; + SecRevocationDbWith(^(SecRevocationDbRef rdb) { + ok &= SecRevocationDbPerformWrite(rdb, &localError, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + if (fullUpdate) { + /* Must completely replace existing database contents */ + secdebug("validupdate", "starting to process full update; clearing database"); + ok = ok && _SecRevocationDbRemoveAllEntries(dbc,blockError); + ok = ok && _SecRevocationDbSetUpdateSource(dbc, updateServer, blockError); + if (dbc) { + dbc->precommitVersion = 0; + dbc->fullUpdate = true; + } + } + ok = ok && SecValidUpdateProcessData(dbc, kSecValidUpdateFormatG3, updateData, blockError); + if (!ok) { + secerror("failed to process valid update: %@", blockError ? *blockError : NULL); + TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, errSecDecode); + } else { + TrustdHealthAnalyticsLogSuccess(TAEventValidUpdate); + } + return ok; + }); + if (rdb->changed) { + rdb->changed = false; + /* signal other trustd instances that the database has been updated */ + notify_post(kSecRevocationDbChanged); + } + }); - secdebug("validupdate", "read %ld bytes from file", (long)CFDataGetLength(data)); + /* remember next update time in case of restart (separate write transaction) */ + (void) SecRevocationDbSetNextUpdateTime(gNextUpdate, NULL); - /* We're about to use a lot of memory for the uncompressed update -- go active */ - os_transaction_t transaction; - transaction = os_transaction_create("com.apple.trustd.valid"); + if (dbc) { + free(dbc); + } + CFReleaseSafe(localError); +} - /* Expand the database */ - __block CFDataRef inflatedData = NULL; - WithPathInRevocationInfoDirectory(CFSTR(kSecRevocationDbFileName), ^(const char *dbPath) { - inflatedData = copyInflatedDataToFile(data, (char *)dbPath); - secdebug("validupdate", "data expanded: %ld bytes", (long)CFDataGetLength(inflatedData)); - }); - unmapData(data); - os_release(transaction); +static bool SecValidUpdateForceReplaceDatabase(void) { + bool result = false; - if (inflatedData) { - unmapData(inflatedData); + // write semaphore file that we will pick up when we next launch + char *semPathBuf = NULL; + asprintf(&semPathBuf, "%s/%s", kSecRevocationBasePath, kSecRevocationDbReplaceFile); + if (semPathBuf) { + struct stat sb; + int fd = open(semPathBuf, O_WRONLY | O_CREAT, DEFFILEMODE); + if (fd == -1 || fstat(fd, &sb)) { + secnotice("validupdate", "unable to write %s", semPathBuf); + } else { + result = true; + } + if (fd >= 0) { + close(fd); + } + free(semPathBuf); + } + if (result) { + // exit as gracefully as possible so we can replace the database + secnotice("validupdate", "process exiting to replace db file"); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + xpc_transaction_exit_clean(); + }); } - return true; + return result; } static bool SecValidUpdateSatisfiedLocally(CFStringRef server, CFIndex version, bool safeToReplace) { __block bool result = false; - CFDataRef data = NULL; SecOTAPKIRef otapkiRef = NULL; bool relaunching = false; - int rtn = 0; static int sNumLocalUpdates = 0; // if we've replaced the database with a local asset twice in a row, @@ -605,29 +620,7 @@ static bool SecValidUpdateSatisfiedLocally(CFStringRef server, CFIndex version, // replace database only if safe to do so (i.e. called at startup) if (!safeToReplace) { - // write semaphore file that we will pick up when we next launch - char *semPathBuf = NULL; - asprintf(&semPathBuf, "%s/%s", kSecRevocationBasePath, kSecRevocationDbReplaceFile); - if (semPathBuf) { - struct stat sb; - int fd = open(semPathBuf, O_WRONLY | O_CREAT, DEFFILEMODE); - if (fd == -1 || fstat(fd, &sb)) { - secnotice("validupdate", "unable to write %s", semPathBuf); - } else { - relaunching = true; - } - if (fd >= 0) { - close(fd); - } - free(semPathBuf); - } - if (relaunching) { - // exit as gracefully as possible so we can replace the database - secnotice("validupdate", "process exiting to replace db file"); - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - xpc_transaction_exit_clean(); - }); - } + relaunching = SecValidUpdateForceReplaceDatabase(); goto updateExit; } @@ -646,33 +639,18 @@ static bool SecValidUpdateSatisfiedLocally(CFStringRef server, CFIndex version, } }); } - if (result) { - goto updateExit; - } - - // see if compressed database asset is available - if (validDbPathBuf) { - char *validDbCmpPathBuf = NULL; - asprintf(&validDbCmpPathBuf, "%s%s", validDbPathBuf, ".gz"); - if (validDbCmpPathBuf) { - secdebug("validupdate", "will read data from \"%s\"", validDbCmpPathBuf); - if ((rtn = readValidFile(validDbCmpPathBuf, &data)) != 0) { - unmapData(data); - data = NULL; - secnotice("validupdate", "readValidFile error %d", rtn); - } - free(validDbCmpPathBuf); - } - } - result = SecValidDatabaseFromCompressed(data); updateExit: CFReleaseNull(otapkiRef); if (result) { sNumLocalUpdates++; gLastVersion = SecRevocationDbGetVersion(); - SecRevocationDbSetUpdateSource(server); - SecRevocationDbUpdateSchema(); + // note: snapshot should already have latest schema and production source, + // but set it here anyway so we don't keep trying to replace the db. + SecRevocationDbWith(^(SecRevocationDbRef db) { + (void)SecRevocationDbSetUpdateSource(db, server); + (void)SecRevocationDbUpdateSchema(db); + }); gUpdateStarted = 0; secdebug("validupdate", "local update to g%ld/v%ld complete at %f", (long)SecRevocationDbGetUpdateFormat(), (long)gLastVersion, @@ -721,6 +699,7 @@ static CFStringRef SecRevocationDbGetDefaultServer(void) { void SecRevocationDbInitialize() { if (!isDbOwner()) { return; } + os_transaction_t transaction = os_transaction_create("com.apple.trustd.valid.initialize"); __block bool initializeDb = false; /* create base path if it doesn't exist */ @@ -756,6 +735,7 @@ void SecRevocationDbInitialize() { }); if (!initializeDb) { + os_release(transaction); return; /* database exists and doesn't need replacing */ } @@ -771,6 +751,7 @@ void SecRevocationDbInitialize() { #endif } CFReleaseSafe(value); + os_release(transaction); } @@ -782,6 +763,8 @@ void SecRevocationDbInitialize() { ====================================================================== */ +CFGiblisWithCompareFor(SecValidInfo); + static SecValidInfoRef SecValidInfoCreate(SecValidInfoFormat format, CFOptionFlags flags, bool isOnList, @@ -793,7 +776,7 @@ static SecValidInfoRef SecValidInfoCreate(SecValidInfoFormat format, CFDataRef nameConstraints, CFDataRef policyConstraints) { SecValidInfoRef validInfo; - validInfo = (SecValidInfoRef)calloc(1, sizeof(struct __SecValidInfo)); + validInfo = CFTypeAllocate(SecValidInfo, struct __SecValidInfo, kCFAllocatorDefault); if (!validInfo) { return NULL; } CFRetainSafe(certHash); @@ -814,7 +797,7 @@ static SecValidInfoRef SecValidInfoCreate(SecValidInfoFormat format, validInfo->checkOCSP = (flags & kSecValidInfoCheckOCSP); validInfo->knownOnly = (flags & kSecValidInfoKnownOnly); validInfo->requireCT = (flags & kSecValidInfoRequireCT); - validInfo->noCACheck = (flags & kSecValidInfoNoCACheck); + validInfo->noCACheck = (flags & kSecValidInfoNoCAv2Check); validInfo->overridable = (flags & kSecValidInfoOverridable); validInfo->hasDateConstraints = (flags & kSecValidInfoDateConstraints); validInfo->hasNameConstraints = (flags & kSecValidInfoNameConstraints); @@ -827,7 +810,8 @@ static SecValidInfoRef SecValidInfoCreate(SecValidInfoFormat format, return validInfo; } -void SecValidInfoRelease(SecValidInfoRef validInfo) { +static void SecValidInfoDestroy(CFTypeRef cf) { + SecValidInfoRef validInfo = (SecValidInfoRef)cf; if (validInfo) { CFReleaseNull(validInfo->certHash); CFReleaseNull(validInfo->issuerHash); @@ -836,7 +820,6 @@ void SecValidInfoRelease(SecValidInfoRef validInfo) { CFReleaseNull(validInfo->notAfterDate); CFReleaseNull(validInfo->nameConstraints); CFReleaseNull(validInfo->policyConstraints); - free(validInfo); } } @@ -857,6 +840,30 @@ void SecValidInfoSetAnchor(SecValidInfoRef validInfo, SecCertificateRef anchor) validInfo->anchorHash = anchorHash; } +static Boolean SecValidInfoCompare(CFTypeRef a, CFTypeRef b) { + SecValidInfoRef validInfoA = (SecValidInfoRef)a; + SecValidInfoRef validInfoB = (SecValidInfoRef)b; + if (validInfoA == validInfoB) { + return true; + } + if (!validInfoA || !validInfoB || + (CFGetTypeID(a) != SecValidInfoGetTypeID()) || + (CFGetTypeID(b) != SecValidInfoGetTypeID())) { + return false; + } + return CFEqualSafe(validInfoA->certHash, validInfoB->certHash) && CFEqualSafe(validInfoA->issuerHash, validInfoB->issuerHash); +} + +static CFStringRef SecValidInfoCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) { + SecValidInfoRef validInfo = (SecValidInfoRef)cf; + CFStringRef certHash = CFDataCopyHexString(validInfo->certHash); + CFStringRef issuerHash = CFDataCopyHexString(validInfo->issuerHash); + CFStringRef desc = CFStringCreateWithFormat(NULL, formatOptions, CFSTR("validInfo certHash: %@ issuerHash: %@"), certHash, issuerHash); + CFReleaseNull(certHash); + CFReleaseNull(issuerHash); + return desc; +} + // MARK: - // MARK: SecRevocationDb @@ -985,7 +992,9 @@ void SecRevocationDbCheckNextUpdate(void) { dispatch_queue_t update_queue = SecRevocationDbGetUpdateQueue(); action = sec_action_create_with_queue(update_queue, "update_check", kSecMinUpdateInterval); sec_action_set_handler(action, ^{ + os_transaction_t transaction = os_transaction_create("com.apple.trustd.valid.checkNextUpdate"); (void)_SecRevocationDbCheckNextUpdate(); + os_release(transaction); }); }); sec_action_perform(action); @@ -1113,14 +1122,17 @@ CFAbsoluteTime SecRevocationDbComputeNextUpdateTime(CFIndex updateInterval) { void SecRevocationDbComputeAndSetNextUpdateTime(void) { gNextUpdate = SecRevocationDbComputeNextUpdateTime(0); - SecRevocationDbSetNextUpdateTime(gNextUpdate); + (void) SecRevocationDbSetNextUpdateTime(gNextUpdate, NULL); gUpdateStarted = 0; /* no update is currently in progress */ } -CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion) { +bool SecRevocationDbIngestUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef update, CFIndex chunkVersion, CFIndex *outVersion, CFErrorRef *error) { + bool ok = false; CFIndex version = 0; + CFErrorRef localError = NULL; if (!update) { - return version; + SecError(errSecParam, &localError, CFSTR("SecRevocationDbIngestUpdate: invalid update parameter")); + goto setVersionAndExit; } CFTypeRef value = (CFNumberRef)CFDictionaryGetValue(update, CFSTR("version")); if (isNumber(value)) { @@ -1133,15 +1145,25 @@ CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion // subsequent chunks will need to pass it in chunkVersion. version = chunkVersion; } - CFIndex curVersion = SecRevocationDbGetVersion(); + // check precommitted version since update hasn't been committed yet + CFIndex curVersion = dbc->precommitVersion; if (version > curVersion || chunkVersion > 0) { - SecRevocationDbApplyUpdate(update, version); + ok = _SecRevocationDbApplyUpdate(dbc, update, version, &localError); + secdebug("validupdate", "_SecRevocationDbApplyUpdate=%s, v%ld, precommit=%ld, full=%s", + (ok) ? "1" : "0", (long)version, (long)dbc->precommitVersion, + (dbc->fullUpdate) ? "1" : "0"); } else { secdebug("validupdate", "we have v%ld, skipping update to v%ld", (long)curVersion, (long)version); version = -1; // invalid, so we know to skip subsequent chunks + ok = true; // this is not an error condition } - return version; +setVersionAndExit: + if (outVersion) { + *outVersion = version; + } + (void) CFErrorPropagate(localError, error); + return ok; } @@ -1168,11 +1190,12 @@ CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion kSecValidInfoKnownOnly (0x00000004) set if any CA from this issuer group must be in database kSecValidInfoRequireCT (0x00000008) set if all certs from this issuer group must have SCTs kSecValidInfoAllowlist (0x00000010) set if this entry describes valid certs (i.e. is allowed) - kSecValidInfoNoCACheck (0x00000020) set if this entry does not require an OCSP check to accept + kSecValidInfoNoCACheck (0x00000020) set if this entry does not require an OCSP check to accept (deprecated) kSecValidInfoOverridable (0x00000040) set if the trust status is recoverable and can be overridden kSecValidInfoDateConstraints (0x00000080) set if this group has not-before or not-after constraints kSecValidInfoNameConstraints (0x00000100) [RESERVED] set if this group has name constraints in database kSecValidInfoPolicyConstraints (0x00000200) [RESERVED] set if this group has policy constraints in database + kSecValidInfoNoCAv2Check (0x00000400) set if this entry does not require an OCSP check to accept format (integer) // an integer describing format of entries: kSecValidInfoFormatUnknown (0) unknown format kSecValidInfoFormatSerial (1) serial number, not greater than 20 bytes in length @@ -1268,11 +1291,18 @@ CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion "(groupid,flags,format,data) VALUES (?,?,?,?)") #define insertSerialRecordSQL CFSTR("INSERT OR REPLACE INTO serials " \ "(groupid,serial) VALUES (?,?)") -#define insertDateRecordSQL CFSTR("INSERT OR REPLACE INTO dates " \ - "(groupid,notbefore,notafter) VALUES (?,?,?)") +#define deleteSerialRecordSQL CFSTR("DELETE FROM serials " \ + "WHERE groupid=? AND hex(serial) LIKE ?") #define insertSha256RecordSQL CFSTR("INSERT OR REPLACE INTO hashes " \ "(groupid,sha256) VALUES (?,?)") -#define deleteGroupRecordSQL CFSTR("DELETE FROM groups WHERE groupid=?") +#define deleteSha256RecordSQL CFSTR("DELETE FROM hashes " \ + "WHERE groupid=? AND hex(sha256) LIKE ?") +#define insertDateRecordSQL CFSTR("INSERT OR REPLACE INTO dates " \ + "(groupid,notbefore,notafter) VALUES (?,?,?)") +#define deleteGroupRecordSQL CFSTR("DELETE FROM groups " \ + "WHERE groupid=?") +#define deleteGroupIssuersSQL CFSTR("DELETE FROM issuers " \ + "WHERE groupid=?") #define updateConstraintsTablesSQL CFSTR("" \ "CREATE TABLE IF NOT EXISTS dates(" \ @@ -1296,26 +1326,25 @@ CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion "DELETE FROM admin WHERE key='version'; " \ "DELETE FROM sqlite_sequence") + /* Database management */ static SecDbRef SecRevocationDbCreate(CFStringRef path) { /* only the db owner should open a read-write connection. */ - bool readWrite = isDbOwner(); + __block bool readWrite = isDbOwner(); mode_t mode = 0644; - SecDbRef result = SecDbCreateWithOptions(path, mode, readWrite, false, false, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) { + SecDbRef result = SecDbCreate(path, mode, readWrite, false, true, true, 1, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) { __block bool ok = true; - CFErrorRef localError = NULL; - if (ok && !SecDbWithSQL(dbconn, selectGroupIdSQL, &localError, NULL) && CFErrorGetCode(localError) == SQLITE_ERROR) { - /* SecDbWithSQL returns SQLITE_ERROR if the table we are preparing the above statement for doesn't exist. */ - - /* Create all database tables, indexes, and triggers. */ + if (readWrite) { ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, error, ^(bool *commit) { - ok = SecDbExec(dbconn, createTablesSQL, error); + /* Create all database tables, indexes, and triggers. + * SecDbOpen will set auto_vacuum and journal_mode for us before we get called back.*/ + ok = ok && SecDbExec(dbconn, createTablesSQL, error); *commit = ok; }); } - if (!ok || localError) { + if (!ok || (error && *error)) { CFIndex errCode = errSecInternalComponent; if (error && *error) { errCode = CFErrorGetCode(*error); @@ -1323,21 +1352,12 @@ static SecDbRef SecRevocationDbCreate(CFStringRef path) { secerror("%s failed: %@", didCreate ? "Create" : "Open", error ? *error : NULL); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationCreate, TAFatalError, errCode); } - CFReleaseSafe(localError); return ok; }); return result; } -typedef struct __SecRevocationDb *SecRevocationDbRef; -struct __SecRevocationDb { - SecDbRef db; - dispatch_queue_t update_queue; - bool updateInProgress; - bool unsupportedVersion; -}; - static dispatch_once_t kSecRevocationDbOnce; static SecRevocationDbRef kSecRevocationDb = NULL; @@ -1350,12 +1370,24 @@ static SecRevocationDbRef SecRevocationDbInit(CFStringRef db_name) { rdb->update_queue = NULL; rdb->updateInProgress = false; rdb->unsupportedVersion = false; + rdb->changed = false; require(rdb->db = SecRevocationDbCreate(db_name), errOut); attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_BACKGROUND, 0); attr = dispatch_queue_attr_make_with_autorelease_frequency(attr, DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM); require(rdb->update_queue = dispatch_queue_create(NULL, attr), errOut); + require(rdb->info_cache_list = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks), errOut); + require(rdb->info_cache = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); + rdb->info_cache_lock = OS_UNFAIR_LOCK_INIT; + if (!isDbOwner()) { + /* register for changes signaled by the db owner instance */ + int out_token = 0; + notify_register_dispatch(kSecRevocationDbChanged, &out_token, rdb->update_queue, ^(int __unused token) { + secnotice("validupdate", "Got notification of database change"); + SecRevocationDbResetCaches(); + }); + } return rdb; errOut: @@ -1392,6 +1424,10 @@ static void SecRevocationDbWith(void(^dbJob)(SecRevocationDbRef db)) { if (dbPath) { kSecRevocationDb = SecRevocationDbInit(dbPath); CFRelease(dbPath); + if (kSecRevocationDb && isDbOwner()) { + /* check and update schema immediately after database is opened */ + SecRevocationDbUpdateSchema(kSecRevocationDb); + } } }); // Do pre job run work here (cancel idle timers etc.) @@ -1402,20 +1438,153 @@ static void SecRevocationDbWith(void(^dbJob)(SecRevocationDbRef db)) { // Do post job run work here (gc timer, etc.) } -static int64_t _SecRevocationDbGetVersion(SecRevocationDbRef rdb, CFErrorRef *error) { - /* look up version entry in admin table; returns -1 on error */ - __block int64_t version = -1; +static bool SecRevocationDbPerformWrite(SecRevocationDbRef rdb, CFErrorRef *error, + bool(^writeJob)(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError)) { __block bool ok = true; __block CFErrorRef localError = NULL; + ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { + ok &= SecDbTransaction(dbconn, kSecDbImmediateTransactionType, &localError, ^(bool *commit) { + SecRevocationDbConnectionRef dbc = SecRevocationDbConnectionInit(rdb, dbconn, &localError); + ok = ok && writeJob(dbc, &localError); + *commit = ok; + free(dbc); + }); + }); + ok &= CFErrorPropagate(localError, error); + return ok; +} + +static bool SecRevocationDbPerformRead(SecRevocationDbRef rdb, CFErrorRef *error, + bool(^readJob)(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError)) { + __block CFErrorRef localError = NULL; + __block bool ok = true; + ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectVersionSQL, &localError, ^bool(sqlite3_stmt *selectVersion) { - ok &= SecDbStep(dbconn, selectVersion, &localError, ^void(bool *stop) { - version = sqlite3_column_int64(selectVersion, 0); - *stop = true; - }); - return ok; + SecRevocationDbConnectionRef dbc = SecRevocationDbConnectionInit(rdb, dbconn, &localError); + ok = ok && readJob(dbc, &localError); + free(dbc); + }); + ok &= CFErrorPropagate(localError, error); + return ok; +} + +static SecRevocationDbConnectionRef SecRevocationDbConnectionInit(SecRevocationDbRef db, SecDbConnectionRef dbconn, CFErrorRef *error) { + SecRevocationDbConnectionRef dbc = NULL; + CFErrorRef localError = NULL; + + dbc = (SecRevocationDbConnectionRef)malloc(sizeof(struct __SecRevocationDbConnection)); + if (dbc) { + dbc->db = db; + dbc->dbconn = dbconn; + dbc->precommitVersion = _SecRevocationDbGetVersion(dbc, &localError); + dbc->precommitDbVersion = _SecRevocationDbGetSchemaVersion(db, dbc, &localError); + dbc->fullUpdate = false; + } + (void) CFErrorPropagate(localError, error); + return dbc; +} + +static CF_RETURNS_RETAINED CFDataRef createCacheKey(CFDataRef certHash, CFDataRef issuerHash) { + CFMutableDataRef concat = CFDataCreateMutableCopy(NULL, 0, certHash); + CFDataAppend(concat, issuerHash); + CFDataRef result = SecSHA256DigestCreateFromData(NULL, concat); + CFReleaseNull(concat); + return result; +} + +static CF_RETURNS_RETAINED SecValidInfoRef SecRevocationDbCacheRead(SecRevocationDbRef db, + SecCertificateRef certificate, + CFDataRef issuerHash) { + if (!db) { + return NULL; + } + SecValidInfoRef result = NULL; + if (!db || !db->info_cache || !db->info_cache_list) { + return result; + } + CFIndex ix = kCFNotFound; + CFDataRef certHash = SecCertificateCopySHA256Digest(certificate); + CFDataRef cacheKey = createCacheKey(certHash, issuerHash); + + os_unfair_lock_lock(&db->info_cache_lock); // grab the cache lock before using the cache + if (0 <= (ix = CFArrayGetFirstIndexOfValue(db->info_cache_list, + CFRangeMake(0, CFArrayGetCount(db->info_cache_list)), + cacheKey))) { + result = (SecValidInfoRef)CFDictionaryGetValue(db->info_cache, cacheKey); + // Verify this really is the right result + if (CFEqualSafe(result->certHash, certHash) && CFEqualSafe(result->issuerHash, issuerHash)) { + // Cache hit. Move the entry to the bottom of the list. + CFArrayRemoveValueAtIndex(db->info_cache_list, ix); + CFArrayAppendValue(db->info_cache_list, cacheKey); + secdebug("validcache", "cache hit: %@", cacheKey); + } else { + // Just remove this bad entry + CFArrayRemoveValueAtIndex(db->info_cache_list, ix); + CFDictionaryRemoveValue(db->info_cache, cacheKey); + secdebug("validcache", "cache remove bad: %@", cacheKey); + secnotice("validcache", "found a bad valid info cache entry at %ld", (long)ix); + } + } + CFRetainSafe(result); + os_unfair_lock_unlock(&db->info_cache_lock); + CFReleaseSafe(certHash); + CFReleaseSafe(cacheKey); + return result; +} + +static void SecRevocationDbCacheWrite(SecRevocationDbRef db, + SecValidInfoRef validInfo) { + if (!db || !validInfo || !db->info_cache || !db->info_cache_list) { + return; + } + + CFDataRef cacheKey = createCacheKey(validInfo->certHash, validInfo->issuerHash); + + os_unfair_lock_lock(&db->info_cache_lock); // grab the cache lock before using the cache + // check to make sure another thread didn't add this entry to the cache already + if (0 > CFArrayGetFirstIndexOfValue(db->info_cache_list, + CFRangeMake(0, CFArrayGetCount(db->info_cache_list)), + cacheKey)) { + CFDictionaryAddValue(db->info_cache, cacheKey, validInfo); + if (kSecRevocationDbCacheSize <= CFArrayGetCount(db->info_cache_list)) { + // Remove least recently used cache entry. + secdebug("validcache", "cache remove stale: %@", CFArrayGetValueAtIndex(db->info_cache_list, 0)); + CFDictionaryRemoveValue(db->info_cache, CFArrayGetValueAtIndex(db->info_cache_list, 0)); + CFArrayRemoveValueAtIndex(db->info_cache_list, 0); + } + CFArrayAppendValue(db->info_cache_list, cacheKey); + secdebug("validcache", "cache add: %@", cacheKey); + } + os_unfair_lock_unlock(&db->info_cache_lock); + CFReleaseNull(cacheKey); +} + +static void SecRevocationDbCachePurge(SecRevocationDbRef db) { + if (!db || !db->info_cache || !db->info_cache_list) { + return; + } + + /* grab the cache lock and clear all entries */ + os_unfair_lock_lock(&db->info_cache_lock); + CFArrayRemoveAllValues(db->info_cache_list); + CFDictionaryRemoveAllValues(db->info_cache); + secdebug("validcache", "cache purge"); + os_unfair_lock_unlock(&db->info_cache_lock); +} + +static int64_t _SecRevocationDbGetVersion(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { + /* look up version entry in admin table; returns -1 on error */ + __block int64_t version = -1; + __block bool ok = (dbc != NULL); + __block CFErrorRef localError = NULL; + + ok = ok && SecDbWithSQL(dbc->dbconn, selectVersionSQL, &localError, ^bool(sqlite3_stmt *selectVersion) { + ok = ok && SecDbStep(dbc->dbconn, selectVersion, &localError, ^void(bool *stop) { + version = sqlite3_column_int64(selectVersion, 0); + *stop = true; }); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbGetVersion failed: %@", localError); @@ -1426,49 +1595,44 @@ static int64_t _SecRevocationDbGetVersion(SecRevocationDbRef rdb, CFErrorRef *er return version; } -static void _SecRevocationDbSetVersion(SecRevocationDbRef rdb, CFIndex version) { +static bool _SecRevocationDbSetVersion(SecRevocationDbConnectionRef dbc, CFIndex version, CFErrorRef *error) { secdebug("validupdate", "setting version to %ld", (long)version); __block CFErrorRef localError = NULL; - __block bool ok = true; - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertVersion) { - const char *versionKey = "version"; - ok = ok && SecDbBindText(insertVersion, 1, versionKey, strlen(versionKey), - SQLITE_TRANSIENT, &localError); - ok = ok && SecDbBindInt64(insertVersion, 2, - (sqlite3_int64)version, &localError); - ok = ok && SecDbStep(dbconn, insertVersion, &localError, NULL); - return ok; - }); - }); + __block bool ok = (dbc != NULL); + ok = ok && SecDbWithSQL(dbc->dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertVersion) { + const char *versionKey = "version"; + ok = ok && SecDbBindText(insertVersion, 1, versionKey, strlen(versionKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertVersion, 2, + (sqlite3_int64)version, &localError); + ok = ok && SecDbStep(dbc->dbconn, insertVersion, &localError, NULL); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbSetVersion failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); } - CFReleaseSafe(localError); + (void) CFErrorPropagate(localError, error); + return ok; } -static int64_t _SecRevocationDbGetSchemaVersion(SecRevocationDbRef rdb, CFErrorRef *error) { +static int64_t _SecRevocationDbReadSchemaVersionFromDb(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { /* look up db_version entry in admin table; returns -1 on error */ __block int64_t db_version = -1; - __block bool ok = true; + __block bool ok = (dbc != NULL); __block CFErrorRef localError = NULL; - ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectDbVersionSQL, &localError, ^bool(sqlite3_stmt *selectDbVersion) { - ok &= SecDbStep(dbconn, selectDbVersion, &localError, ^void(bool *stop) { - db_version = sqlite3_column_int64(selectDbVersion, 0); - *stop = true; - }); - return ok; + ok = ok && SecDbWithSQL(dbc->dbconn, selectDbVersionSQL, &localError, ^bool(sqlite3_stmt *selectDbVersion) { + ok = ok && SecDbStep(dbc->dbconn, selectDbVersion, &localError, ^void(bool *stop) { + db_version = sqlite3_column_int64(selectDbVersion, 0); + *stop = true; }); + return ok; }); if (!ok || localError) { - secerror("_SecRevocationDbGetSchemaVersion failed: %@", localError); + secerror("_SecRevocationDbReadSchemaVersionFromDb failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); } @@ -1476,9 +1640,48 @@ static int64_t _SecRevocationDbGetSchemaVersion(SecRevocationDbRef rdb, CFErrorR return db_version; } -static bool _SecRevocationDbSetSchemaVersion(SecRevocationDbRef rdb, CFIndex dbversion) { +static _Atomic int64_t gSchemaVersion = -1; +static int64_t _SecRevocationDbGetSchemaVersion(SecRevocationDbRef rdb, SecRevocationDbConnectionRef dbc, CFErrorRef *error) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + if (dbc) { + atomic_init(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, error)); + } else { + (void) SecRevocationDbPerformRead(rdb, error, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + atomic_init(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, blockError)); + return true; + }); + } + }); + if (atomic_load(&gSchemaVersion) == -1) { + /* Initial read(s) failed. Try to read the schema version again. */ + if (dbc) { + atomic_store(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, error)); + } else { + (void) SecRevocationDbPerformRead(rdb, error, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + atomic_store(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, blockError)); + return true; + }); + } + } + return atomic_load(&gSchemaVersion); +} + +static void SecRevocationDbResetCaches(void) { + SecRevocationDbWith(^(SecRevocationDbRef db) { + db->unsupportedVersion = false; + db->changed = false; + (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + atomic_store(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, blockError)); + return true; + }); + SecRevocationDbCachePurge(db); + }); +} + +static bool _SecRevocationDbSetSchemaVersion(SecRevocationDbConnectionRef dbc, CFIndex dbversion, CFErrorRef *error) { if (dbversion > 0) { - int64_t db_version = _SecRevocationDbGetSchemaVersion(rdb, NULL); + int64_t db_version = (dbc) ? dbc->precommitDbVersion : -1; if (db_version >= dbversion) { return true; /* requested schema is earlier than current schema */ } @@ -1486,72 +1689,98 @@ static bool _SecRevocationDbSetSchemaVersion(SecRevocationDbRef rdb, CFIndex dbv secdebug("validupdate", "setting db_version to %ld", (long)dbversion); __block CFErrorRef localError = NULL; - __block bool ok = true; - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertDbVersion) { - const char *dbVersionKey = "db_version"; - ok = ok && SecDbBindText(insertDbVersion, 1, dbVersionKey, strlen(dbVersionKey), - SQLITE_TRANSIENT, &localError); - ok = ok && SecDbBindInt64(insertDbVersion, 2, - (sqlite3_int64)dbversion, &localError); - ok = ok && SecDbStep(dbconn, insertDbVersion, &localError, NULL); - return ok; - }); - }); + __block bool ok = (dbc != NULL); + ok = ok && SecDbWithSQL(dbc->dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertDbVersion) { + const char *dbVersionKey = "db_version"; + ok = ok && SecDbBindText(insertDbVersion, 1, dbVersionKey, strlen(dbVersionKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertDbVersion, 2, + (sqlite3_int64)dbversion, &localError); + ok = ok && SecDbStep(dbc->dbconn, insertDbVersion, &localError, NULL); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbSetSchemaVersion failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); } else { - rdb->unsupportedVersion = false; + dbc->db->changed = true; /* will notify clients of this change */ + dbc->db->unsupportedVersion = false; + dbc->precommitDbVersion = dbversion; + atomic_store(&gSchemaVersion, (int64_t)dbversion); } CFReleaseSafe(localError); return ok; } -static bool _SecRevocationDbUpdateSchema(SecRevocationDbRef rdb) { - secdebug("validupdate", "updating db schema to v%ld", (long)kSecRevocationDbSchemaVersion); - +static bool _SecRevocationDbUpdateSchema(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { __block CFErrorRef localError = NULL; - __block bool ok = true; - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - ok &= SecDbWithSQL(dbconn, updateConstraintsTablesSQL, &localError, ^bool(sqlite3_stmt *updateTables) { - ok = SecDbStep(dbconn, updateTables, &localError, NULL); - return ok; - }); - - ok &= SecDbWithSQL(dbconn, updateGroupDeleteTriggerSQL, &localError, ^bool(sqlite3_stmt *updateTrigger) { - ok = SecDbStep(dbconn, updateTrigger, &localError, NULL); - return ok; - }); + __block bool ok = (dbc != NULL); + __block int64_t db_version = (dbc) ? dbc->precommitDbVersion : 0; + if (db_version >= kSecRevocationDbSchemaVersion) { + return ok; /* schema version already up to date */ + } + secdebug("validupdate", "updating db schema from v%lld to v%lld", + (long long)db_version, (long long)kSecRevocationDbSchemaVersion); + + if (ok && db_version < 5) { + /* apply v5 changes (add dates table and replace trigger) */ + ok &= SecDbWithSQL(dbc->dbconn, updateConstraintsTablesSQL, &localError, ^bool(sqlite3_stmt *updateTables) { + ok = SecDbStep(dbc->dbconn, updateTables, &localError, NULL); + return ok; }); - }); + ok &= SecDbWithSQL(dbc->dbconn, updateGroupDeleteTriggerSQL, &localError, ^bool(sqlite3_stmt *updateTrigger) { + ok = SecDbStep(dbc->dbconn, updateTrigger, &localError, NULL); + return ok; + }); + secdebug("validupdate", "applied schema update to v5 (%s)", (ok) ? "ok" : "failed!"); + } + if (ok && db_version < 6) { + /* apply v6 changes (the SecDb layer will update autovacuum mode if needed, so we don't execute + any SQL here, but we do want the database to be replaced in case transaction scope problems + with earlier versions caused missing entries.) */ + secdebug("validupdate", "applied schema update to v6 (%s)", (ok) ? "ok" : "failed!"); + if (db_version > 0) { + SecValidUpdateForceReplaceDatabase(); + } + } + if (!ok) { secerror("_SecRevocationDbUpdateSchema failed: %@", localError); } else { - ok &= _SecRevocationDbSetSchemaVersion(rdb, kSecRevocationDbSchemaVersion); + ok = ok && _SecRevocationDbSetSchemaVersion(dbc, kSecRevocationDbSchemaVersion, &localError); + } + (void) CFErrorPropagate(localError, error); + return ok; +} + +bool SecRevocationDbUpdateSchema(SecRevocationDbRef rdb) { + /* note: this function assumes it is called only by the database owner. + non-owner (read-only) clients will fail if changes to the db are needed. */ + if (!rdb || !rdb->db) { + return false; } + __block bool ok = true; + __block CFErrorRef localError = NULL; + ok &= SecRevocationDbPerformWrite(rdb, &localError, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + return _SecRevocationDbUpdateSchema(dbc, blockError); + }); CFReleaseSafe(localError); return ok; } -static int64_t _SecRevocationDbGetUpdateFormat(SecRevocationDbRef rdb, CFErrorRef *error) { +static int64_t _SecRevocationDbGetUpdateFormat(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { /* look up db_format entry in admin table; returns -1 on error */ __block int64_t db_format = -1; - __block bool ok = true; + __block bool ok = (dbc != NULL); __block CFErrorRef localError = NULL; - ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectDbFormatSQL, &localError, ^bool(sqlite3_stmt *selectDbFormat) { - ok &= SecDbStep(dbconn, selectDbFormat, &localError, ^void(bool *stop) { - db_format = sqlite3_column_int64(selectDbFormat, 0); - *stop = true; - }); - return ok; + ok = ok && SecDbWithSQL(dbc->dbconn, selectDbFormatSQL, &localError, ^bool(sqlite3_stmt *selectDbFormat) { + ok &= SecDbStep(dbc->dbconn, selectDbFormat, &localError, ^void(bool *stop) { + db_format = sqlite3_column_int64(selectDbFormat, 0); + *stop = true; }); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbGetUpdateFormat failed: %@", localError); @@ -1562,54 +1791,50 @@ static int64_t _SecRevocationDbGetUpdateFormat(SecRevocationDbRef rdb, CFErrorRe return db_format; } -static void _SecRevocationDbSetUpdateFormat(SecRevocationDbRef rdb, CFIndex dbformat) { +static bool _SecRevocationDbSetUpdateFormat(SecRevocationDbConnectionRef dbc, CFIndex dbformat, CFErrorRef *error) { secdebug("validupdate", "setting db_format to %ld", (long)dbformat); __block CFErrorRef localError = NULL; - __block bool ok = true; - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertDbFormat) { - const char *dbFormatKey = "db_format"; - ok = ok && SecDbBindText(insertDbFormat, 1, dbFormatKey, strlen(dbFormatKey), - SQLITE_TRANSIENT, &localError); - ok = ok && SecDbBindInt64(insertDbFormat, 2, - (sqlite3_int64)dbformat, &localError); - ok = ok && SecDbStep(dbconn, insertDbFormat, &localError, NULL); - return ok; - }); - }); + __block bool ok = (dbc != NULL); + ok = ok && SecDbWithSQL(dbc->dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertDbFormat) { + const char *dbFormatKey = "db_format"; + ok = ok && SecDbBindText(insertDbFormat, 1, dbFormatKey, strlen(dbFormatKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertDbFormat, 2, + (sqlite3_int64)dbformat, &localError); + ok = ok && SecDbStep(dbc->dbconn, insertDbFormat, &localError, NULL); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbSetUpdateFormat failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); } else { - rdb->unsupportedVersion = false; + dbc->db->changed = true; /* will notify clients of this change */ + dbc->db->unsupportedVersion = false; } - CFReleaseSafe(localError); + (void) CFErrorPropagate(localError, error); + return ok; } -static CFStringRef _SecRevocationDbCopyUpdateSource(SecRevocationDbRef rdb, CFErrorRef *error) { +static CFStringRef _SecRevocationDbCopyUpdateSource(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { /* look up db_source entry in admin table; returns NULL on error */ __block CFStringRef updateSource = NULL; - __block bool ok = true; + __block bool ok = (dbc != NULL); __block CFErrorRef localError = NULL; - ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectDbSourceSQL, &localError, ^bool(sqlite3_stmt *selectDbSource) { - ok &= SecDbStep(dbconn, selectDbSource, &localError, ^void(bool *stop) { - const UInt8 *p = (const UInt8 *)sqlite3_column_blob(selectDbSource, 0); - if (p != NULL) { - CFIndex length = (CFIndex)sqlite3_column_bytes(selectDbSource, 0); - if (length > 0) { - updateSource = CFStringCreateWithBytes(kCFAllocatorDefault, p, length, kCFStringEncodingUTF8, false); - } + ok = ok && SecDbWithSQL(dbc->dbconn, selectDbSourceSQL, &localError, ^bool(sqlite3_stmt *selectDbSource) { + ok &= SecDbStep(dbc->dbconn, selectDbSource, &localError, ^void(bool *stop) { + const UInt8 *p = (const UInt8 *)sqlite3_column_blob(selectDbSource, 0); + if (p != NULL) { + CFIndex length = (CFIndex)sqlite3_column_bytes(selectDbSource, 0); + if (length > 0) { + updateSource = CFStringCreateWithBytes(kCFAllocatorDefault, p, length, kCFStringEncodingUTF8, false); } - *stop = true; - }); - return ok; + } + *stop = true; }); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbCopyUpdateSource failed: %@", localError); @@ -1620,10 +1845,10 @@ static CFStringRef _SecRevocationDbCopyUpdateSource(SecRevocationDbRef rdb, CFEr return updateSource; } -static void _SecRevocationDbSetUpdateSource(SecRevocationDbRef rdb, CFStringRef updateSource) { +bool _SecRevocationDbSetUpdateSource(SecRevocationDbConnectionRef dbc, CFStringRef updateSource, CFErrorRef *error) { if (!updateSource) { secerror("_SecRevocationDbSetUpdateSource failed: %d", errSecParam); - return; + return false; } __block char buffer[256]; __block const char *updateSourceCStr = CFStringGetCStringPtr(updateSource, kCFStringEncodingUTF8); @@ -1634,55 +1859,66 @@ static void _SecRevocationDbSetUpdateSource(SecRevocationDbRef rdb, CFStringRef } if (!updateSourceCStr) { secerror("_SecRevocationDbSetUpdateSource failed: unable to get UTF-8 encoding"); - return; + return false; } secdebug("validupdate", "setting update source to \"%s\"", updateSourceCStr); __block CFErrorRef localError = NULL; - __block bool ok = true; - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertRecord) { - const char *dbSourceKey = "db_source"; - ok = ok && SecDbBindText(insertRecord, 1, dbSourceKey, strlen(dbSourceKey), - SQLITE_TRANSIENT, &localError); - ok = ok && SecDbBindInt64(insertRecord, 2, - (sqlite3_int64)0, &localError); - ok = ok && SecDbBindBlob(insertRecord, 3, - updateSourceCStr, strlen(updateSourceCStr), - SQLITE_TRANSIENT, &localError); - ok = ok && SecDbStep(dbconn, insertRecord, &localError, NULL); - return ok; - }); - }); + __block bool ok = (dbc != NULL); + ok = ok && SecDbWithSQL(dbc->dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertRecord) { + const char *dbSourceKey = "db_source"; + ok = ok && SecDbBindText(insertRecord, 1, dbSourceKey, strlen(dbSourceKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertRecord, 2, + (sqlite3_int64)0, &localError); + ok = ok && SecDbBindBlob(insertRecord, 3, + updateSourceCStr, strlen(updateSourceCStr), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbStep(dbc->dbconn, insertRecord, &localError, NULL); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbSetUpdateSource failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); } + (void) CFErrorPropagate(localError, error); + CFReleaseSafe(localError); + return ok; +} + +bool SecRevocationDbSetUpdateSource(SecRevocationDbRef rdb, CFStringRef updateSource) { + /* note: this function assumes it is called only by the database owner. + non-owner (read-only) clients will fail if changes to the db are needed. */ + if (!rdb || !rdb->db) { + return false; + } + CFErrorRef localError = NULL; + bool ok = true; + ok &= SecRevocationDbPerformWrite(rdb, &localError, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { + return _SecRevocationDbSetUpdateSource(dbc, updateSource, error); + }); CFReleaseSafe(localError); + return ok; } -static CFAbsoluteTime _SecRevocationDbGetNextUpdateTime(SecRevocationDbRef rdb, CFErrorRef *error) { +static CFAbsoluteTime _SecRevocationDbGetNextUpdateTime(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { /* look up check_again entry in admin table; returns 0 on error */ __block CFAbsoluteTime nextUpdate = 0; - __block bool ok = true; + __block bool ok = (dbc != NULL); __block CFErrorRef localError = NULL; - ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectNextUpdateSQL, &localError, ^bool(sqlite3_stmt *selectNextUpdate) { - ok &= SecDbStep(dbconn, selectNextUpdate, &localError, ^void(bool *stop) { - CFAbsoluteTime *p = (CFAbsoluteTime *)sqlite3_column_blob(selectNextUpdate, 0); - if (p != NULL) { - if (sizeof(CFAbsoluteTime) == sqlite3_column_bytes(selectNextUpdate, 0)) { - nextUpdate = *p; - } + ok = ok && SecDbWithSQL(dbc->dbconn, selectNextUpdateSQL, &localError, ^bool(sqlite3_stmt *selectNextUpdate) { + ok &= SecDbStep(dbc->dbconn, selectNextUpdate, &localError, ^void(bool *stop) { + CFAbsoluteTime *p = (CFAbsoluteTime *)sqlite3_column_blob(selectNextUpdate, 0); + if (p != NULL) { + if (sizeof(CFAbsoluteTime) == sqlite3_column_bytes(selectNextUpdate, 0)) { + nextUpdate = *p; } - *stop = true; - }); - return ok; + } + *stop = true; }); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbGetNextUpdateTime failed: %@", localError); @@ -1693,97 +1929,81 @@ static CFAbsoluteTime _SecRevocationDbGetNextUpdateTime(SecRevocationDbRef rdb, return nextUpdate; } -static void _SecRevocationDbSetNextUpdateTime(SecRevocationDbRef rdb, CFAbsoluteTime nextUpdate){ +static bool _SecRevocationDbSetNextUpdateTime(SecRevocationDbConnectionRef dbc, CFAbsoluteTime nextUpdate, CFErrorRef *error){ secdebug("validupdate", "setting next update to %f", (double)nextUpdate); __block CFErrorRef localError = NULL; - __block bool ok = true; - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertRecord) { - const char *nextUpdateKey = "check_again"; - ok = ok && SecDbBindText(insertRecord, 1, nextUpdateKey, strlen(nextUpdateKey), - SQLITE_TRANSIENT, &localError); - ok = ok && SecDbBindInt64(insertRecord, 2, - (sqlite3_int64)0, &localError); - ok = ok && SecDbBindBlob(insertRecord, 3, - &nextUpdate, sizeof(CFAbsoluteTime), - SQLITE_TRANSIENT, &localError); - ok = ok && SecDbStep(dbconn, insertRecord, &localError, NULL); - return ok; - }); - }); + __block bool ok = (dbc != NULL); + ok = ok && SecDbWithSQL(dbc->dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertRecord) { + const char *nextUpdateKey = "check_again"; + ok = ok && SecDbBindText(insertRecord, 1, nextUpdateKey, strlen(nextUpdateKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertRecord, 2, + (sqlite3_int64)0, &localError); + ok = ok && SecDbBindBlob(insertRecord, 3, + &nextUpdate, sizeof(CFAbsoluteTime), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbStep(dbc->dbconn, insertRecord, &localError, NULL); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbSetNextUpdate failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); } - CFReleaseSafe(localError); + (void) CFErrorPropagate(localError, error); + return ok; } -static bool _SecRevocationDbRemoveAllEntries(SecRevocationDbRef rdb) { +bool _SecRevocationDbRemoveAllEntries(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { /* clear out the contents of the database and start fresh */ - __block bool ok = true; - __block CFErrorRef localError = NULL; + bool ok = (dbc != NULL); + CFErrorRef localError = NULL; - /* update schema first */ - _SecRevocationDbUpdateSchema(rdb); + /* _SecRevocationDbUpdateSchema was called when db was opened, so no need to do it again. */ + + /* delete all entries */ + ok = ok && SecDbExec(dbc->dbconn, deleteAllEntriesSQL, &localError); + secnotice("validupdate", "resetting database, result: %d (expected 1)", (ok) ? 1 : 0); - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - /* delete all entries */ - ok &= SecDbExec(dbconn, deleteAllEntriesSQL, &localError); - secnotice("validupdate", "resetting database, result: %d (expected 1)", (ok) ? 1 : 0); - *commit = ok; - }); - /* compact the db (must be done outside transaction scope) */ - ok &= SecDbExec(dbconn, CFSTR("VACUUM"), &localError); - secnotice("validupdate", "compacting database, result: %d (expected 1)", (ok) ? 1 : 0); - }); /* one more thing: update the schema version and format to current */ - _SecRevocationDbSetSchemaVersion(rdb, kSecRevocationDbSchemaVersion); - _SecRevocationDbSetUpdateFormat(rdb, kSecRevocationDbUpdateFormat); + ok = ok && _SecRevocationDbSetSchemaVersion(dbc, kSecRevocationDbSchemaVersion, &localError); + ok = ok && _SecRevocationDbSetUpdateFormat(dbc, kSecRevocationDbUpdateFormat, &localError); if (!ok || localError) { secerror("_SecRevocationDbRemoveAllEntries failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); } - CFReleaseSafe(localError); + (void) CFErrorPropagate(localError, error); return ok; } -static bool _SecRevocationDbUpdateIssuers(SecRevocationDbRef rdb, int64_t groupId, CFArrayRef issuers, CFErrorRef *error) { +static bool _SecRevocationDbUpdateIssuers(SecRevocationDbConnectionRef dbc, int64_t groupId, CFArrayRef issuers, CFErrorRef *error) { /* insert or replace issuer records in issuers table */ if (!issuers || groupId < 0) { return false; /* must have something to insert, and a group to associate with it */ } - __block bool ok = true; + __block bool ok = (dbc != NULL); __block CFErrorRef localError = NULL; - - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - if (isArray(issuers)) { - CFIndex issuerIX, issuerCount = CFArrayGetCount(issuers); - for (issuerIX=0; issuerIXdbconn, insertIssuerRecordSQL, &localError, ^bool(sqlite3_stmt *insertIssuer) { + ok = ok && SecDbBindInt64(insertIssuer, 1, + groupId, &localError); + ok = ok && SecDbBindBlob(insertIssuer, 2, + CFDataGetBytePtr(hash), + CFDataGetLength(hash), + SQLITE_TRANSIENT, &localError); + /* Execute the insert statement for this issuer record. */ + ok = ok && SecDbStep(dbc->dbconn, insertIssuer, &localError, NULL); + return ok; + }); + } + } if (!ok || localError) { secerror("_SecRevocationDbUpdateIssuers failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, @@ -1793,56 +2013,116 @@ static bool _SecRevocationDbUpdateIssuers(SecRevocationDbRef rdb, int64_t groupI return ok; } -static bool _SecRevocationDbUpdateIssuerData(SecRevocationDbRef rdb, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { +static SecValidInfoFormat _SecRevocationDbGetGroupFormatForData(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDataRef data) { + /* determine existing format if groupId is supplied and this is a partial update, + otherwise return the expected format for the given data. */ + SecValidInfoFormat format = kSecValidInfoFormatUnknown; + if (groupId >= 0 && !dbc->fullUpdate) { + format = _SecRevocationDbGetGroupFormat(dbc, groupId, NULL, NULL, NULL); + } + if (format == kSecValidInfoFormatUnknown && data != NULL) { + /* group doesn't exist, so determine format based on length of specified data. + len <= 20 is a serial number (actually, <=37, but != 32.) + len==32 is a sha256 hash. otherwise: nto1. */ + CFIndex length = CFDataGetLength(data); + if (length == 32) { + format = kSecValidInfoFormatSHA256; + } else if (length <= 37) { + format = kSecValidInfoFormatSerial; + } else if (length > 0) { + format = kSecValidInfoFormatNto1; + } + } + return format; +} + +static bool _SecRevocationDbUpdateIssuerData(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { /* update/delete records in serials or hashes table. */ if (!dict || groupId < 0) { return false; /* must have something to insert, and a group to associate with it */ } - __block bool ok = true; + __block bool ok = (dbc != NULL); __block CFErrorRef localError = NULL; - - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - CFArrayRef deleteArray = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("delete")); - /* process deletions */ - if (isArray(deleteArray)) { - //%%% delete old data here (rdar://31439625) + /* process deletions */ + CFArrayRef deleteArray = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("delete")); + if (isArray(deleteArray)) { + SecValidInfoFormat format = kSecValidInfoFormatUnknown; + CFIndex processed=0, identifierIX, identifierCount = CFArrayGetCount(deleteArray); + for (identifierIX=0; identifierIXdbconn, sql, &localError, ^bool(sqlite3_stmt *deleteIdentifier) { + /* (groupid,serial|sha256) */ + CFDataRef hexData = cfToHexData(identifierData, true); + if (!hexData) { return false; } + ok = ok && SecDbBindInt64(deleteIdentifier, 1, + groupId, &localError); + ok = ok && SecDbBindBlob(deleteIdentifier, 2, + CFDataGetBytePtr(hexData), + CFDataGetLength(hexData), + SQLITE_TRANSIENT, &localError); + /* Execute the delete statement for the identifier record. */ + ok = ok && SecDbStep(dbc->dbconn, deleteIdentifier, &localError, NULL); + CFReleaseSafe(hexData); + return ok; + }); + if (ok) { ++processed; } + } +#if VERBOSE_LOGGING + secdebug("validupdate", "Processed %ld of %ld deletions for group %lld, result=%s", + processed, identifierCount, groupId, (ok) ? "true" : "false"); +#endif + } + /* process additions */ + CFArrayRef addArray = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("add")); + if (isArray(addArray)) { + SecValidInfoFormat format = kSecValidInfoFormatUnknown; + CFIndex processed=0, identifierIX, identifierCount = CFArrayGetCount(addArray); + for (identifierIX=0; identifierIXdbconn, sql, &localError, ^bool(sqlite3_stmt *insertIdentifier) { + /* rowid,(groupid,serial|sha256) */ + /* rowid is autoincremented and we never set it directly */ + ok = ok && SecDbBindInt64(insertIdentifier, 1, + groupId, &localError); + ok = ok && SecDbBindBlob(insertIdentifier, 2, + CFDataGetBytePtr(identifierData), + CFDataGetLength(identifierData), + SQLITE_TRANSIENT, &localError); + /* Execute the insert statement for the identifier record. */ + ok = ok && SecDbStep(dbc->dbconn, insertIdentifier, &localError, NULL); + return ok; + }); + if (ok) { ++processed; } + } +#if VERBOSE_LOGGING + secdebug("validupdate", "Processed %ld of %ld additions for group %lld, result=%s", + processed, identifierCount, groupId, (ok) ? "true" : "false"); +#endif + } if (!ok || localError) { secerror("_SecRevocationDbUpdatePerIssuerData failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, @@ -1852,41 +2132,42 @@ static bool _SecRevocationDbUpdateIssuerData(SecRevocationDbRef rdb, int64_t gro return ok; } -static bool _SecRevocationDbCopyDateConstraints(SecRevocationDbRef rdb, +static bool _SecRevocationDbCopyDateConstraints(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDateRef *notBeforeDate, CFDateRef *notAfterDate, CFErrorRef *error) { /* return true if one or both date constraints exist for a given groupId. the actual constraints are optionally returned in output CFDateRef parameters. caller is responsible for releasing date and error parameters, if provided. */ - __block bool ok = true; + __block bool ok = (dbc != NULL); __block CFDateRef localNotBefore = NULL; __block CFDateRef localNotAfter = NULL; __block CFErrorRef localError = NULL; - ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectDateRecordSQL, &localError, ^bool(sqlite3_stmt *selectDates) { - /* (groupid,notbefore,notafter) */ - ok &= SecDbBindInt64(selectDates, 1, groupId, &localError); - ok = ok && SecDbStep(dbconn, selectDates, &localError, ^(bool *stop) { - /* if column has no value, its type will be SQLITE_NULL */ - if (SQLITE_NULL != sqlite3_column_type(selectDates, 0)) { - CFAbsoluteTime nb = (CFAbsoluteTime)sqlite3_column_double(selectDates, 0); - localNotBefore = CFDateCreate(NULL, nb); - } - if (SQLITE_NULL != sqlite3_column_type(selectDates, 1)) { - CFAbsoluteTime na = (CFAbsoluteTime)sqlite3_column_double(selectDates, 1); - localNotAfter = CFDateCreate(NULL, na); - } - }); - return ok; + ok = ok && SecDbWithSQL(dbc->dbconn, selectDateRecordSQL, &localError, ^bool(sqlite3_stmt *selectDates) { + /* (groupid,notbefore,notafter) */ + ok &= SecDbBindInt64(selectDates, 1, groupId, &localError); + ok = ok && SecDbStep(dbc->dbconn, selectDates, &localError, ^(bool *stop) { + /* if column has no value, its type will be SQLITE_NULL */ + if (SQLITE_NULL != sqlite3_column_type(selectDates, 0)) { + CFAbsoluteTime nb = (CFAbsoluteTime)sqlite3_column_double(selectDates, 0); + localNotBefore = CFDateCreate(NULL, nb); + } + if (SQLITE_NULL != sqlite3_column_type(selectDates, 1)) { + CFAbsoluteTime na = (CFAbsoluteTime)sqlite3_column_double(selectDates, 1); + localNotAfter = CFDateCreate(NULL, na); + } }); + return ok; }); - /* must have at least one date constraint */ - ok = ok && (localNotBefore != NULL || localNotAfter != NULL); - if (!ok || localError) { + /* must have at least one date constraint to return true. + since date constraints are optional, not finding any should not log an error. */ + ok = ok && !localError && (localNotBefore != NULL || localNotAfter != NULL); + if (localError) { secerror("_SecRevocationDbCopyDateConstraints failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } + if (!ok) { CFReleaseNull(localNotBefore); CFReleaseNull(localNotAfter); } @@ -1905,9 +2186,9 @@ static bool _SecRevocationDbCopyDateConstraints(SecRevocationDbRef rdb, return ok; } -static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbRef rdb, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { +static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { /* update optional records in dates, names, or policies tables. */ - if (!dict || groupId < 0) { + if (!dbc || !dict || groupId < 0) { return false; /* must have something to insert, and a group to associate with it */ } __block bool ok = true; @@ -1928,15 +2209,15 @@ static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbRef rdb, int6 notAfterDate = NULL; } if (!(notBeforeDate || notAfterDate)) { - return false; /* no dates supplied, so we have nothing to update for this issuer */ + return ok; /* no dates supplied, so we have nothing to update for this issuer */ } - if (!(notBeforeDate && notAfterDate)) { + if (!(notBeforeDate && notAfterDate) && !dbc->fullUpdate) { /* only one date was supplied, so check for existing date constraints */ CFDateRef curNotBeforeDate = NULL; CFDateRef curNotAfterDate = NULL; - if (_SecRevocationDbCopyDateConstraints(rdb, groupId, &curNotBeforeDate, - &curNotAfterDate, &localError)) { + if (_SecRevocationDbCopyDateConstraints(dbc, groupId, &curNotBeforeDate, + &curNotAfterDate, &localError)) { if (!notBeforeDate) { notBeforeDate = curNotBeforeDate; notBefore = CFDateGetAbsoluteTime(notBeforeDate); @@ -1952,21 +2233,17 @@ static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbRef rdb, int6 } } - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - ok &= SecDbWithSQL(dbconn, insertDateRecordSQL, &localError, ^bool(sqlite3_stmt *insertDate) { - /* (groupid,notbefore,notafter) */ - ok = ok && SecDbBindInt64(insertDate, 1, groupId, &localError); - ok = ok && SecDbBindDouble(insertDate, 2, notBefore, &localError); - ok = ok && SecDbBindDouble(insertDate, 3, notAfter, &localError); - ok = ok && SecDbStep(dbconn, insertDate, &localError, NULL); - return ok; - }); - - /* %%% (TBI:9254570,21234699) update name and policy constraint entries here */ - }); + ok = ok && SecDbWithSQL(dbc->dbconn, insertDateRecordSQL, &localError, ^bool(sqlite3_stmt *insertDate) { + /* (groupid,notbefore,notafter) */ + ok = ok && SecDbBindInt64(insertDate, 1, groupId, &localError); + ok = ok && SecDbBindDouble(insertDate, 2, notBefore, &localError); + ok = ok && SecDbBindDouble(insertDate, 3, notAfter, &localError); + ok = ok && SecDbStep(dbc->dbconn, insertDate, &localError, NULL); + return ok; }); + /* %%% (TBI:9254570,21234699) update name and policy constraint entries here */ + if (!ok || localError) { secinfo("validupdate", "_SecRevocationDbUpdateIssuerConstraints failed (ok=%s, localError=%@)", (ok) ? "1" : "0", localError); @@ -1978,36 +2255,34 @@ static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbRef rdb, int6 return ok; } -static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbRef rdb, +static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbConnectionRef dbc, int64_t groupId, SecValidInfoFlags *flags, CFDataRef *data, CFErrorRef *error) { /* return group record fields for a given groupId. on success, returns a non-zero format type, and other field values in optional output parameters. caller is responsible for releasing data and error parameters, if provided. */ - __block bool ok = true; + __block bool ok = (dbc != NULL); __block SecValidInfoFormat format = 0; __block CFErrorRef localError = NULL; /* Select the group record to determine flags and format. */ - ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectGroupRecordSQL, &localError, ^bool(sqlite3_stmt *selectGroup) { - ok = ok && SecDbBindInt64(selectGroup, 1, groupId, &localError); - ok = ok && SecDbStep(dbconn, selectGroup, &localError, ^(bool *stop) { - if (flags) { - *flags = (SecValidInfoFlags)sqlite3_column_int(selectGroup, 0); - } - format = (SecValidInfoFormat)sqlite3_column_int(selectGroup, 1); - if (data) { - //%%% stream the data from the db into a streamed decompression - uint8_t *p = (uint8_t *)sqlite3_column_blob(selectGroup, 2); - if (p != NULL && format == kSecValidInfoFormatNto1) { - CFIndex length = (CFIndex)sqlite3_column_bytes(selectGroup, 2); - *data = CFDataCreate(kCFAllocatorDefault, p, length); - } + ok = ok && SecDbWithSQL(dbc->dbconn, selectGroupRecordSQL, &localError, ^bool(sqlite3_stmt *selectGroup) { + ok = ok && SecDbBindInt64(selectGroup, 1, groupId, &localError); + ok = ok && SecDbStep(dbc->dbconn, selectGroup, &localError, ^(bool *stop) { + if (flags) { + *flags = (SecValidInfoFlags)sqlite3_column_int(selectGroup, 0); + } + format = (SecValidInfoFormat)sqlite3_column_int(selectGroup, 1); + if (data) { + //%%% stream the data from the db into a streamed decompression + uint8_t *p = (uint8_t *)sqlite3_column_blob(selectGroup, 2); + if (p != NULL && format == kSecValidInfoFormatNto1) { + CFIndex length = (CFIndex)sqlite3_column_bytes(selectGroup, 2); + *data = CFDataCreate(kCFAllocatorDefault, p, length); } - }); - return ok; + } }); + return ok; }); if (!ok || localError) { secdebug("validupdate", "GetGroupFormat for groupId %lu failed", (unsigned long)groupId); @@ -2182,7 +2457,7 @@ static bool _SecRevocationDbUpdateFilter(CFDictionaryRef dict, CFDataRef oldData } -static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { +static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { /* insert group record for a given groupId. if the specified groupId is < 0, a new group entry is created. returns the groupId on success, or -1 on failure. @@ -2192,7 +2467,7 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t group } __block int64_t result = -1; - __block bool ok = true; + __block bool ok = (dbc != NULL); __block bool isFormatChange = false; __block CFErrorRef localError = NULL; @@ -2203,7 +2478,9 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t group if (groupId >= 0) { /* fetch the flags and data for an existing group record, in case some are being changed. */ - format = _SecRevocationDbGetGroupFormat(rdb, groupId, &flags, &data, NULL); + if (ok) { + format = _SecRevocationDbGetGroupFormat(dbc, groupId, &flags, &data, NULL); + } if (format == kSecValidInfoFormatUnknown) { secdebug("validupdate", "existing group %lld has unknown format %d, flags=0x%lx", (long long)groupId, format, flags); @@ -2228,115 +2505,112 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t group formatUpdate != format && groupId >= 0); - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - if (isFormatChange) { - secdebug("validupdate", "group %lld format change from %d to %d", - (long long)groupId, format, formatUpdate); - /* format of an existing group is changing; delete the group first. - this should ensure that all entries referencing the old groupid are deleted. - */ - ok &= SecDbWithSQL(dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) { - ok = SecDbBindInt64(deleteResponse, 1, groupId, &localError); - /* Execute the delete statement. */ - ok = ok && SecDbStep(dbconn, deleteResponse, &localError, NULL); - return ok; - }); + if (isFormatChange) { + secdebug("validupdate", "group %lld format change from %d to %d", + (long long)groupId, format, formatUpdate); + /* format of an existing group is changing; delete the group first. + this should ensure that all entries referencing the old groupid are deleted. + */ + ok = ok && SecDbWithSQL(dbc->dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) { + ok = ok && SecDbBindInt64(deleteResponse, 1, groupId, &localError); + /* Execute the delete statement. */ + ok = ok && SecDbStep(dbc->dbconn, deleteResponse, &localError, NULL); + return ok; + }); + } + ok = ok && SecDbWithSQL(dbc->dbconn, insertGroupRecordSQL, &localError, ^bool(sqlite3_stmt *insertGroup) { + /* (groupid,flags,format,data) */ + /* groups.groupid */ + if (ok && (!isFormatChange) && (groupId >= 0)) { + /* bind to existing groupId row if known, otherwise will insert and autoincrement */ + ok = SecDbBindInt64(insertGroup, 1, groupId, &localError); + if (!ok) { + secdebug("validupdate", "failed to set groupId %lld", (long long)groupId); + } + } + /* groups.flags */ + if (ok) { + (void)_SecRevocationDbUpdateFlags(dict, CFSTR("complete"), kSecValidInfoComplete, &flags); + (void)_SecRevocationDbUpdateFlags(dict, CFSTR("check-ocsp"), kSecValidInfoCheckOCSP, &flags); + (void)_SecRevocationDbUpdateFlags(dict, CFSTR("known-intermediates-only"), kSecValidInfoKnownOnly, &flags); + (void)_SecRevocationDbUpdateFlags(dict, CFSTR("require-ct"), kSecValidInfoRequireCT, &flags); + (void)_SecRevocationDbUpdateFlags(dict, CFSTR("valid"), kSecValidInfoAllowlist, &flags); + (void)_SecRevocationDbUpdateFlags(dict, CFSTR("no-ca"), kSecValidInfoNoCACheck, &flags); + (void)_SecRevocationDbUpdateFlags(dict, CFSTR("no-ca-v2"), kSecValidInfoNoCAv2Check, &flags); + (void)_SecRevocationDbUpdateFlags(dict, CFSTR("overridable"), kSecValidInfoOverridable, &flags); + + /* date constraints exist if either "not-before" or "not-after" keys are found */ + CFTypeRef notBeforeValue = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-before")); + CFTypeRef notAfterValue = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-after")); + if (isDate(notBeforeValue) || isDate(notAfterValue)) { + (void)_SecRevocationDbUpdateFlags(dict, kBoolTrueKey, kSecValidInfoDateConstraints, &flags); + /* Note that the spec defines not-before and not-after dates as optional, such that + not providing one does not change the database contents. Therefore, we can never clear + this flag; either a new date entry will be supplied, or a format change will cause + the entire group entry to be deleted. */ } - ok &= SecDbWithSQL(dbconn, insertGroupRecordSQL, &localError, ^bool(sqlite3_stmt *insertGroup) { - /* (groupid,flags,format,data) */ - /* groups.groupid */ - if (ok && (!isFormatChange) && (groupId >= 0)) { - /* bind to existing groupId row if known, otherwise will insert and autoincrement */ - ok = SecDbBindInt64(insertGroup, 1, groupId, &localError); - if (!ok) { - secdebug("validupdate", "failed to set groupId %lld", (long long)groupId); - } - } - /* groups.flags */ - if (ok) { - (void)_SecRevocationDbUpdateFlags(dict, CFSTR("complete"), kSecValidInfoComplete, &flags); - (void)_SecRevocationDbUpdateFlags(dict, CFSTR("check-ocsp"), kSecValidInfoCheckOCSP, &flags); - (void)_SecRevocationDbUpdateFlags(dict, CFSTR("known-intermediates-only"), kSecValidInfoKnownOnly, &flags); - (void)_SecRevocationDbUpdateFlags(dict, CFSTR("require-ct"), kSecValidInfoRequireCT, &flags); - (void)_SecRevocationDbUpdateFlags(dict, CFSTR("valid"), kSecValidInfoAllowlist, &flags); - (void)_SecRevocationDbUpdateFlags(dict, CFSTR("no-ca"), kSecValidInfoNoCACheck, &flags); - (void)_SecRevocationDbUpdateFlags(dict, CFSTR("overridable"), kSecValidInfoOverridable, &flags); - - /* date constraints exist if either "not-before" or "not-after" keys are found */ - CFTypeRef notBeforeValue = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-before")); - CFTypeRef notAfterValue = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-after")); - if (isDate(notBeforeValue) || isDate(notAfterValue)) { - (void)_SecRevocationDbUpdateFlags(dict, kBoolTrueKey, kSecValidInfoDateConstraints, &flags); - /* Note that the spec defines not-before and not-after dates as optional, such that - not providing one does not change the database contents. Therefore, we can never clear - this flag; either a new date entry will be supplied, or a format change will cause - the entire group entry to be deleted. */ - } - /* %%% (TBI:9254570,21234699) name and policy constraints don't exist yet */ - (void)_SecRevocationDbUpdateFlags(dict, kBoolFalseKey, kSecValidInfoNameConstraints, &flags); - (void)_SecRevocationDbUpdateFlags(dict, kBoolFalseKey, kSecValidInfoPolicyConstraints, &flags); + /* %%% (TBI:9254570,21234699) name and policy constraints don't exist yet */ + (void)_SecRevocationDbUpdateFlags(dict, kBoolFalseKey, kSecValidInfoNameConstraints, &flags); + (void)_SecRevocationDbUpdateFlags(dict, kBoolFalseKey, kSecValidInfoPolicyConstraints, &flags); - ok = SecDbBindInt(insertGroup, 2, (int)flags, &localError); - if (!ok) { - secdebug("validupdate", "failed to set flags (%lu) for groupId %lld", flags, (long long)groupId); - } - } - /* groups.format */ - if (ok) { - SecValidInfoFormat formatValue = format; - if (formatUpdate > kSecValidInfoFormatUnknown) { - formatValue = formatUpdate; - } - ok = SecDbBindInt(insertGroup, 3, (int)formatValue, &localError); - if (!ok) { - secdebug("validupdate", "failed to set format (%d) for groupId %lld", formatValue, (long long)groupId); - } - } - /* groups.data */ - CFDataRef xmlData = NULL; - if (ok) { - bool hasFilter = ((formatUpdate == kSecValidInfoFormatNto1) || - (formatUpdate == kSecValidInfoFormatUnknown && - format == kSecValidInfoFormatNto1)); - if (hasFilter) { - CFDataRef dataValue = data; /* use existing data */ - if (_SecRevocationDbUpdateFilter(dict, data, &xmlData)) { - dataValue = xmlData; /* use updated data */ - } - if (dataValue) { - ok = SecDbBindBlob(insertGroup, 4, - CFDataGetBytePtr(dataValue), - CFDataGetLength(dataValue), - SQLITE_TRANSIENT, &localError); - } - if (!ok) { - secdebug("validupdate", "failed to set data for groupId %lld", - (long long)groupId); - } - } - /* else there is no data, so NULL is implicitly bound to column 4 */ + ok = SecDbBindInt(insertGroup, 2, (int)flags, &localError); + if (!ok) { + secdebug("validupdate", "failed to set flags (%lu) for groupId %lld", flags, (long long)groupId); + } + } + /* groups.format */ + if (ok) { + SecValidInfoFormat formatValue = format; + if (formatUpdate > kSecValidInfoFormatUnknown) { + formatValue = formatUpdate; + } + ok = SecDbBindInt(insertGroup, 3, (int)formatValue, &localError); + if (!ok) { + secdebug("validupdate", "failed to set format (%d) for groupId %lld", formatValue, (long long)groupId); + } + } + /* groups.data */ + CFDataRef xmlData = NULL; + if (ok) { + bool hasFilter = ((formatUpdate == kSecValidInfoFormatNto1) || + (formatUpdate == kSecValidInfoFormatUnknown && + format == kSecValidInfoFormatNto1)); + if (hasFilter) { + CFDataRef dataValue = data; /* use existing data */ + if (_SecRevocationDbUpdateFilter(dict, data, &xmlData)) { + dataValue = xmlData; /* use updated data */ } - - /* Execute the insert statement for the group record. */ - if (ok) { - ok = SecDbStep(dbconn, insertGroup, &localError, NULL); - if (!ok) { - secdebug("validupdate", "failed to execute insertGroup statement for groupId %lld", - (long long)groupId); - } - result = (int64_t)sqlite3_last_insert_rowid(SecDbHandle(dbconn)); + if (dataValue) { + ok = SecDbBindBlob(insertGroup, 4, + CFDataGetBytePtr(dataValue), + CFDataGetLength(dataValue), + SQLITE_TRANSIENT, &localError); } if (!ok) { - secdebug("validupdate", "failed to insert group %lld", (long long)result); + secdebug("validupdate", "failed to set data for groupId %lld", + (long long)groupId); } - /* Clean up temporary allocation made in this block. */ - CFReleaseSafe(xmlData); - CFReleaseSafe(data); - return ok; - }); - }); + } + /* else there is no data, so NULL is implicitly bound to column 4 */ + } + + /* Execute the insert statement for the group record. */ + if (ok) { + ok = SecDbStep(dbc->dbconn, insertGroup, &localError, NULL); + if (!ok) { + secdebug("validupdate", "failed to execute insertGroup statement for groupId %lld", + (long long)groupId); + } + result = (int64_t)sqlite3_last_insert_rowid(SecDbHandle(dbc->dbconn)); + } + if (!ok) { + secdebug("validupdate", "failed to insert group %lld", (long long)result); + } + /* Clean up temporary allocation made in this block. */ + CFReleaseSafe(xmlData); + CFReleaseSafe(data); + return ok; }); if (!ok || localError) { secerror("_SecRevocationDbUpdateGroup failed: %@", localError); @@ -2347,16 +2621,16 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t group return result; } -static int64_t _SecRevocationDbGroupIdForIssuerHash(SecRevocationDbRef rdb, CFDataRef hash, CFErrorRef *error) { +static int64_t _SecRevocationDbGroupIdForIssuerHash(SecRevocationDbConnectionRef dbc, CFDataRef hash, CFErrorRef *error) { /* look up issuer hash in issuers table to get groupid, if it exists */ __block int64_t groupId = -1; - __block bool ok = true; + __block bool ok = (dbc != NULL); __block CFErrorRef localError = NULL; if (!hash) { secdebug("validupdate", "failed to get hash (%@)", hash); } - require(hash, errOut); + require(hash && dbc, errOut); /* This is the starting point for any lookup; find a group id for the given issuer hash. Before we do that, need to verify the current db_version. We cannot use results from a @@ -2365,25 +2639,23 @@ static int64_t _SecRevocationDbGroupIdForIssuerHash(SecRevocationDbRef rdb, CFDa update interval, if the existing schema is old, we'll be removing and recreating the database contents with the current schema version. */ - int64_t db_version = _SecRevocationDbGetSchemaVersion(rdb, NULL); + int64_t db_version = _SecRevocationDbGetSchemaVersion(dbc->db, dbc, NULL); if (db_version < kSecRevocationDbMinSchemaVersion) { - if (!rdb->unsupportedVersion) { + if (!dbc->db->unsupportedVersion) { secdebug("validupdate", "unsupported db_version: %lld", (long long)db_version); - rdb->unsupportedVersion = true; /* only warn once for a given unsupported version */ + dbc->db->unsupportedVersion = true; /* only warn once for a given unsupported version */ } } require_quiet(db_version >= kSecRevocationDbMinSchemaVersion, errOut); /* Look up provided issuer_hash in the issuers table. */ - ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectGroupIdSQL, &localError, ^bool(sqlite3_stmt *selectGroupId) { - ok &= SecDbBindBlob(selectGroupId, 1, CFDataGetBytePtr(hash), CFDataGetLength(hash), SQLITE_TRANSIENT, &localError); - ok &= SecDbStep(dbconn, selectGroupId, &localError, ^(bool *stopGroupId) { - groupId = sqlite3_column_int64(selectGroupId, 0); - }); - return ok; + ok = ok && SecDbWithSQL(dbc->dbconn, selectGroupIdSQL, &localError, ^bool(sqlite3_stmt *selectGroupId) { + ok &= SecDbBindBlob(selectGroupId, 1, CFDataGetBytePtr(hash), CFDataGetLength(hash), SQLITE_TRANSIENT, &localError); + ok &= SecDbStep(dbc->dbconn, selectGroupId, &localError, ^(bool *stopGroupId) { + groupId = sqlite3_column_int64(selectGroupId, 0); }); + return ok; }); errOut: @@ -2396,90 +2668,108 @@ errOut: return groupId; } -static bool _SecRevocationDbApplyGroupDelete(SecRevocationDbRef rdb, CFDataRef issuerHash, CFErrorRef *error) { +static bool _SecRevocationDbApplyGroupDelete(SecRevocationDbConnectionRef dbc, CFDataRef issuerHash, CFErrorRef *error) { /* delete group associated with the given issuer; schema trigger will delete associated issuers, serials, and hashes. */ __block int64_t groupId = -1; - __block bool ok = true; + __block bool ok = (dbc != NULL); __block CFErrorRef localError = NULL; - groupId = _SecRevocationDbGroupIdForIssuerHash(rdb, issuerHash, &localError); - require(!(groupId < 0), errOut); - - ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - ok &= SecDbWithSQL(dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) { - ok &= SecDbBindInt64(deleteResponse, 1, groupId, &localError); - /* Execute the delete statement. */ - ok = ok && SecDbStep(dbconn, deleteResponse, &localError, NULL); - return ok; - }); - }); + if (ok) { + groupId = _SecRevocationDbGroupIdForIssuerHash(dbc, issuerHash, &localError); + } + if (groupId < 0) { + if (!localError) { + SecError(errSecParam, &localError, CFSTR("group not found for issuer")); + } + ok = false; + } + ok = ok && SecDbWithSQL(dbc->dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) { + ok &= SecDbBindInt64(deleteResponse, 1, groupId, &localError); + /* Execute the delete statement. */ + ok = ok && SecDbStep(dbc->dbconn, deleteResponse, &localError, NULL); + return ok; }); - -errOut: if (!ok || localError) { secerror("_SecRevocationDbApplyGroupDelete failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); } (void) CFErrorPropagate(localError, error); - return (groupId < 0) ? false : true; + return ok; } -static bool _SecRevocationDbApplyGroupUpdate(SecRevocationDbRef rdb, CFDictionaryRef dict, CFErrorRef *error) { +static bool _SecRevocationDbApplyGroupUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef dict, CFErrorRef *error) { /* process one issuer group's update dictionary */ - int64_t groupId = -1; - CFErrorRef localError = NULL; + __block int64_t groupId = -1; + __block bool ok = (dbc != NULL); + __block CFErrorRef localError = NULL; CFArrayRef issuers = (dict) ? (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("issuer-hash")) : NULL; - if (isArray(issuers)) { + /* if this is not a full update, then look for existing group id */ + if (ok && isArray(issuers) && !dbc->fullUpdate) { CFIndex issuerIX, issuerCount = CFArrayGetCount(issuers); /* while we have issuers and haven't found a matching group id */ for (issuerIX=0; issuerIX= 0) { + /* according to the spec, we must replace all existing issuers with + the new issuers list, so delete all issuers in the group first. */ + ok = ok && SecDbWithSQL(dbc->dbconn, deleteGroupIssuersSQL, &localError, ^bool(sqlite3_stmt *deleteIssuers) { + ok = ok && SecDbBindInt64(deleteIssuers, 1, groupId, &localError); + ok = ok && SecDbStep(dbc->dbconn, deleteIssuers, &localError, NULL); + return ok; + }); } } /* create or update the group entry */ - groupId = _SecRevocationDbUpdateGroup(rdb, groupId, dict, &localError); + if (ok) { + groupId = _SecRevocationDbUpdateGroup(dbc, groupId, dict, &localError); + } if (groupId < 0) { secdebug("validupdate", "failed to get groupId"); + ok = false; } else { /* create or update issuer entries, now that we know the group id */ - _SecRevocationDbUpdateIssuers(rdb, groupId, issuers, &localError); + ok = ok && _SecRevocationDbUpdateIssuers(dbc, groupId, issuers, &localError); /* create or update entries in serials or hashes tables */ - _SecRevocationDbUpdateIssuerData(rdb, groupId, dict, &localError); + ok = ok && _SecRevocationDbUpdateIssuerData(dbc, groupId, dict, &localError); /* create or update entries in dates/names/policies tables */ - _SecRevocationDbUpdateIssuerConstraints(rdb, groupId, dict, &localError); + ok = ok && _SecRevocationDbUpdateIssuerConstraints(dbc, groupId, dict, &localError); } (void) CFErrorPropagate(localError, error); - return (groupId > 0) ? true : false; + return ok; } -static void _SecRevocationDbApplyUpdate(SecRevocationDbRef rdb, CFDictionaryRef update, CFIndex version) { +bool _SecRevocationDbApplyUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef update, CFIndex version, CFErrorRef *error) { /* process entire update dictionary */ - if (!rdb || !update) { + if (!dbc || !dbc->db || !update) { secerror("_SecRevocationDbApplyUpdate failed: invalid args"); - return; + SecError(errSecParam, error, CFSTR("_SecRevocationDbApplyUpdate: invalid db or update parameter")); + return false; } - __block CFDictionaryRef localUpdate = (CFDictionaryRef)CFRetainSafe(update); - __block CFErrorRef localError = NULL; + CFDictionaryRef localUpdate = (CFDictionaryRef)CFRetainSafe(update); + CFErrorRef localError = NULL; + bool ok = true; CFTypeRef value = NULL; CFIndex deleteCount = 0; CFIndex updateCount = 0; - rdb->updateInProgress = true; + dbc->db->updateInProgress = true; /* check whether this is a full update */ value = (CFBooleanRef)CFDictionaryGetValue(update, CFSTR("full")); if (isBoolean(value) && CFBooleanGetValue((CFBooleanRef)value)) { /* clear the database before processing a full update */ - SecRevocationDbRemoveAllEntries(); + dbc->fullUpdate = true; + secdebug("validupdate", "update has \"full\" attribute; clearing database"); + ok = ok && _SecRevocationDbRemoveAllEntries(dbc, &localError); } /* process 'delete' list */ @@ -2490,8 +2780,7 @@ static void _SecRevocationDbApplyUpdate(SecRevocationDbRef rdb, CFDictionaryRef for (CFIndex deleteIX=0; deleteIXdb, dbc, NULL); if (db_version <= 0) { - _SecRevocationDbSetSchemaVersion(rdb, kSecRevocationDbSchemaVersion); + ok = ok && _SecRevocationDbSetSchemaVersion(dbc, kSecRevocationDbSchemaVersion, &localError); } /* set db_format if not already set */ - int64_t db_format = _SecRevocationDbGetUpdateFormat(rdb, NULL); + int64_t db_format = _SecRevocationDbGetUpdateFormat(dbc, NULL); if (db_format <= 0) { - _SecRevocationDbSetUpdateFormat(rdb, kSecRevocationDbUpdateFormat); + ok = ok && _SecRevocationDbSetUpdateFormat(dbc, kSecRevocationDbUpdateFormat, &localError); } - /* compact the db (must be done outside transaction scope) */ - (void)SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - SecDbExec(dbconn, CFSTR("VACUUM"), &localError); - CFReleaseNull(localError); - }); + /* purge the in-memory cache */ + SecRevocationDbCachePurge(dbc->db); - rdb->updateInProgress = false; + dbc->db->updateInProgress = false; + + (void) CFErrorPropagate(localError, error); + return ok; } -static bool _SecRevocationDbSerialInGroup(SecRevocationDbRef rdb, +static bool _SecRevocationDbSerialInGroup(SecRevocationDbConnectionRef dbc, CFDataRef serial, int64_t groupId, CFErrorRef *error) { __block bool result = false; __block bool ok = true; __block CFErrorRef localError = NULL; - require(rdb && serial, errOut); - ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectSerialRecordSQL, &localError, ^bool(sqlite3_stmt *selectSerial) { - ok &= SecDbBindInt64(selectSerial, 1, groupId, &localError); - ok &= SecDbBindBlob(selectSerial, 2, CFDataGetBytePtr(serial), - CFDataGetLength(serial), SQLITE_TRANSIENT, &localError); - ok &= SecDbStep(dbconn, selectSerial, &localError, ^(bool *stop) { - int64_t foundRowId = (int64_t)sqlite3_column_int64(selectSerial, 0); - result = (foundRowId > 0); - }); - return ok; + require(dbc && serial, errOut); + ok &= SecDbWithSQL(dbc->dbconn, selectSerialRecordSQL, &localError, ^bool(sqlite3_stmt *selectSerial) { + ok &= SecDbBindInt64(selectSerial, 1, groupId, &localError); + ok &= SecDbBindBlob(selectSerial, 2, CFDataGetBytePtr(serial), + CFDataGetLength(serial), SQLITE_TRANSIENT, &localError); + ok &= SecDbStep(dbc->dbconn, selectSerial, &localError, ^(bool *stop) { + int64_t foundRowId = (int64_t)sqlite3_column_int64(selectSerial, 0); + result = (foundRowId > 0); }); + return ok; }); errOut: @@ -2570,25 +2856,23 @@ errOut: return result; } -static bool _SecRevocationDbCertHashInGroup(SecRevocationDbRef rdb, +static bool _SecRevocationDbCertHashInGroup(SecRevocationDbConnectionRef dbc, CFDataRef certHash, int64_t groupId, CFErrorRef *error) { __block bool result = false; __block bool ok = true; __block CFErrorRef localError = NULL; - require(rdb && certHash, errOut); - ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - ok &= SecDbWithSQL(dbconn, selectHashRecordSQL, &localError, ^bool(sqlite3_stmt *selectHash) { - ok &= SecDbBindInt64(selectHash, 1, groupId, &localError); - ok = SecDbBindBlob(selectHash, 2, CFDataGetBytePtr(certHash), - CFDataGetLength(certHash), SQLITE_TRANSIENT, &localError); - ok &= SecDbStep(dbconn, selectHash, &localError, ^(bool *stop) { - int64_t foundRowId = (int64_t)sqlite3_column_int64(selectHash, 0); - result = (foundRowId > 0); - }); - return ok; + require(dbc && certHash, errOut); + ok &= SecDbWithSQL(dbc->dbconn, selectHashRecordSQL, &localError, ^bool(sqlite3_stmt *selectHash) { + ok &= SecDbBindInt64(selectHash, 1, groupId, &localError); + ok = SecDbBindBlob(selectHash, 2, CFDataGetBytePtr(certHash), + CFDataGetLength(certHash), SQLITE_TRANSIENT, &localError); + ok &= SecDbStep(dbc->dbconn, selectHash, &localError, ^(bool *stop) { + int64_t foundRowId = (int64_t)sqlite3_column_int64(selectHash, 0); + result = (foundRowId > 0); }); + return ok; }); errOut: @@ -2601,7 +2885,7 @@ errOut: return result; } -static bool _SecRevocationDbSerialInFilter(SecRevocationDbRef rdb, +static bool _SecRevocationDbSerialInFilter(SecRevocationDbConnectionRef dbc, CFDataRef serialData, CFDataRef xmlData) { /* N-To-1 filter implementation. @@ -2667,7 +2951,7 @@ errOut: return result; } -static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbRef rdb, +static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbConnectionRef dbc, SecCertificateRef certificate, CFDataRef issuerHash, CFErrorRef *error) { @@ -2689,10 +2973,10 @@ static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbRe require((serial = SecCertificateCopySerialNumberData(certificate, NULL)) != NULL, errOut); require((certHash = SecCertificateCopySHA256Digest(certificate)) != NULL, errOut); - require((groupId = _SecRevocationDbGroupIdForIssuerHash(rdb, issuerHash, &localError)) > 0, errOut); + require((groupId = _SecRevocationDbGroupIdForIssuerHash(dbc, issuerHash, &localError)) > 0, errOut); /* Look up the group record to determine flags and format. */ - format = _SecRevocationDbGetGroupFormat(rdb, groupId, &flags, &data, &localError); + format = _SecRevocationDbGetGroupFormat(dbc, groupId, &flags, &data, &localError); if (format == kSecValidInfoFormatUnknown) { /* No group record found for this issuer. Don't return a SecValidInfoRef */ @@ -2700,17 +2984,17 @@ static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbRe } else if (format == kSecValidInfoFormatSerial) { /* Look up certificate's serial number in the serials table. */ - matched = _SecRevocationDbSerialInGroup(rdb, serial, groupId, &localError); + matched = _SecRevocationDbSerialInGroup(dbc, serial, groupId, &localError); } else if (format == kSecValidInfoFormatSHA256) { /* Look up certificate's SHA-256 hash in the hashes table. */ - matched = _SecRevocationDbCertHashInGroup(rdb, certHash, groupId, &localError); + matched = _SecRevocationDbCertHashInGroup(dbc, certHash, groupId, &localError); } else if (format == kSecValidInfoFormatNto1) { /* Perform a Bloom filter match against the serial. If matched is false, then the cert is definitely not in the list. But if matched is true, we don't know for certain, so we would need to check OCSP. */ - matched = _SecRevocationDbSerialInFilter(rdb, serial, data); + matched = _SecRevocationDbSerialInFilter(dbc, serial, data); } if (matched) { @@ -2722,7 +3006,7 @@ static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbRe /* If supplemental constraints are present for this issuer, then we always match. */ if ((flags & kSecValidInfoDateConstraints) && - (_SecRevocationDbCopyDateConstraints(rdb, groupId, ¬BeforeDate, ¬AfterDate, &localError))) { + (_SecRevocationDbCopyDateConstraints(dbc, groupId, ¬BeforeDate, ¬AfterDate, &localError))) { secdebug("validupdate", "Valid db matched supplemental date constraints for groupId %lld: nb=%@, na=%@", (long long)groupId, notBeforeDate, notAfterDate); } @@ -2738,8 +3022,7 @@ static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbRe /* Prevent a catch-22. */ secdebug("validupdate", "Valid db match for Apple trust anchor: %@, format=%d, flags=0x%lx", certHash, format, flags); - SecValidInfoRelease(result); - result = NULL; + CFReleaseNull(result); } errOut: @@ -2754,17 +3037,24 @@ errOut: return result; } -static SecValidInfoRef _SecRevocationDbCopyMatching(SecRevocationDbRef db, +static SecValidInfoRef _SecRevocationDbCopyMatching(SecRevocationDbConnectionRef dbc, SecCertificateRef certificate, SecCertificateRef issuer) { SecValidInfoRef result = NULL; CFErrorRef error = NULL; CFDataRef issuerHash = NULL; - require(certificate && issuer, errOut); + require(dbc && certificate && issuer, errOut); require(issuerHash = SecCertificateCopySHA256Digest(issuer), errOut); - result = _SecRevocationDbValidInfoForCertificate(db, certificate, issuerHash, &error); + /* Check for the result in the cache. */ + result = SecRevocationDbCacheRead(dbc->db, certificate, issuerHash); + + /* Upon cache miss, get the result from the database and add it to the cache. */ + if (!result) { + result = _SecRevocationDbValidInfoForCertificate(dbc, certificate, issuerHash, &error); + SecRevocationDbCacheWrite(dbc->db, result); + } errOut: CFReleaseSafe(issuerHash); @@ -2772,85 +3062,16 @@ errOut: return result; } -static dispatch_queue_t _SecRevocationDbGetUpdateQueue(SecRevocationDbRef rdb) { - return (rdb) ? rdb->update_queue : NULL; -} - - -/* Given a valid update dictionary, insert/replace or delete records - in the revocation database. (This function is expected to be called only - by the database maintainer, normally the system instance of trustd.) -*/ -void SecRevocationDbApplyUpdate(CFDictionaryRef update, CFIndex version) { - SecRevocationDbWith(^(SecRevocationDbRef db) { - _SecRevocationDbApplyUpdate(db, update, version); - }); -} - -/* Update the database schema, insert missing tables and replace triggers. - (This function is expected to be called only by the database maintainer, - normally the system instance of trustd.) -*/ -bool SecRevocationDbUpdateSchema(void) { - __block bool result = false; - SecRevocationDbWith(^(SecRevocationDbRef db) { - result = _SecRevocationDbUpdateSchema(db); - }); - return result; -} - -/* Set the schema version for the revocation database. - (This function is expected to be called only by the database maintainer, - normally the system instance of trustd.) -*/ -bool SecRevocationDbSetSchemaVersion(CFIndex db_version) { - __block bool result = false; - SecRevocationDbWith(^(SecRevocationDbRef db) { - result = _SecRevocationDbSetSchemaVersion(db, db_version); - }); - return result; -} - -/* Set the current version for the revocation database. - (This function is expected to be called only by the database maintainer, - normally the system instance of trustd.) -*/ -bool SecRevocationDbSetVersion(CFIndex version) { - __block bool result = false; - SecRevocationDbWith(^(SecRevocationDbRef db) { - _SecRevocationDbSetVersion(db, version); - }); - return result; -} - -/* Set the update format for the revocation database. - (This function is expected to be called only by the database maintainer, - normally the system instance of trustd.) -*/ -void SecRevocationDbSetUpdateFormat(CFIndex db_format) { - SecRevocationDbWith(^(SecRevocationDbRef db) { - _SecRevocationDbSetUpdateFormat(db, db_format); - }); -} - -/* Set the update source for the revocation database. - (This function is expected to be called only by the database - maintainer, normally the system instance of trustd. If the - caller does not have write access, this is a no-op.) -*/ -void SecRevocationDbSetUpdateSource(CFStringRef updateSource) { - SecRevocationDbWith(^(SecRevocationDbRef db) { - _SecRevocationDbSetUpdateSource(db, updateSource); - }); -} - /* Return the update source as a retained CFStringRef. If the value cannot be obtained, NULL is returned. */ CFStringRef SecRevocationDbCopyUpdateSource(void) { __block CFStringRef result = NULL; SecRevocationDbWith(^(SecRevocationDbRef db) { - result = _SecRevocationDbCopyUpdateSource(db, NULL); + (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + result = _SecRevocationDbCopyUpdateSource(dbc, blockError); + return (bool)result; + }); }); return result; } @@ -2860,10 +3081,16 @@ CFStringRef SecRevocationDbCopyUpdateSource(void) { maintainer, normally the system instance of trustd. If the caller does not have write access, this is a no-op.) */ -void SecRevocationDbSetNextUpdateTime(CFAbsoluteTime nextUpdate) { - SecRevocationDbWith(^(SecRevocationDbRef db) { - _SecRevocationDbSetNextUpdateTime(db, nextUpdate); +bool SecRevocationDbSetNextUpdateTime(CFAbsoluteTime nextUpdate, CFErrorRef *error) { + __block bool ok = true; + __block CFErrorRef localError = NULL; + SecRevocationDbWith(^(SecRevocationDbRef rdb) { + ok &= SecRevocationDbPerformWrite(rdb, &localError, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + return _SecRevocationDbSetNextUpdateTime(dbc, nextUpdate, blockError); + }); }); + (void) CFErrorPropagate(localError, error); + return ok; } /* Return the next update value as a CFAbsoluteTime. @@ -2872,7 +3099,10 @@ void SecRevocationDbSetNextUpdateTime(CFAbsoluteTime nextUpdate) { CFAbsoluteTime SecRevocationDbGetNextUpdateTime(void) { __block CFAbsoluteTime result = -1; SecRevocationDbWith(^(SecRevocationDbRef db) { - result = _SecRevocationDbGetNextUpdateTime(db, NULL); + (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + result = _SecRevocationDbGetNextUpdateTime(dbc, blockError); + return true; + }); }); return result; } @@ -2883,21 +3113,11 @@ CFAbsoluteTime SecRevocationDbGetNextUpdateTime(void) { dispatch_queue_t SecRevocationDbGetUpdateQueue(void) { __block dispatch_queue_t result = NULL; SecRevocationDbWith(^(SecRevocationDbRef db) { - result = _SecRevocationDbGetUpdateQueue(db); + result = (db) ? db->update_queue : NULL; }); return result; } -/* Remove all entries in the revocation database and reset its version to 0. - (This function is expected to be called only by the database maintainer, - normally the system instance of trustd.) -*/ -void SecRevocationDbRemoveAllEntries(void) { - SecRevocationDbWith(^(SecRevocationDbRef db) { - _SecRevocationDbRemoveAllEntries(db); - }); -} - /* Release all connections to the revocation database. */ void SecRevocationDbReleaseAllConnections(void) { @@ -2910,14 +3130,37 @@ void SecRevocationDbReleaseAllConnections(void) { /* Given a certificate and its issuer, returns a SecValidInfoRef if the valid database contains matching info; otherwise returns NULL. - Caller must release the returned SecValidInfoRef by calling - SecValidInfoRelease when finished. + Caller must release the returned SecValidInfoRef when finished. */ SecValidInfoRef SecRevocationDbCopyMatching(SecCertificateRef certificate, SecCertificateRef issuer) { __block SecValidInfoRef result = NULL; SecRevocationDbWith(^(SecRevocationDbRef db) { - result = _SecRevocationDbCopyMatching(db, certificate, issuer); + (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + result = _SecRevocationDbCopyMatching(dbc, certificate, issuer); + return (bool)result; + }); + }); + return result; +} + +/* Given an issuer, returns true if an entry for this issuer exists in + the database (i.e. a known CA). If the provided certificate is NULL, + or its entry is not found, the function returns false. +*/ +bool SecRevocationDbContainsIssuer(SecCertificateRef issuer) { + if (!issuer) { + return false; + } + __block bool result = false; + SecRevocationDbWith(^(SecRevocationDbRef db) { + (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + CFDataRef issuerHash = SecCertificateCopySHA256Digest(issuer); + int64_t groupId = _SecRevocationDbGroupIdForIssuerHash(dbc, issuerHash, blockError); + CFReleaseSafe(issuerHash); + result = (groupId > 0); + return result; + }); }); return result; } @@ -2929,31 +3172,37 @@ SecValidInfoRef SecRevocationDbCopyMatching(SecCertificateRef certificate, CFIndex SecRevocationDbGetVersion(void) { __block CFIndex result = -1; SecRevocationDbWith(^(SecRevocationDbRef db) { - result = (CFIndex)_SecRevocationDbGetVersion(db, NULL); + (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + result = (CFIndex)_SecRevocationDbGetVersion(dbc, blockError); + return (result >= 0); + }); }); return result; } /* Return the current schema version of the revocation database. - A version of 0 indicates an empty database which must be populated. - If the schema version cannot be obtained, -1 is returned. -*/ + A version of 0 indicates an empty database which must be populated. + If the schema version cannot be obtained, -1 is returned. + */ CFIndex SecRevocationDbGetSchemaVersion(void) { __block CFIndex result = -1; SecRevocationDbWith(^(SecRevocationDbRef db) { - result = (CFIndex)_SecRevocationDbGetSchemaVersion(db, NULL); + result = _SecRevocationDbGetSchemaVersion(db, NULL, NULL); }); return result; } /* Return the current update format of the revocation database. - A version of 0 indicates the format was unknown. - If the update format cannot be obtained, -1 is returned. -*/ + A version of 0 indicates the format was unknown. + If the update format cannot be obtained, -1 is returned. + */ CFIndex SecRevocationDbGetUpdateFormat(void) { __block CFIndex result = -1; SecRevocationDbWith(^(SecRevocationDbRef db) { - result = (CFIndex)_SecRevocationDbGetUpdateFormat(db, NULL); + (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + result = (CFIndex)_SecRevocationDbGetUpdateFormat(dbc, blockError); + return (result >= 0); + }); }); return result; } diff --git a/OSX/sec/securityd/SecRevocationDb.h b/OSX/sec/securityd/SecRevocationDb.h index dd4b05a9..709f5274 100644 --- a/OSX/sec/securityd/SecRevocationDb.h +++ b/OSX/sec/securityd/SecRevocationDb.h @@ -31,6 +31,7 @@ #ifndef _SECURITY_SECREVOCATIONDB_H_ #define _SECURITY_SECREVOCATIONDB_H_ +#include #include #include #include @@ -50,11 +51,13 @@ typedef CF_ENUM(uint32_t, SecValidInfoFormat) { /*! @typedef SecValidInfoRef - @abstract Object used to return valid info lookup results. + @abstract CFType used to return valid info lookup results. */ typedef struct __SecValidInfo *SecValidInfoRef; struct __SecValidInfo { + CFRuntimeBase _base; + SecValidInfoFormat format; // format of per-issuer validity data CFDataRef certHash; // SHA-256 hash of cert to which the following info applies CFDataRef issuerHash; // SHA-256 hash of issuing CA certificate @@ -63,7 +66,7 @@ struct __SecValidInfo { bool valid; // true if this is an allow list, false if a block list bool complete; // true if list is complete (i.e. status is definitive) bool checkOCSP; // true if complete is false and OCSP check is required - bool knownOnly; // true if all intermediates under issuer must be found in database + bool knownOnly; // true if intermediate CAs under issuer must be found in database bool requireCT; // true if this cert must have CT proof bool noCACheck; // true if an entry does not require an OCSP check to accept bool overridable; // true if the trust status is recoverable and can be overridden @@ -76,13 +79,6 @@ struct __SecValidInfo { CFDataRef policyConstraints; // policy constraints blob (if policyConstraints is true) }; -/*! - @function SecValidInfoRelease - @abstract Releases a SecValidInfo reference previously obtained from a call to SecRevocationDbCopyMatching. - @param validInfo The SecValidInfo reference to be released. - */ -void SecValidInfoRelease(SecValidInfoRef validInfo); - /*! @function SecValidInfoSetAnchor @abstract Updates a SecValidInfo reference with info about the anchor certificate in a chain. @@ -103,11 +99,19 @@ void SecRevocationDbCheckNextUpdate(void); @abstract Returns a SecValidInfo reference if matching revocation (or allow list) info was found. @param certificate The certificate whose validity status is being requested. @param issuer The issuing CA certificate. If the cert is self-signed, the same reference should be passed in both certificate and issuer parameters. Omitting either cert parameter is an error and NULL will be returned. - @result A SecValidInfoRef if there was matching revocation info. Caller must release this reference when finished by calling SecValidInfoRelease. NULL is returned if no matching info was found in the database. + @result A SecValidInfoRef if there was matching revocation info. Caller must release this reference when finished by calling CFRelease. NULL is returned if no matching info was found in the database. */ SecValidInfoRef SecRevocationDbCopyMatching(SecCertificateRef certificate, SecCertificateRef issuer); +/*! + @function SecRevocationDbContainsIssuer + @abstract Returns true if the database contains an entry for the specified CA certificate. + @param issuer The certificate being checked. + @result If a matching issuer group was found, returns true, otherwise false. +*/ +bool SecRevocationDbContainsIssuer(SecCertificateRef issuer); + /*! @function SecRevocationDbGetVersion @abstract Returns a CFIndex containing the version number of the database. @@ -153,6 +157,16 @@ void SecRevocationDbComputeAndSetNextUpdateTime(void); */ void SecRevocationDbInitialize(void); +extern const CFStringRef kValidUpdateProdServer; +extern const CFStringRef kValidUpdateCarryServer; + +/*! + @function SecRevocationDbCopyUpdateSource + @abstract Returns the server source for updates of the revocation database. + @result The base string of the server URI. + */ +CFStringRef SecRevocationDbCopyUpdateSource(void); + __END_DECLS diff --git a/OSX/sec/securityd/SecRevocationNetworking.h b/OSX/sec/securityd/SecRevocationNetworking.h index 6af99881..8c36345d 100644 --- a/OSX/sec/securityd/SecRevocationNetworking.h +++ b/OSX/sec/securityd/SecRevocationNetworking.h @@ -22,6 +22,13 @@ * */ +#ifndef _SECURITY_SECREVOCATIONNETWORKING_H_ +#define _SECURITY_SECREVOCATIONNETWORKING_H_ + #import +#import bool SecValidUpdateRequest(dispatch_queue_t queue, CFStringRef server, CFIndex version); +bool SecORVCBeginFetches(SecORVCRef orvc, SecCertificateRef cert); + +#endif /* _SECURITY_SECREVOCATIONNETWORKING_H_ */ diff --git a/OSX/sec/securityd/SecRevocationNetworking.m b/OSX/sec/securityd/SecRevocationNetworking.m index 48672e3a..9b1673b9 100644 --- a/OSX/sec/securityd/SecRevocationNetworking.m +++ b/OSX/sec/securityd/SecRevocationNetworking.m @@ -28,17 +28,26 @@ #include #include +#include #include +#include #include "utilities/debugging.h" #include "utilities/SecCFWrappers.h" #include "utilities/SecPLWrappers.h" #include "utilities/SecFileLocations.h" #include "SecRevocationDb.h" +#include "SecRevocationServer.h" +#include "SecTrustServer.h" +#include "SecOCSPRequest.h" +#include "SecOCSPResponse.h" + #import "SecTrustLoggingServer.h" +#import "TrustURLSessionDelegate.h" #import "SecRevocationNetworking.h" +/* MARK: Valid Update Networking */ #define kSecRevocationBasePath "/Library/Keychains/crls" static CFStringRef kSecPrefsDomain = CFSTR("com.apple.security"); @@ -82,11 +91,6 @@ typedef void (^CompletionHandler)(void); @implementation ValidDelegate - (void)reschedule { - /* make sure we release any os transaction, if we went active */ - if (self->_transaction) { - //os_release(self->_transaction); // ARC does this for us and won't let us call release - self->_transaction = NULL; - } /* POWER LOG EVENT: operation canceled */ SecPLLogRegisteredEvent(@"ValidUpdateEvent", @{ @"timestamp" : @([[NSDate date] timeIntervalSince1970]), @@ -98,6 +102,9 @@ typedef void (^CompletionHandler)(void); self->_handler(); SecRevocationDbComputeAndSetNextUpdateTime(); + if (self->_transaction) { + self->_transaction = nil; + } } - (void)updateDb:(NSUInteger)version { @@ -109,6 +116,8 @@ typedef void (^CompletionHandler)(void); return; } + /* Hold a transaction until we finish the update */ + __block os_transaction_t transaction = os_transaction_create("com.apple.trustd.valid.updateDb"); dispatch_async(_revDbUpdateQueue, ^{ /* POWER LOG EVENT: background update started */ SecPLLogRegisteredEvent(@"ValidUpdateEvent", @{ @@ -124,6 +133,7 @@ typedef void (^CompletionHandler)(void); secerror("failed to read %@ with error %d", updateFileURL, rtn); TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, rtn); [self reschedule]; + transaction = nil; return; } @@ -154,6 +164,7 @@ typedef void (^CompletionHandler)(void); gUpdateStarted = 0; self->_handler(); + transaction = nil; // we're all done now }); } @@ -165,6 +176,8 @@ typedef void (^CompletionHandler)(void); dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { + /* nsurlsessiond started our download. Create a transaction since we're going to be working for a little bit */ + self->_transaction = os_transaction_create("com.apple.trustd.valid.download"); secinfo("validupdate", "Session %@ data task %@ returned response %ld, expecting %lld bytes", session, dataTask, (long)[(NSHTTPURLResponse *)response statusCode],[response expectedContentLength]); @@ -211,8 +224,6 @@ didReceiveResponse:(NSURLResponse *)response return; } - /* We're about to begin downloading -- go active now so we don't get jetsammed */ - self->_transaction = os_transaction_create("com.apple.trustd.valid.download"); completionHandler(NSURLSessionResponseAllow); } @@ -244,11 +255,6 @@ didReceiveResponse:(NSURLResponse *)response - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { - /* all finished downloading data -- go inactive */ - if (self->_transaction) { - // os_release(self->_transaction); // ARC does this for us and won't let us call release - self->_transaction = NULL; - } if (error) { secnotice("validupdate", "Session %@ task %@ failed with error %@", session, task, error); #if ENABLE_TRUSTD_ANALYTICS @@ -271,6 +277,9 @@ didCompleteWithError:(NSError *)error { self->_finishedDownloading = YES; [self updateDb:[self versionFromTask:task]]; } + if (self->_transaction) { + self->_transaction = nil; + } } @end @@ -359,6 +368,8 @@ static ValidUpdateRequest *request = nil; * after system boot before trying to initiate network activity, to avoid the possibility * of a performance regression in the boot path. */ dispatch_async(updateQueue, ^{ + /* Take a transaction while we work */ + os_transaction_t transaction = os_transaction_create("com.apple.trustd.valid.scheduleUpdate"); CFAbsoluteTime now = CFAbsoluteTimeGetCurrent(); if (self.updateScheduled != 0.0) { secdebug("validupdate", "update in progress (scheduled %f)", (double)self.updateScheduled); @@ -386,13 +397,18 @@ static ValidUpdateRequest *request = nil; /* clear all old sessions and cleanup disk (for previous download tasks) */ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - [NSURLSession _obliterateAllBackgroundSessionsWithCompletionHandler:^{ - secnotice("validupdate", "removing all old sessions for trustd"); - }]; + @autoreleasepool { + [NSURLSession _obliterateAllBackgroundSessionsWithCompletionHandler:^{ + secnotice("validupdate", "removing all old sessions for trustd"); + }]; + } }); if (!self.backgroundSession) { [self createSession:updateQueue forServer:server]; + } else { + ValidDelegate *delegate = (ValidDelegate *)[self.backgroundSession delegate]; + delegate.currentUpdateServer = [server copy]; } /* POWER LOG EVENT: scheduling our background download session now */ @@ -406,6 +422,8 @@ static ValidUpdateRequest *request = nil; dataTask.taskDescription = [NSString stringWithFormat:@"%lu",(unsigned long)version]; [dataTask resume]; secnotice("validupdate", "scheduled background data task %@ at %f", dataTask, CFAbsoluteTimeGetCurrent()); + (void) transaction; // dead store + transaction = nil; }); return YES; @@ -413,9 +431,178 @@ static ValidUpdateRequest *request = nil; @end bool SecValidUpdateRequest(dispatch_queue_t queue, CFStringRef server, CFIndex version) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - request = [[ValidUpdateRequest alloc] init]; - }); - return [request scheduleUpdateFromServer:(__bridge NSString*)server forVersion:version withQueue:queue]; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + @autoreleasepool { + request = [[ValidUpdateRequest alloc] init]; + } + }); + @autoreleasepool { + return [request scheduleUpdateFromServer:(__bridge NSString*)server forVersion:version withQueue:queue]; + } +} + +/* MARK: - */ +/* MARK: OCSP Fetch Networking */ +#define OCSP_REQUEST_THRESHOLD 10 + +@interface OCSPFetchDelegate : TrustURLSessionDelegate +@end + +@implementation OCSPFetchDelegate +- (BOOL)fetchNext:(NSURLSession *)session { + SecORVCRef orvc = (SecORVCRef)self.context; + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(orvc->builder); + + BOOL result = true; + if ((result = [super fetchNext:session])) { + /* no fetch scheduled */ + orvc->done = true; + } else { + if (self.URIix > 0) { + orvc->responder = (__bridge CFURLRef)self.URIs[self.URIix - 1]; + } else { + orvc->responder = (__bridge CFURLRef)self.URIs[0]; + } + if (analytics) { + analytics->ocsp_fetches++; + } + } + return result; +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { + /* call the superclass's method to set expiration */ + [super URLSession:session task:task didCompleteWithError:error]; + + __block SecORVCRef orvc = (SecORVCRef)self.context; + if (!orvc || !orvc->builder) { + /* We already returned to the PathBuilder state machine. */ + return; + } + + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(orvc->builder); + if (error) { + /* Log the error */ + secnotice("rvc", "Failed to download ocsp response %@, with error %@", task.originalRequest.URL, error); + if (analytics) { + analytics->ocsp_fetch_failed++; + } + } else { + SecOCSPResponseRef ocspResponse = SecOCSPResponseCreate((__bridge CFDataRef)self.response); + if (ocspResponse) { + SecORVCConsumeOCSPResponse(orvc, ocspResponse, self.expiration, true, false); + if (analytics && !orvc->done) { + /* We got an OCSP response that didn't pass validation */ + analytics-> ocsp_validation_failed = true; + } + } else if (analytics) { + /* We got something that wasn't an OCSP response (e.g. captive portal) -- + * we consider that a fetch failure */ + analytics->ocsp_fetch_failed++; + } + } + + /* If we didn't get a valid OCSP response, try the next URI */ + if (!orvc->done) { + (void)[self fetchNext:session]; + } + + /* We got a valid OCSP response or couldn't schedule any more fetches. + * Close the session, update the PVCs, decrement the async count, and callback if we're all done. */ + if (orvc->done) { + secdebug("rvc", "builder %p, done with OCSP fetches for cert: %ld", orvc->builder, orvc->certIX); + self.context = nil; + [session invalidateAndCancel]; + SecORVCUpdatePVC(orvc); + if (0 == SecPathBuilderDecrementAsyncJobCount(orvc->builder)) { + /* We're the last async job to finish, jump back into the state machine */ + secdebug("rvc", "builder %p, done with all async jobs", orvc->builder); + dispatch_async(SecPathBuilderGetQueue(orvc->builder), ^{ + SecPathBuilderStep(orvc->builder); + }); + } + } +} + +- (NSURLRequest *)createNextRequest:(NSURL *)uri { + SecORVCRef orvc = (SecORVCRef)self.context; + CFDataRef ocspDER = CFRetainSafe(SecOCSPRequestGetDER(orvc->ocspRequest)); + NSData *nsOcspDER = CFBridgingRelease(ocspDER); + NSString *ocspBase64 = [nsOcspDER base64EncodedStringWithOptions:0]; + NSString *escapedRequest = [ocspBase64 stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]; + NSURLRequest *request = nil; + + /* Interesting tidbit from rfc5019 + When sending requests that are less than or equal to 255 bytes in + total (after encoding) including the scheme and delimiters (http://), + server name and base64-encoded OCSPRequest structure, clients MUST + use the GET method (to enable OCSP response caching). OCSP requests + larger than 255 bytes SHOULD be submitted using the POST method. + */ + if ([escapedRequest length] < 256) { + /* Use a GET */ + NSURL *requestURL = [uri URLByAppendingPathComponent:escapedRequest]; + request = [NSURLRequest requestWithURL:requestURL]; + } else { + /* Use a POST */ + NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:uri]; + mutableRequest.HTTPMethod = @"POST"; + mutableRequest.HTTPBody = nsOcspDER; + request = mutableRequest; + } + + return request; +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)taskMetrics { + secdebug("rvc", "got metrics with task interval %f", taskMetrics.taskInterval.duration); + SecORVCRef orvc = (SecORVCRef)self.context; + if (orvc && orvc->builder) { + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(orvc->builder); + if (analytics) { + analytics->ocsp_fetch_time += (uint64_t)(taskMetrics.taskInterval.duration * NSEC_PER_SEC); + } + } +} +@end + +bool SecORVCBeginFetches(SecORVCRef orvc, SecCertificateRef cert) { + @autoreleasepool { + CFArrayRef ocspResponders = CFRetainSafe(SecCertificateGetOCSPResponders(cert)); + NSArray *nsResponders = CFBridgingRelease(ocspResponders); + + NSInteger count = [nsResponders count]; + if (count > OCSP_REQUEST_THRESHOLD) { + secnotice("rvc", "too may OCSP responder entries (%ld)", (long)count); + orvc->done = true; + return true; + } + + NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + config.timeoutIntervalForResource = TrustURLSessionGetResourceTimeout(); + config.HTTPAdditionalHeaders = @{@"User-Agent" : @"com.apple.trustd/2.0"}; + + NSData *auditToken = CFBridgingRelease(SecPathBuilderCopyClientAuditToken(orvc->builder)); + if (auditToken) { + config._sourceApplicationAuditTokenData = auditToken; + } + + OCSPFetchDelegate *delegate = [[OCSPFetchDelegate alloc] init]; + delegate.context = orvc; + delegate.URIs = nsResponders; + delegate.URIix = 0; + + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; + + NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:queue]; + secdebug("rvc", "created URLSession for %@", cert); + + bool result = false; + if ((result = [delegate fetchNext:session])) { + /* no fetch scheduled, close the session */ + [session invalidateAndCancel]; + } + return result; + } } diff --git a/OSX/sec/securityd/SecRevocationServer.c b/OSX/sec/securityd/SecRevocationServer.c index 60b319f6..c23ea89e 100644 --- a/OSX/sec/securityd/SecRevocationServer.c +++ b/OSX/sec/securityd/SecRevocationServer.c @@ -42,11 +42,11 @@ #include #include #include -#include #include #include #include #include +#include #include @@ -58,45 +58,8 @@ const CFAbsoluteTime kSecDefaultOCSPResponseTTL = 24.0 * 60.0 * 60.0; const CFAbsoluteTime kSecOCSPResponseOnlineTTL = 5.0 * 60.0; #define OCSP_RESPONSE_TIMEOUT (3 * NSEC_PER_SEC) -/* OCSP Revocation verification context. */ -struct OpaqueSecORVC { - /* Will contain the response data. */ - asynchttp_t http; - - /* Pointer to the builder for this revocation check. */ - SecPathBuilderRef builder; - - /* Pointer to the generic rvc for this revocation check */ - SecRVCRef rvc; - - /* The ocsp request we send to each responder. */ - SecOCSPRequestRef ocspRequest; - - /* The freshest response we received so far, from stapling or cache or responder. */ - SecOCSPResponseRef ocspResponse; - - /* The best validated candidate single response we received so far, from stapling or cache or responder. */ - SecOCSPSingleResponseRef ocspSingleResponse; - - /* Index of cert in builder that this RVC is for 0 = leaf, etc. */ - CFIndex certIX; - - /* Index in array returned by SecCertificateGetOCSPResponders() for current - responder. */ - CFIndex responderIX; - - /* URL of current responder. */ - CFURLRef responder; - - /* Date until which this revocation status is valid. */ - CFAbsoluteTime nextUpdate; - - bool done; -}; - static void SecORVCFinish(SecORVCRef orvc) { - secdebug("alloc", "%p", orvc); - asynchttp_free(&orvc->http); + secdebug("alloc", "finish orvc %p", orvc); if (orvc->ocspRequest) { SecOCSPRequestFinalize(orvc->ocspRequest); orvc->ocspRequest = NULL; @@ -109,57 +72,7 @@ static void SecORVCFinish(SecORVCRef orvc) { orvc->ocspSingleResponse = NULL; } } -} - -#define MAX_OCSP_RESPONDERS 3 -#define OCSP_REQUEST_THRESHOLD 10 - -/* Return the next responder we should contact for this rvc or NULL if we - exhausted them all. */ -static CFURLRef SecORVCGetNextResponder(SecORVCRef rvc) { - SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); - CFArrayRef ocspResponders = SecCertificateGetOCSPResponders(cert); - if (ocspResponders) { - CFIndex responderCount = CFArrayGetCount(ocspResponders); - if (responderCount >= OCSP_REQUEST_THRESHOLD) { - secnotice("rvc", "too many ocsp responders (%ld)", (long)responderCount); - return NULL; - } - while (rvc->responderIX < responderCount && rvc->responderIX < MAX_OCSP_RESPONDERS) { - CFURLRef responder = CFArrayGetValueAtIndex(ocspResponders, rvc->responderIX); - rvc->responderIX++; - CFStringRef scheme = CFURLCopyScheme(responder); - if (scheme) { - /* We only support http and https responders currently. */ - bool valid_responder = (CFEqual(CFSTR("http"), scheme) || - CFEqual(CFSTR("https"), scheme)); - CFRelease(scheme); - if (valid_responder) - return responder; - } - } - } - return NULL; -} - -/* Fire off an async http request for this certs revocation status, return - false if request was queued, true if we're done. */ -static bool SecORVCFetchNext(SecORVCRef rvc) { - while ((rvc->responder = SecORVCGetNextResponder(rvc))) { - CFDataRef request = SecOCSPRequestGetDER(rvc->ocspRequest); - if (!request) - goto errOut; - - secinfo("rvc", "Sending http ocsp request for cert %ld", rvc->certIX); - if (!asyncHttpPost(rvc->responder, request, OCSP_RESPONSE_TIMEOUT, &rvc->http)) { - /* Async request was posted, wait for reply. */ - return false; - } - } - -errOut: - rvc->done = true; - return true; + memset(orvc, 0, sizeof(struct OpaqueSecORVC)); } /* Process a verified ocsp response for a given cert. Return true if the @@ -211,7 +124,7 @@ static bool SecOCSPSingleResponseProcess(SecOCSPSingleResponseRef this, return processed; } -static void SecORVCUpdatePVC(SecORVCRef rvc) { +void SecORVCUpdatePVC(SecORVCRef rvc) { if (rvc->ocspSingleResponse) { SecOCSPSingleResponseProcess(rvc->ocspSingleResponse, rvc); } @@ -271,11 +184,7 @@ static bool SecOCSPResponseEvaluateSigner(SecORVCRef rvc, CFArrayRef signers, CF signer = (SecCertificateRef)CFArrayGetValueAtIndex(signers, 0); if (issuer) { -#if TARGET_OS_IPHONE - issuerPubKey = SecCertificateCopyPublicKey(issuer); -#else - issuerPubKey = SecCertificateCopyPublicKey_ios(issuer); -#endif + issuerPubKey = SecCertificateCopyKey(issuer); } if (signer && issuerPubKey && (errSecSuccess == SecCertificateIsSignedBy(signer, issuerPubKey))) { trusted = true; @@ -350,7 +259,8 @@ static bool SecOCSPResponseVerify(SecOCSPResponseRef ocspResponse, SecORVCRef rv return trusted; } -static void SecORVCConsumeOCSPResponse(SecORVCRef rvc, SecOCSPResponseRef ocspResponse /*CF_CONSUMED*/, CFTimeInterval maxAge, bool updateCache) { +void SecORVCConsumeOCSPResponse(SecORVCRef rvc, SecOCSPResponseRef ocspResponse /*CF_CONSUMED*/, + CFTimeInterval maxAge, bool updateCache, bool fromCache) { SecOCSPSingleResponseRef sr = NULL; require_quiet(ocspResponse, errOut); SecOCSPResponseStatus orStatus = SecOCSPGetResponseStatus(ocspResponse); @@ -362,9 +272,18 @@ static void SecORVCConsumeOCSPResponse(SecORVCRef rvc, SecOCSPResponseRef ocspRe require_quiet(!rvc->ocspSingleResponse || rvc->ocspSingleResponse->thisUpdate < sr->thisUpdate, errOut); CFAbsoluteTime verifyTime = CFAbsoluteTimeGetCurrent(); - /* Check the OCSP response signature and verify the response. */ +#if TARGET_OS_IPHONE + /* Check the OCSP response signature and verify the response if not pulled from the cache. + * Performance optimization since we don't write invalid responses to the cache. */ + if (!fromCache) { + require_quiet(SecOCSPResponseVerify(ocspResponse, rvc, + sr->certStatus == CS_Revoked ? SecOCSPResponseProducedAt(ocspResponse) : verifyTime), errOut); + } +#else + /* Always check the OCSP response signature and verify the response (since the cache is user-modifiable). */ require_quiet(SecOCSPResponseVerify(ocspResponse, rvc, sr->certStatus == CS_Revoked ? SecOCSPResponseProducedAt(ocspResponse) : verifyTime), errOut); +#endif // If we get here, we have a properly signed ocsp response // but we haven't checked dates yet. @@ -397,72 +316,15 @@ errOut: if (ocspResponse) SecOCSPResponseFinalize(ocspResponse); } -/* Callback from async http code after an ocsp response has been received. */ -static void SecOCSPFetchCompleted(asynchttp_t *http, CFTimeInterval maxAge) { - SecORVCRef rvc = (SecORVCRef)http->info; - SecPathBuilderRef builder = rvc->builder; - TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); - if (analytics) { - /* Add the time this fetch took to complete to the total time */ - analytics->ocsp_fetch_time += (mach_absolute_time() - http->start_time); - } - SecOCSPResponseRef ocspResponse = NULL; - if (http->response) { - CFDataRef data = CFHTTPMessageCopyBody(http->response); - if (data) { - /* Parse the returned data as if it's an ocspResponse. */ - ocspResponse = SecOCSPResponseCreate(data); - CFRelease(data); - } - } - - if ((!http->response || !ocspResponse) && analytics) { - /* We didn't get any data back, so the fetch failed */ - analytics->ocsp_fetch_failed++; - } - - SecORVCConsumeOCSPResponse(rvc, ocspResponse, maxAge, true); - // TODO: maybe we should set the cache-control: false in the http header and try again if the response is stale - - if (!rvc->done) { - if (analytics && ocspResponse) { - /* We got an OCSP response that didn't pass validation */ - analytics-> ocsp_validation_failed = true; - } - /* Clear the data for the next response. */ - asynchttp_free(http); - SecORVCFetchNext(rvc); - } - - if (rvc->done) { - secdebug("rvc", "got OCSP response for cert: %ld", rvc->certIX); - SecORVCUpdatePVC(rvc); - if (!SecPathBuilderDecrementAsyncJobCount(builder)) { - secdebug("rvc", "done with all async jobs"); - SecPathBuilderStep(builder); - } - } -} - static SecORVCRef SecORVCCreate(SecRVCRef rvc, SecPathBuilderRef builder, CFIndex certIX) { SecORVCRef orvc = NULL; orvc = malloc(sizeof(struct OpaqueSecORVC)); + secdebug("alloc", "orvc %p", orvc); if (orvc) { memset(orvc, 0, sizeof(struct OpaqueSecORVC)); orvc->builder = builder; orvc->rvc = rvc; orvc->certIX = certIX; - orvc->http.queue = SecPathBuilderGetQueue(builder); - orvc->http.token = SecPathBuilderCopyClientAuditToken(builder); - orvc->http.completed = SecOCSPFetchCompleted; - orvc->http.info = orvc; - orvc->ocspRequest = NULL; - orvc->responderIX = 0; - orvc->responder = NULL; - orvc->nextUpdate = NULL_TIME; - orvc->ocspResponse = NULL; - orvc->ocspSingleResponse = NULL; - orvc->done = false; SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(builder, certIX); if (SecPathBuilderGetCertificateCount(builder) > (certIX + 1)) { @@ -481,7 +343,7 @@ static void SecORVCProcessStapledResponses(SecORVCRef rvc) { secdebug("rvc", "Checking stapled responses for cert %ld", rvc->certIX); CFArrayForEach(ocspResponsesData, ^(const void *value) { SecOCSPResponseRef ocspResponse = SecOCSPResponseCreate(value); - SecORVCConsumeOCSPResponse(rvc, ocspResponse, NULL_TIME, false); + SecORVCConsumeOCSPResponse(rvc, ocspResponse, NULL_TIME, false, false); }); CFRelease(ocspResponsesData); } @@ -717,6 +579,7 @@ static bool SecRVCShouldCheckCRL(SecRVCRef rvc) { #endif /* ENABLE_CRLS */ void SecRVCDelete(SecRVCRef rvc) { + secdebug("alloc", "delete rvc %p", rvc); if (rvc->orvc) { SecORVCFinish(rvc->orvc); free(rvc->orvc); @@ -730,13 +593,15 @@ void SecRVCDelete(SecRVCRef rvc) { } #endif if (rvc->valid_info) { - SecValidInfoRelease(rvc->valid_info); - rvc->valid_info = NULL; + CFReleaseNull(rvc->valid_info); } } +// Forward declaration +static void SecRVCSetFinishedWithoutNetwork(SecRVCRef rvc); + static void SecRVCInit(SecRVCRef rvc, SecPathBuilderRef builder, CFIndex certIX) { - secdebug("alloc", "%p", rvc); + secdebug("alloc", "rvc %p", rvc); rvc->builder = builder; rvc->certIX = certIX; rvc->orvc = SecORVCCreate(rvc, builder, certIX); @@ -749,7 +614,7 @@ static void SecRVCInit(SecRVCRef rvc, SecPathBuilderRef builder, CFIndex certIX) #endif ) { SecRVCDelete(rvc); - rvc->done = true; + SecRVCSetFinishedWithoutNetwork(rvc); } else { rvc->done = false; } @@ -859,17 +724,24 @@ bool SecRVCHasRevokedValidInfo(SecRVCRef rvc) { return (!info->isOnList && info->valid) || (info->isOnList && !info->valid); } -void SecRVCSetRevokedResult(SecRVCRef rvc) { +void SecRVCSetValidDeterminedErrorResult(SecRVCRef rvc) { if (!rvc || !rvc->valid_info || !rvc->builder) { return; } if (rvc->valid_info->overridable) { /* error is recoverable, treat certificate as untrusted */ - SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckGrayListedKey, rvc->certIX, + SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckGrayListedLeaf, rvc->certIX, + kCFBooleanFalse, true); + return; + } + /* error is fatal at this point */ + if (!SecRVCHasRevokedValidInfo(rvc) || rvc->valid_info->noCACheck) { + /* result key should indicate blocked instead of revoked, + * but result must be non-recoverable */ + SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckBlackListedLeaf, rvc->certIX, kCFBooleanFalse, true); return; } - /* error is fatal, treat certificate as revoked */ SInt32 reason = 0; /* unspecified, since the Valid db doesn't tell us */ CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason); SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckRevocation, rvc->certIX, @@ -900,6 +772,8 @@ static void SecRVCProcessValidInfoResults(SecRVCRef rvc) { } else { analytics->valid_status |= definitive ? TAValidDefinitelyOK : TAValidProbablyOK; } + analytics->valid_require_ct |= info->requireCT; + analytics->valid_known_intermediates_only |= info->knownOnly; } /* Handle no-ca cases */ @@ -907,7 +781,7 @@ static void SecRVCProcessValidInfoResults(SecRVCRef rvc) { bool allowed = (info->valid && info->complete && info->isOnList); if (revoked) { /* definitely revoked */ - SecRVCSetRevokedResult(rvc); + SecRVCSetValidDeterminedErrorResult(rvc); } else if (allowed) { /* definitely not revoked (allowlisted) */ SecCertificatePathVCSetIsAllowlisted(path, true); @@ -926,9 +800,6 @@ static void SecRVCProcessValidInfoResults(SecRVCRef rvc) { /* Set CT requirement on path, if present. */ if (info->requireCT) { - if (analytics) { - analytics->valid_require_ct |= info->requireCT; - } SecPathCTPolicy ctp = kSecPathCTRequired; if (info->overridable) { ctp = kSecPathCTRequiredOverridable; @@ -942,10 +813,6 @@ static void SecRVCProcessValidInfoResults(SecRVCRef rvc) { } if (info->checkOCSP) { - if (analytics) { - /* Valid DB results caused us to do OCSP */ - analytics->valid_trigger_ocsp = true; - } CFIndex count = SecPathBuilderGetCertificateCount(rvc->builder); CFIndex issuerIX = rvc->certIX + 1; if (issuerIX >= count) { @@ -953,31 +820,13 @@ static void SecRVCProcessValidInfoResults(SecRVCRef rvc) { chain, since we don't have its issuer. */ return; } - CFIndex pvcIX; - for (pvcIX = 0; pvcIX < SecPathBuilderGetPVCCount(rvc->builder); pvcIX++) { - SecPVCRef pvc = SecPathBuilderGetPVCAtIndex(rvc->builder, pvcIX); - if (!pvc) { continue; } - SecPolicyRef policy = (SecPolicyRef)CFArrayGetValueAtIndex(pvc->policies, 0); - CFStringRef policyName = (policy) ? SecPolicyGetName(policy) : NULL; - if (policyName && CFEqual(CFSTR("sslServer"), policyName)) { - /* perform revocation check for SSL policy; - require for leaf if an OCSP responder is present. */ - if (0 == rvc->certIX) { - SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); - CFArrayRef resps = (cert) ? SecCertificateGetOCSPResponders(cert) : NULL; - CFIndex rcount = (resps) ? CFArrayGetCount(resps) : 0; - if (rcount > 0) { - // %%% rdar://31279923 - // This currently requires a valid revocation response for each cert, - // but we only want to require a leaf check. For now, do not require. - //SecPathBuilderSetRevocationResponseRequired(rvc->builder); - } - } - secdebug("validupdate", "rvc: %s%s cert %" PRIdCFIndex " (will check OCSP)", - (info->complete) ? "" : "possibly ", (info->valid) ? "allowed" : "revoked", - rvc->certIX); - SecPathBuilderSetRevocationMethod(rvc->builder, kSecPolicyCheckRevocationAny); - } + secdebug("validupdate", "rvc: %s%s cert %" PRIdCFIndex " (will check OCSP)", + (info->complete) ? "" : "possibly ", (info->valid) ? "allowed" : "revoked", + rvc->certIX); + SecPathBuilderSetRevocationMethod(rvc->builder, kSecPolicyCheckRevocationAny); + if (analytics) { + /* Valid DB results caused us to do OCSP */ + analytics->valid_trigger_ocsp = true; } } } @@ -1028,7 +877,7 @@ static bool SecRVCCheckValidInfoDatabase(SecRVCRef rvc) { SecValidInfoRef old_info = rvc->valid_info; rvc->valid_info = info; if (old_info) { - SecValidInfoRelease(old_info); + CFReleaseNull(old_info); } return true; } @@ -1046,9 +895,7 @@ static void SecRVCCheckRevocationCaches(SecRVCRef rvc) { } else { response = SecOCSPCacheCopyMatching(rvc->orvc->ocspRequest, NULL); } - SecORVCConsumeOCSPResponse(rvc->orvc, - response, - NULL_TIME, false); + SecORVCConsumeOCSPResponse(rvc->orvc, response, NULL_TIME, false, true); TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder); if (rvc->orvc->done && analytics) { /* We found a valid OCSP response in the cache */ @@ -1071,20 +918,31 @@ static void SecRVCUpdatePVC(SecRVCRef rvc) { #endif } +static void SecRVCSetFinishedWithoutNetwork(SecRVCRef rvc) { + rvc->done = true; + SecRVCUpdatePVC(rvc); + (void)SecPathBuilderDecrementAsyncJobCount(rvc->builder); +#if ENABLE_CRLS + (void)SecPathBuilderDecrementAsyncJobCount(rvc->builder); +#endif +} + static bool SecRVCFetchNext(SecRVCRef rvc) { bool OCSP_fetch_finished = true; TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder); /* Don't send OCSP request only if CRLs enabled and policy requested CRL only */ if (SecRVCShouldCheckOCSP(rvc)) { - OCSP_fetch_finished &= SecORVCFetchNext(rvc->orvc); + SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); + SecCertificateRef cert = SecCertificatePathVCGetCertificateAtIndex(path, rvc->certIX); + OCSP_fetch_finished = SecORVCBeginFetches(rvc->orvc, cert); + if (analytics && !OCSP_fetch_finished) { + /* We did a network OCSP fetch, set report appropriately */ + analytics->ocsp_network = true; + } } if (OCSP_fetch_finished) { /* we didn't start an OCSP background job for this cert */ (void)SecPathBuilderDecrementAsyncJobCount(rvc->builder); - } else if (analytics) { - /* We did a network OCSP fetch, set report appropriately */ - analytics->ocsp_network = true; - analytics->ocsp_fetches++; } #if ENABLE_CRLS @@ -1135,15 +993,19 @@ static bool SecRevocationDidCheckRevocation(SecPathBuilderRef builder, bool *fir secdebug("rvc", "Not rechecking revocation"); } - CFIndex certIX, certCount = SecPathBuilderGetCertificateCount(builder); - for (certIX = 0; certIX < certCount; ++certIX) { - SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, certIX); - if (rvc && !recheck) { - SecRVCUpdatePVC(rvc); - } else if (rvc) { - SecRVCDelete(rvc); // reset the RVC for the second pass + if (recheck) { + // reset the RVCs for the second pass + SecCertificatePathVCDeleteRVCs(path); + } else { + CFIndex certIX, certCount = SecPathBuilderGetCertificateCount(builder); + for (certIX = 0; certIX < certCount; ++certIX) { + SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, certIX); + if (rvc) { + SecRVCUpdatePVC(rvc); + } } } + return !recheck; } @@ -1165,19 +1027,79 @@ static bool SecRevocationCanAccessNetwork(SecPathBuilderRef builder, bool first_ return SecPathBuilderCanAccessNetwork(builder); } +void SecPathBuilderCheckKnownIntermediateConstraints(SecPathBuilderRef builder) { + SecCertificatePathVCRef path = SecPathBuilderGetPath(builder); + if (!path) { + return; + } + /* only perform this check once per path! */ + CFIndex certIX = kCFNotFound; + if (SecCertificatePathVCCheckedIssuers(path)) { + certIX = SecCertificatePathVCUnknownCAIndex(path); + goto checkedIssuers; + } + /* check full path: start with anchor and decrement to leaf */ + bool parentConstrained = false; + CFIndex certCount = SecPathBuilderGetCertificateCount(builder); + for (certIX = certCount - 1; certIX >= 0; --certIX) { + SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, certIX); + if (!rvc) { + continue; + } + if (parentConstrained && !rvc->valid_info) { + /* Parent had the known-only constraint, but our issuer is unknown. + Bump index to point back at the issuer since it fails the constraint. */ + certIX++; + break; + } + parentConstrained = (rvc->valid_info && rvc->valid_info->knownOnly); + if (parentConstrained) { + secdebug("validupdate", "Valid db found a known-intermediate constraint on %@ (index=%ld)", + rvc->valid_info->issuerHash, certIX+1); + if (certIX == 0) { + /* check special case: unknown constrained CA in leaf position */ + SecCertificateRef cert = SecCertificatePathVCGetCertificateAtIndex(path, certIX); + if (cert && SecCertificateIsCA(cert) && !SecRevocationDbContainsIssuer(cert)) { + /* leaf is a CA which violates the constraint */ + break; + } + } + } + } + /* At this point, certIX will either be -1, indicating no CA was found + which failed a known-intermediates-only constraint on its parent, or it + will be the index of the first unknown CA which fails the constraint. */ + if (certIX >= 0) { + secnotice("validupdate", "CA at index %ld violates known-intermediate constraint", certIX); + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + if (analytics) { + analytics->valid_unknown_intermediate = true; + } + /* [40648172] For now, log this error but do not fail the evaluation. */ + certIX = -1; + } + SecCertificatePathVCSetUnknownCAIndex(path, certIX); + SecCertificatePathVCSetCheckedIssuers(path, true); + +checkedIssuers: + if (certIX >= 0) { + /* Error is set on CA certificate which failed the constraint. */ + SecRVCSetValidDeterminedErrorResult(SecCertificatePathVCGetRVCAtIndex(path, certIX)); + } +} + bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { secdebug("rvc", "checking revocation"); CFIndex certIX, certCount = SecPathBuilderGetCertificateCount(builder); SecCertificatePathVCRef path = SecPathBuilderGetPath(builder); - bool completed = true; if (certCount <= 1) { /* Can't verify without an issuer; we're done */ - return completed; + return true; } bool first_check_done = false; if (SecRevocationDidCheckRevocation(builder, &first_check_done)) { - return completed; + return true; } /* Setup things so we check revocation status of all certs. */ @@ -1186,16 +1108,17 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { /* Note that if we are multi threaded and a job completes after it is started but before we return from this function, we don't want a callback to decrement asyncJobCount to zero before we finish issuing - all the jobs. To avoid this we pretend we issued certCount-1 async jobs, + all the jobs. To avoid this we pretend we issued certCount async jobs, and decrement pvc->asyncJobCount for each cert that we don't start a - background fetch for. (We will never start an async job for the final - cert in the chain.) */ + background fetch for. We include the root, even though we'll never start + an async job for it so that we count all active threads for this eval. */ #if !ENABLE_CRLS - SecPathBuilderSetAsyncJobCount(builder, (unsigned int)(certCount-1)); + SecPathBuilderSetAsyncJobCount(builder, (unsigned int)(certCount)); #else /* If we enable CRLS, we may end up with two async jobs per cert: one - * for OCSP and one for fetching the CRL */ - SecPathBuilderSetAsyncJobCount(builder, 2 * (unsigned int)(certCount-1)); + * for OCSP and one for fetching the CRL. Except the root, which only + * needs to track this thread. */ + SecPathBuilderSetAsyncJobCount(builder, 2 * (unsigned int)(certCount) - 1); #endif /* Loop though certificates again and issue an ocsp fetch if the @@ -1219,7 +1142,7 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { /* This certificate has OCSP No-Check, so add to reporting analytics */ analytics->ocsp_no_check = true; } - rvc->done = true; + SecRVCSetFinishedWithoutNetwork(rvc); } if (rvc->done) { @@ -1234,7 +1157,7 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { #endif /* Any other revocation method requires an issuer certificate to verify the response; * skip the last cert in the chain since it doesn't have one. */ - if (certIX+1 >= certCount) { + if (certIX + 1 >= certCount) { continue; } @@ -1248,21 +1171,22 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { #if TARGET_OS_BRIDGE /* The bridge has no writeable storage and no network. Nothing else we can * do here. */ - rvc->done = true; - return completed; + SecRVCSetFinishedWithoutNetwork(rvc); + continue; #endif /* Then check the caches for revocation results. */ SecRVCCheckRevocationCaches(rvc); /* The check is done if we found cached responses from either method. */ - if (rvc->orvc->done + if (rvc->done || rvc->orvc->done #if ENABLE_CRLS || rvc->crvc->done #endif ) { secdebug("rvc", "found cached response for cert: %ld", certIX); - rvc->done = true; + SecRVCSetFinishedWithoutNetwork(rvc); + continue; } /* If we got a cached response that is no longer valid (which can only be true for @@ -1276,7 +1200,6 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { bool allow_fetch = SecRevocationCanAccessNetwork(builder, first_check_done) && (SecCertificatePathVCIsEV(path) || SecCertificatePathVCIsOptionallyEV(path) || SecPathBuilderGetRevocationMethod(builder) || old_cached_response); - bool fetch_done = true; if (rvc->done || !allow_fetch) { /* We got a cache hit or we aren't allowed to access the network */ SecRVCUpdatePVC(rvc); @@ -1286,22 +1209,15 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { (void)SecPathBuilderDecrementAsyncJobCount(builder); #endif } else { - fetch_done = SecRVCFetchNext(rvc); - } - if (!fetch_done) { - /* We started at least one background fetch. */ - secdebug("rvc", "waiting on background fetch for cert %ld", certIX); - completed = false; + (void)SecRVCFetchNext(rvc); } } - /* Return false if we started any background jobs. */ - /* We can't just return !builder->asyncJobCount here, since if we started any - jobs the completion callback will be called eventually and it will call - SecPathBuilderStep(). If for some reason everything completed before we - get here we still want the outer SecPathBuilderStep() to terminate so we - keep track of whether we started any jobs and return false if so. */ - return completed; + /* Return false if there are still async jobs running. */ + /* builder->asyncJobCount is atomic, so we know that if the job count is 0, all other + * threads are finished. If the job count is > 0, other threads will decrement the job + * count and SecPathBuilderStep to crank the state machine when the job count is 0. */ + return (SecPathBuilderDecrementAsyncJobCount(builder) == 0); } CFAbsoluteTime SecRVCGetEarliestNextUpdate(SecRVCRef rvc) { diff --git a/OSX/sec/securityd/SecRevocationServer.h b/OSX/sec/securityd/SecRevocationServer.h index 255f1f78..7f42f736 100644 --- a/OSX/sec/securityd/SecRevocationServer.h +++ b/OSX/sec/securityd/SecRevocationServer.h @@ -32,6 +32,8 @@ #include #include +#include +#include typedef struct OpaqueSecORVC *SecORVCRef; #if ENABLE_CRLS @@ -60,12 +62,47 @@ struct OpaqueSecRVC { }; typedef struct OpaqueSecRVC *SecRVCRef; +/* OCSP Revocation verification context. */ +struct OpaqueSecORVC { + /* Pointer to the builder for this revocation check. */ + SecPathBuilderRef builder; + + /* Pointer to the generic rvc for this revocation check */ + SecRVCRef rvc; + + /* The ocsp request we send to each responder. */ + SecOCSPRequestRef ocspRequest; + + /* The freshest response we received so far, from stapling or cache or responder. */ + SecOCSPResponseRef ocspResponse; + + /* The best validated candidate single response we received so far, from stapling or cache or responder. */ + SecOCSPSingleResponseRef ocspSingleResponse; + + /* Index of cert in builder that this RVC is for 0 = leaf, etc. */ + CFIndex certIX; + + /* Date until which this revocation status is valid. */ + CFAbsoluteTime nextUpdate; + + /* URL of current responder. For logging purposes. */ + CFURLRef responder; + + bool done; +}; + bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder); +void SecPathBuilderCheckKnownIntermediateConstraints(SecPathBuilderRef builder); CFAbsoluteTime SecRVCGetEarliestNextUpdate(SecRVCRef rvc); void SecRVCDelete(SecRVCRef rvc); bool SecRVCHasDefinitiveValidInfo(SecRVCRef rvc); bool SecRVCHasRevokedValidInfo(SecRVCRef rvc); -void SecRVCSetRevokedResult(SecRVCRef rvc); +void SecRVCSetValidDeterminedErrorResult(SecRVCRef rvc); + +/* OCSP verification callbacks */ +void SecORVCConsumeOCSPResponse(SecORVCRef rvc, SecOCSPResponseRef ocspResponse /*CF_CONSUMED*/, + CFTimeInterval maxAge, bool updateCache, bool fromCache); +void SecORVCUpdatePVC(SecORVCRef rvc); #endif /* _SECURITY_SECREVOCATIONSERVER_H_ */ diff --git a/OSX/sec/securityd/SecTrustServer.c b/OSX/sec/securityd/SecTrustServer.c index 3f376e16..af70276a 100644 --- a/OSX/sec/securityd/SecTrustServer.c +++ b/OSX/sec/securityd/SecTrustServer.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,7 @@ #include "personalization.h" #include #include +#include #if TARGET_OS_OSX #include @@ -131,7 +133,7 @@ struct SecPathBuilder { CFIndex pvcCount; SecCertificatePathVCRef path; - unsigned int asyncJobCount; + _Atomic unsigned int asyncJobCount; bool online_revocation; bool trusted_revocation; CFStringRef revocation_check_method; @@ -167,7 +169,7 @@ static void SecPathBuilderInit(SecPathBuilderRef builder, CFArrayRef signedCertificateTimestamps, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, CFArrayRef accessGroups, CFArrayRef exceptions, SecPathBuilderCompleted completed, const void *context) { - secdebug("alloc", "%p", builder); + secdebug("alloc", "builder %p", builder); CFAllocatorRef allocator = kCFAllocatorDefault; builder->analyticsData = calloc(1, sizeof(TrustAnalyticsBuilder)); @@ -175,13 +177,34 @@ static void SecPathBuilderInit(SecPathBuilderRef builder, builder->clientAuditToken = (CFDataRef) ((clientAuditToken) ? CFRetain(clientAuditToken) : NULL); - builder->queue = dispatch_queue_create("builder", DISPATCH_QUEUE_SERIAL); + + /* Put all trust evaluations on the same workloop in order to avoid + * high thread fanout and frequent expensive context switches */ + static dispatch_workloop_t workloop = NULL; + static dispatch_once_t onceToken; + static const char *recursion_key = "trust-evaluation-recursion-token"; + dispatch_once(&onceToken, ^{ + workloop = dispatch_workloop_create("com.apple.trustd.evaluation"); + }); + dispatch_queue_t builderQueue = NULL; + if (dispatch_workloop_is_current(workloop) || dispatch_get_specific(recursion_key)) { + /* If we're on the workloop already or are in a recursive trust evaluation, make a + * new thread so that the new path builder block will get scheduled and the blocked + * trust evaluation can proceed. */ + builderQueue = dispatch_queue_create("com.apple.trustd.evaluation.recursive", DISPATCH_QUEUE_SERIAL); + dispatch_queue_set_specific(builderQueue, recursion_key, (void *)1, NULL); + } else { + builderQueue = workloop; + dispatch_retain_safe(builderQueue); + } + builder->queue = builderQueue; builder->nextParentSource = 1; #if !TARGET_OS_WATCH /* */ builder->canAccessNetwork = true; #endif + atomic_init(&builder->asyncJobCount, 0); builder->anchorSources = CFArrayCreateMutable(allocator, 0, NULL); builder->parentSources = CFArrayCreateMutable(allocator, 0, NULL); @@ -337,7 +360,7 @@ static void SecPathBuilderForEachPVC(SecPathBuilderRef builder,void (^operation) } static void SecPathBuilderDestroy(SecPathBuilderRef builder) { - secdebug("alloc", "%p", builder); + secdebug("alloc", "destroy builder %p", builder); dispatch_release_null(builder->queue); if (builder->anchorSource) { SecMemoryCertificateSourceDestroy(builder->anchorSource); @@ -500,12 +523,22 @@ bool SecPathBuilderIsAnchored(SecPathBuilderRef builder) { } unsigned int SecPathBuilderDecrementAsyncJobCount(SecPathBuilderRef builder) { - return --builder->asyncJobCount; + unsigned int result = atomic_fetch_sub(&builder->asyncJobCount, 1); + secdebug("rvc", "%p: decrement asyncJobCount from %d", builder, result); + /* atomic_fetch_sub returns the original value, but we want this function to return the + * value after the operation. */ + return --result; } void SecPathBuilderSetAsyncJobCount(SecPathBuilderRef builder, unsigned int jobCount) { - builder->asyncJobCount = jobCount; - secdebug("rvc", "set asyncJobCount to %d", builder->asyncJobCount); + atomic_store(&builder->asyncJobCount, jobCount); + secdebug("rvc", "%p: set asyncJobCount to %d", builder, jobCount); +} + +unsigned int SecPathBuilderGetAsyncJobCount(SecPathBuilderRef builder) { + unsigned int count = atomic_load(&builder->asyncJobCount); + secdebug("rvc", "%p: current asyncJobCount is %d", builder, count); + return count; } CFMutableDictionaryRef SecPathBuilderGetInfo(SecPathBuilderRef builder) { @@ -1256,6 +1289,7 @@ static bool SecPathBuilderReportResult(SecPathBuilderRef builder) { the completion callback will be invoked and the builder will be deallocated. */ bool SecPathBuilderStep(SecPathBuilderRef builder) { + secdebug("async", "step builder %p", builder); if (builder->activations) { secdebug("async", "activations: %lu returning true", builder->activations); @@ -1292,16 +1326,30 @@ bool SecPathBuilderStep(SecPathBuilderRef builder) { builder->bestPath, pvc->details, result); if (builder->completed) { + /* We want to retain just the data we need to return to our caller + * and free the rest of the builder before doing the callback. + * Since the callback may end an XPC transaction that made us active, we + * want to retain as little residual memory as possible. */ CFArrayRef resultPath = SecCertificatePathVCCopyCertificates(builder->bestPath); - builder->completed(builder->context, resultPath, - pvc->details, builder->info, result); + CFDictionaryRef info = CFRetainSafe(builder->info); + CFArrayRef details = CFRetainSafe(pvc->details); + const void *context = builder->context; + SecPathBuilderCompleted completed = builder->completed; + + secdebug("async", "free builder"); + SecPathBuilderDestroy(builder); + free(builder); + + secdebug("async", "returning to caller"); + completed(context, resultPath, details, info, result); CFReleaseNull(resultPath); + CFReleaseNull(info); + CFReleaseNull(details); + } else { + SecPathBuilderDestroy(builder); + free(builder); } - /* Finally, destroy the builder and free it. */ - SecPathBuilderDestroy(builder); - free(builder); - return false; } diff --git a/OSX/sec/securityd/SecTrustServer.h b/OSX/sec/securityd/SecTrustServer.h index e032db1d..4e95664b 100644 --- a/OSX/sec/securityd/SecTrustServer.h +++ b/OSX/sec/securityd/SecTrustServer.h @@ -111,9 +111,10 @@ SecPVCRef SecPathBuilderGetResultPVC(SecPathBuilderRef builder); void SecPathBuilderSetResultInPVCs(SecPathBuilderRef builder, CFStringRef key, CFIndex ix, CFTypeRef result, bool force); -/* This is a pre-decrement operation */ +/* This is an atomic pre-decrement operation */ unsigned int SecPathBuilderDecrementAsyncJobCount(SecPathBuilderRef builder); void SecPathBuilderSetAsyncJobCount(SecPathBuilderRef builder, unsigned int jobCount); +unsigned int SecPathBuilderGetAsyncJobCount(SecPathBuilderRef builder); CFMutableDictionaryRef SecPathBuilderGetInfo(SecPathBuilderRef builder); @@ -155,6 +156,20 @@ typedef CF_OPTIONS(uint8_t, TA_SCTSource) { TA_SCT_TLS = 1 << 2, }; +typedef CF_ENUM(uint8_t, TA_CTFailureReason) { + TA_CTNoFailure = 0, + TA_CTNoSCTs = 1, + TA_CTMissingLogs = 2, + TA_CTNoCurrentSCTsUnknownLog = 3, + TA_CTNoCurrentSCTsDisqualifiedLog = 4, + TA_CTPresentedNotEnoughUnknown = 5, + TA_CTPresentedNotEnoughDisqualified = 6, + TA_CTPresentedNotEnough = 7, + TA_CTEmbeddedNotEnoughUnknown = 8, + TA_CTEmbeddedNotEnoughDisqualified = 9, + TA_CTEmbeddedNotEnough = 10, +}; + typedef CF_OPTIONS(uint8_t, TAValidStatus) { TAValidDefinitelyOK = 1 << 0, TAValidProbablyOK = 1 << 1, @@ -170,7 +185,8 @@ typedef struct { TA_SCTSource sct_sources; uint32_t number_scts; uint32_t number_trusted_scts; - size_t total_sct_size; + TA_CTFailureReason ct_failure_reason; + bool ct_one_current; // CAIssuer bool ca_issuer_cache_hit; bool ca_issuer_network; @@ -199,6 +215,8 @@ typedef struct { TAValidStatus valid_status; bool valid_trigger_ocsp; bool valid_require_ct; + bool valid_known_intermediates_only; + bool valid_unknown_intermediate; } TrustAnalyticsBuilder; TrustAnalyticsBuilder *SecPathBuilderGetAnalyticsData(SecPathBuilderRef builder); diff --git a/OSX/sec/securityd/SecTrustStoreServer.c b/OSX/sec/securityd/SecTrustStoreServer.c index c7f0a5ba..b288c7af 100644 --- a/OSX/sec/securityd/SecTrustStoreServer.c +++ b/OSX/sec/securityd/SecTrustStoreServer.c @@ -62,8 +62,7 @@ static SecTrustStoreRef kSecTrustStoreUser = NULL; static const char copyParentsSQL[] = "SELECT data FROM tsettings WHERE subj=?"; static const char containsSQL[] = "SELECT tset FROM tsettings WHERE sha1=?"; -static const char insertSQL[] = "INSERT INTO tsettings(sha1,subj,tset,data)VALUES(?,?,?,?)"; -static const char updateSQL[] = "UPDATE tsettings SET tset=? WHERE sha1=?"; +static const char insertSQL[] = "INSERT OR REPLACE INTO tsettings(sha1,subj,tset,data)VALUES(?,?,?,?)"; static const char deleteSQL[] = "DELETE FROM tsettings WHERE sha1=?"; static const char deleteAllSQL[] = "BEGIN EXCLUSIVE TRANSACTION; DELETE from tsettings; COMMIT TRANSACTION; VACUUM;"; static const char copyAllSQL[] = "SELECT data,tset FROM tsettings ORDER BY sha1"; @@ -145,7 +144,7 @@ static int64_t SecTrustStoreCountAll(SecTrustStoreRef ts) { require_quiet(ts, errOutNotLocked); dispatch_sync(ts->queue, ^{ sqlite3_stmt *countAllStmt = NULL; - int s3e = sqlite3_prepare(ts->s3h, countAllSQL, sizeof(countAllSQL), + int s3e = sqlite3_prepare_v2(ts->s3h, countAllSQL, sizeof(countAllSQL), &countAllStmt, NULL); if (s3e == SQLITE_OK) { s3e = sqlite3_step(countAllStmt); @@ -172,8 +171,8 @@ static SecTrustStoreRef SecTrustStoreCreate(const char *db_name, ts->queue = dispatch_queue_create("truststore", DISPATCH_QUEUE_SERIAL); require_noerr(s3e = sec_sqlite3_open(db_name, &ts->s3h, create), errOut); - s3e = sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL), - &ts->copyParents, NULL); + s3e = sqlite3_prepare_v3(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL), + SQLITE_PREPARE_PERSISTENT, &ts->copyParents, NULL); if (create && s3e == SQLITE_ERROR) { /* sqlite3_prepare returns SQLITE_ERROR if the table we are compiling this statement for doesn't exist. */ @@ -193,12 +192,12 @@ static SecTrustStoreRef SecTrustStoreCreate(const char *db_name, sqlite3_free(errmsg); } require_noerr(s3e, errOut); - s3e = sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL), - &ts->copyParents, NULL); + s3e = sqlite3_prepare_v3(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL), + SQLITE_PREPARE_PERSISTENT, &ts->copyParents, NULL); } require_noerr(s3e, errOut); - require_noerr(s3e = sqlite3_prepare(ts->s3h, containsSQL, sizeof(containsSQL), - &ts->contains, NULL), errOut); + require_noerr(s3e = sqlite3_prepare_v3(ts->s3h, containsSQL, sizeof(containsSQL), SQLITE_PREPARE_PERSISTENT, + &ts->contains, NULL), errOut); if (SecTrustStoreCountAll(ts) == 0) { ts->containsSettings = false; @@ -274,7 +273,7 @@ bool _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts, require_action_quiet(!ts->readOnly, errOutNotLocked, ok = SecError(errSecReadOnly, error, CFSTR("truststore is readOnly"))); dispatch_sync(ts->queue, ^{ CFTypeRef trustSettingsDictOrArray = tsdoa; - sqlite3_stmt *insert = NULL, *update = NULL; + sqlite3_stmt *insert = NULL; CFDataRef xmlData = NULL; CFArrayRef array = NULL; @@ -306,7 +305,7 @@ bool _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts, require_action_quiet(s3e == SQLITE_OK, errOut, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); /* Parameter order is sha1,subj,tset,data. */ - require_noerr_action_quiet(s3e = sqlite3_prepare(ts->s3h, insertSQL, sizeof(insertSQL), + require_noerr_action_quiet(s3e = sqlite3_prepare_v2(ts->s3h, insertSQL, sizeof(insertSQL), &insert, NULL), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(insert, 1, CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC), @@ -325,20 +324,6 @@ bool _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts, /* Great the insert worked. */ ok = true; ts->containsSettings = true; - } else if (s3e == SQLITE_ERROR) { - /* Try update. */ - require_noerr_action_quiet(s3e = sqlite3_prepare(ts->s3h, updateSQL, sizeof(updateSQL), - &update, NULL), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); - require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(update, 1, - CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData), - SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); - require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(update, 2, - CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC), - errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); - s3e = sqlite3_step(update); - require_action_quiet(s3e == SQLITE_DONE, errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); - s3e = SQLITE_OK; - ok = true; } else { require_noerr_action_quiet(s3e, errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); ok = true; @@ -348,9 +333,6 @@ bool _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts, if (insert) { s3e = sqlite3_finalize(insert); } - if (update) { - s3e = sqlite3_finalize(update); - } if (ok && s3e == SQLITE_OK) { s3e = sqlite3_exec(ts->s3h, "COMMIT TRANSACTION", NULL, NULL, NULL); @@ -385,7 +367,7 @@ bool SecTrustStoreRemoveCertificateWithDigest(SecTrustStoreRef ts, int s3e = SQLITE_OK; sqlite3_stmt *deleteStmt = NULL; - require_noerr(s3e = sqlite3_prepare(ts->s3h, deleteSQL, sizeof(deleteSQL), + require_noerr(s3e = sqlite3_prepare_v2(ts->s3h, deleteSQL, sizeof(deleteSQL), &deleteStmt, NULL), errOut); require_noerr(s3e = sqlite3_bind_blob_wrapper(deleteStmt, 1, CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC), @@ -423,11 +405,11 @@ bool _SecTrustStoreRemoveAll(SecTrustStoreRef ts, CFErrorRef *error) /* prepared statements become unusable after deleteAllSQL, reset them */ if (ts->copyParents) sqlite3_finalize(ts->copyParents); - sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL), + sqlite3_prepare_v3(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL), SQLITE_PREPARE_PERSISTENT, &ts->copyParents, NULL); if (ts->contains) sqlite3_finalize(ts->contains); - sqlite3_prepare(ts->s3h, containsSQL, sizeof(containsSQL), + sqlite3_prepare_v3(ts->s3h, containsSQL, sizeof(containsSQL), SQLITE_PREPARE_PERSISTENT, &ts->contains, NULL); }); errOutNotLocked: @@ -552,7 +534,7 @@ bool _SecTrustStoreCopyAll(SecTrustStoreRef ts, CFArrayRef *trustStoreContents, CFPropertyListRef trustSettings = NULL; CFArrayRef certSettingsPair = NULL; int s3e = SQLITE_OK; - require_noerr(s3e = sqlite3_prepare(ts->s3h, copyAllSQL, sizeof(copyAllSQL), + require_noerr(s3e = sqlite3_prepare_v2(ts->s3h, copyAllSQL, sizeof(copyAllSQL), ©AllStmt, NULL), errOut); require(CertsAndSettings = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks), errOut); for(;;) { diff --git a/OSX/sec/securityd/TrustURLSessionDelegate.h b/OSX/sec/securityd/TrustURLSessionDelegate.h new file mode 100644 index 00000000..ff9d4a02 --- /dev/null +++ b/OSX/sec/securityd/TrustURLSessionDelegate.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018 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@ + * + */ + +#ifndef _SECURITY_TRUSTURLSESSIONDELEGATE_H_ +#define _SECURITY_TRUSTURLSESSIONDELEGATE_H_ + +#if __OBJC__ +#include + +NS_ASSUME_NONNULL_BEGIN +/* This is our abstract NSURLSessionDelegate that handles the elements common to + * fetching data over the network during a trust evaluation */ +@interface TrustURLSessionDelegate : NSObject +@property (assign, nullable) void *context; +@property NSArray *URIs; +@property NSUInteger URIix; +@property (nullable) NSMutableData *response; +@property NSTimeInterval expiration; +@property NSUInteger numTasks; + +- (BOOL)fetchNext:(NSURLSession *)session; +- (NSURLRequest *)createNextRequest:(NSURL *)uri; +@end + +NSTimeInterval TrustURLSessionGetResourceTimeout(void); + +NS_ASSUME_NONNULL_END +#endif // __OBJC__ + +#endif /* _SECURITY_TRUSTURLSESSIONDELEGATE_H_ */ diff --git a/OSX/sec/securityd/TrustURLSessionDelegate.m b/OSX/sec/securityd/TrustURLSessionDelegate.m new file mode 100644 index 00000000..6698130a --- /dev/null +++ b/OSX/sec/securityd/TrustURLSessionDelegate.m @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2018 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@ + * + */ + +#import +#import +#include +#include +#include +#include "TrustURLSessionDelegate.h" + +#define MAX_TASKS 3 + +/* There has got to be an easier way to do this. For now we based this code + on CFNetwork/Connection/URLResponse.cpp. */ +static CFStringRef copyParseMaxAge(CFStringRef cacheControlHeader) { + if (!cacheControlHeader) { return NULL; } + + /* The format of the cache control header is a comma-separated list, but + each list element could be a key-value pair, with the value quoted and + possibly containing a comma. */ + CFStringInlineBuffer inlineBuf = {}; + CFRange componentRange; + CFIndex length = CFStringGetLength(cacheControlHeader); + bool done = false; + CFCharacterSetRef whitespaceSet = CFCharacterSetGetPredefined(kCFCharacterSetWhitespace); + CFStringRef maxAgeValue = NULL; + + CFStringInitInlineBuffer(cacheControlHeader, &inlineBuf, CFRangeMake(0, length)); + componentRange.location = 0; + + while (!done) { + bool inQuotes = false; + bool foundComponentStart = false; + CFIndex charIndex = componentRange.location; + CFIndex componentEnd = -1; + CFRange maxAgeRg; + componentRange.length = 0; + + while (charIndex < length) { + UniChar ch = CFStringGetCharacterFromInlineBuffer(&inlineBuf, charIndex); + if (!inQuotes && ch == ',') { + componentRange.length = charIndex - componentRange.location; + break; + } + if (!CFCharacterSetIsCharacterMember(whitespaceSet, ch)) { + if (!foundComponentStart) { + foundComponentStart = true; + componentRange.location = charIndex; + } else { + componentEnd = charIndex; + } + if (ch == '\"') { + inQuotes = (inQuotes == false); + } + } + charIndex ++; + } + + if (componentEnd == -1) { + componentRange.length = charIndex - componentRange.location; + } else { + componentRange.length = componentEnd - componentRange.location + 1; + } + + if (charIndex == length) { + /* Fell off the end; this is the last component. */ + done = true; + } + + /* componentRange should now contain the range of the current + component; trimmed of any whitespace. */ + + /* We want to look for a max-age value. */ + if (!maxAgeValue && CFStringFindWithOptions(cacheControlHeader, CFSTR("max-age"), componentRange, kCFCompareCaseInsensitive | kCFCompareAnchored, &maxAgeRg)) { + CFIndex equalIdx; + CFIndex maxCompRg = componentRange.location + componentRange.length; + for (equalIdx = maxAgeRg.location + maxAgeRg.length; equalIdx < maxCompRg; equalIdx ++) { + UniChar equalCh = CFStringGetCharacterFromInlineBuffer(&inlineBuf, equalIdx); + if (equalCh == '=') { + // Parse out max-age value + equalIdx ++; + while (equalIdx < maxCompRg && CFCharacterSetIsCharacterMember(whitespaceSet, CFStringGetCharacterAtIndex(cacheControlHeader, equalIdx))) { + equalIdx ++; + } + if (equalIdx < maxCompRg) { + CFReleaseNull(maxAgeValue); + maxAgeValue = CFStringCreateWithSubstring(kCFAllocatorDefault, cacheControlHeader, CFRangeMake(equalIdx, maxCompRg-equalIdx)); + } + } else if (!CFCharacterSetIsCharacterMember(whitespaceSet, equalCh)) { + // Not a valid max-age header; break out doing nothing + break; + } + } + } + + if (!done && maxAgeValue) { + done = true; + } + if (!done) { + /* Advance to the next component; + 1 to get past the comma. */ + componentRange.location = charIndex + 1; + } + } + + return maxAgeValue; +} + +@implementation TrustURLSessionDelegate +- (id)init { + /* Protect future developers from themselves */ + if ([self class] == [TrustURLSessionDelegate class]) { + NSException *e = [NSException exceptionWithName:@"AbstractClassException" + reason:@"This is an abstract class. To use it, please subclass." + userInfo:nil]; + @throw e; + } else { + return [super init]; + } +} + +- (NSURLRequest *)createNextRequest:(NSURL *)uri { + return [NSURLRequest requestWithURL:uri]; +} + +- (BOOL)fetchNext:(NSURLSession *)session { + if (self.numTasks >= MAX_TASKS) { + secnotice("http", "Too many fetch %@ requests for this cert", [self class]); + return true; + } + + for (NSUInteger ix = self.URIix; ix < [self.URIs count]; ix++) { + NSURL *uri = self.URIs[ix]; + if ([[uri scheme] isEqualToString:@"http"]) { + self.URIix = ix + 1; // Next time we'll start with the next index + self.numTasks++; + NSURLSessionTask *task = [session dataTaskWithRequest:[self createNextRequest:uri]]; + [task resume]; + secinfo("http", "request for uri: %@", uri); + return false; // we scheduled a job + } else { + secnotice("http", "skipping unsupported scheme %@", [uri scheme]); + } + } + + /* No more issuers left to try, we're done. Report that no async jobs were started. */ + secdebug("http", "no request issued"); + return true; +} + +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { + /* Append the data to the response data*/ + if (!_response) { + _response = [NSMutableData data]; + } + [_response appendData:data]; +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { + /* Protect future developers from themselves */ + if ([self class] == [TrustURLSessionDelegate class]) { + NSException *e = [NSException exceptionWithName:@"AbstractClassException" + reason:@"This is an abstract class. To use it, please subclass and override didCompleteWithError." + userInfo:nil]; + @throw e; + } else { + _expiration = 60.0 * 60.0 * 24.0 * 7; /* Default is 7 days */ + if ([_response length] > 0 && [[task response] isKindOfClass:[NSHTTPURLResponse class]]) { + NSString *cacheControl = [[(NSHTTPURLResponse *)[task response] allHeaderFields] objectForKey:@"cache-control"]; + NSString *maxAge = CFBridgingRelease(copyParseMaxAge((__bridge CFStringRef)cacheControl)); + if (maxAge && [maxAge doubleValue] > _expiration) { + _expiration = [maxAge doubleValue]; + } + } + } +} + +- (void)URLSession:(NSURLSession *)session + task:(NSURLSessionTask *)task +willPerformHTTPRedirection:(NSHTTPURLResponse *)redirectResponse + newRequest:(NSURLRequest *)request + completionHandler:(void (^)(NSURLRequest *))completionHandler { + /* The old code didn't allow re-direction, so we won't either. */ + secnotice("http", "failed redirection for %@", task.originalRequest.URL); + [task cancel]; +} +@end + +NSTimeInterval TrustURLSessionGetResourceTimeout(void) { + return (NSTimeInterval)3.0; +} diff --git a/OSX/sec/securityd/asynchttp.c b/OSX/sec/securityd/asynchttp.c deleted file mode 100644 index d13e023a..00000000 --- a/OSX/sec/securityd/asynchttp.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Copyright (c) 2009-2010,2012-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * asynchttp.c - asynchronous http get/post engine. - */ - -#include "asynchttp.h" - -#include -#include -#include /* CFNetworkCopySystemProxySettings */ -#include /* kCFStreamPropertySourceApplication */ -#include -#include "SecBase64.h" -#include -#include -#include -#include -#include -#include - -#include - -#if __LP64__ -#define PRIstatus "d" -#else -#define PRIstatus "ld" -#endif - -static CFStringRef kUserAgent = CFSTR("User-Agent"); -static CFStringRef kAppUserAgent = CFSTR("com.apple.trustd/1.0"); - -/* POST method has Content-Type header line equal to - "application/ocsp-request" */ -static CFStringRef kContentType = CFSTR("Content-Type"); -static CFStringRef kAppOcspRequest = CFSTR("application/ocsp-request"); - -/* SPI to specify timeout on CFReadStream */ -#define _kCFStreamPropertyReadTimeout CFSTR("_kCFStreamPropertyReadTimeout") -#define _kCFStreamPropertyWriteTimeout CFSTR("_kCFStreamPropertyWriteTimeout") - -/* The timeout we set - 7 seconds */ -#define STREAM_TIMEOUT (7 * NSEC_PER_SEC) - -#define POST_BUFSIZE 2048 - -/* There has got to be an easier way to do this. For now we based this code - on CFNetwork/Connection/URLResponse.cpp. */ -static CFStringRef copyParseMaxAge(CFStringRef cacheControlHeader) { - /* The format of the cache control header is a comma-separated list, but - each list element could be a key-value pair, with the value quoted and - possibly containing a comma. */ - CFStringInlineBuffer inlineBuf = {}; - CFRange componentRange; - CFIndex length = CFStringGetLength(cacheControlHeader); - bool done = false; - CFCharacterSetRef whitespaceSet = CFCharacterSetGetPredefined(kCFCharacterSetWhitespace); - CFStringRef maxAgeValue = NULL; - - CFStringInitInlineBuffer(cacheControlHeader, &inlineBuf, CFRangeMake(0, length)); - componentRange.location = 0; - - while (!done) { - bool inQuotes = false; - bool foundComponentStart = false; - CFIndex charIndex = componentRange.location; - CFIndex componentEnd = -1; - CFRange maxAgeRg; - componentRange.length = 0; - - while (charIndex < length) { - UniChar ch = CFStringGetCharacterFromInlineBuffer(&inlineBuf, charIndex); - if (!inQuotes && ch == ',') { - componentRange.length = charIndex - componentRange.location; - break; - } - if (!CFCharacterSetIsCharacterMember(whitespaceSet, ch)) { - if (!foundComponentStart) { - foundComponentStart = true; - componentRange.location = charIndex; - } else { - componentEnd = charIndex; - } - if (ch == '\"') { - inQuotes = (inQuotes == false); - } - } - charIndex ++; - } - - if (componentEnd == -1) { - componentRange.length = charIndex - componentRange.location; - } else { - componentRange.length = componentEnd - componentRange.location + 1; - } - - if (charIndex == length) { - /* Fell off the end; this is the last component. */ - done = true; - } - - /* componentRange should now contain the range of the current - component; trimmed of any whitespace. */ - - /* We want to look for a max-age value. */ - if (!maxAgeValue && CFStringFindWithOptions(cacheControlHeader, CFSTR("max-age"), componentRange, kCFCompareCaseInsensitive | kCFCompareAnchored, &maxAgeRg)) { - CFIndex equalIdx; - CFIndex maxCompRg = componentRange.location + componentRange.length; - for (equalIdx = maxAgeRg.location + maxAgeRg.length; equalIdx < maxCompRg; equalIdx ++) { - UniChar equalCh = CFStringGetCharacterFromInlineBuffer(&inlineBuf, equalIdx); - if (equalCh == '=') { - // Parse out max-age value - equalIdx ++; - while (equalIdx < maxCompRg && CFCharacterSetIsCharacterMember(whitespaceSet, CFStringGetCharacterAtIndex(cacheControlHeader, equalIdx))) { - equalIdx ++; - } - if (equalIdx < maxCompRg) { - CFReleaseNull(maxAgeValue); - maxAgeValue = CFStringCreateWithSubstring(kCFAllocatorDefault, cacheControlHeader, CFRangeMake(equalIdx, maxCompRg-equalIdx)); - } - } else if (!CFCharacterSetIsCharacterMember(whitespaceSet, equalCh)) { - // Not a valid max-age header; break out doing nothing - break; - } - } - } - - if (!done && maxAgeValue) { - done = true; - } - if (!done) { - /* Advance to the next component; + 1 to get past the comma. */ - componentRange.location = charIndex + 1; - } - } - - return maxAgeValue; -} - -static void asynchttp_complete(asynchttp_t *http) { - secdebug("http", "http: %p", http); - /* Shutdown streams and timer, we're about to invoke our client callback. */ - if (http->stream) { - CFReadStreamSetClient(http->stream, kCFStreamEventNone, NULL, NULL); - CFReadStreamSetDispatchQueue(http->stream, NULL); - CFReadStreamClose(http->stream); - CFReleaseNull(http->stream); - } - if (http->timer) { - dispatch_source_cancel(http->timer); - dispatch_release_null(http->timer); - } - - if (http->completed) { - /* This should probably move to our clients. */ - CFTimeInterval maxAge = NULL_TIME; - if (http->response) { - CFStringRef cacheControl = CFHTTPMessageCopyHeaderFieldValue( - http->response, CFSTR("cache-control")); - if (cacheControl) { - CFStringRef maxAgeValue = copyParseMaxAge(cacheControl); - CFRelease(cacheControl); - if (maxAgeValue) { - secdebug("http", "http header max-age: %@", maxAgeValue); - maxAge = CFStringGetDoubleValue(maxAgeValue); - CFRelease(maxAgeValue); - } - } - } - http->completed(http, maxAge); - } -} - -static void handle_server_response(CFReadStreamRef stream, - CFStreamEventType type, void *info) { - asynchttp_t *http = (asynchttp_t *)info; - if (!http->stream) { - secerror("Avoiding crash due to CFReadStream invoking us after we called CFReadStreamSetDispatchQueue(stream, NULL) on a different block on our serial queue"); - return; - } - - switch (type) { - case kCFStreamEventHasBytesAvailable: - { - UInt8 buffer[POST_BUFSIZE]; - CFIndex length; - do { -#if 1 - length = CFReadStreamRead(stream, buffer, sizeof(buffer)); -#else - const UInt8 *buffer = CFReadStreamGetBuffer(stream, -1, &length); -#endif - secdebug("http", - "stream: %@ kCFStreamEventHasBytesAvailable read: %lu bytes", - stream, length); - if (length < 0) { - /* Negative length == error */ - asynchttp_complete(http); - break; - } else if (length > 0) { - //CFHTTPMessageAppendBytes(http->response, buffer, length); - CFDataAppendBytes(http->data, buffer, length); - } else { - /* Read 0 bytes. This is a no-op, but we need to keep - reading until CFReadStreamHasBytesAvailable is false. - */ - } - } while (CFReadStreamHasBytesAvailable(stream)); - break; - } - case kCFStreamEventErrorOccurred: - { - CFStreamError error = CFReadStreamGetError(stream); - - secdebug("http", - "stream: %@ kCFStreamEventErrorOccurred domain: %ld error: %ld", - stream, error.domain, (long) error.error); - - if (error.domain == kCFStreamErrorDomainPOSIX) { - secerror("CFReadStream posix: %s", strerror(error.error)); - } else if (error.domain == kCFStreamErrorDomainMacOSStatus) { - secerror("CFReadStream osstatus: %"PRIstatus, error.error); - } else { - secerror("CFReadStream domain: %ld error: %"PRIstatus, - error.domain, error.error); - } - asynchttp_complete(http); - break; - } - case kCFStreamEventEndEncountered: - { - http->response = (CFHTTPMessageRef)CFReadStreamCopyProperty( - stream, kCFStreamPropertyHTTPResponseHeader); - secdebug("http", "stream: %@ kCFStreamEventEndEncountered hdr: %@", - stream, http->response); - CFHTTPMessageSetBody(http->response, http->data); - asynchttp_complete(http); - break; - } - default: - secerror("handle_server_response unexpected event type: %lu", - type); - break; - } -} - -/* Create a URI suitable for use in an http GET request, will return NULL if - the length would exceed 255 bytes. */ -static CFURLRef createGetURL(CFURLRef responder, CFDataRef request) { - CFURLRef getURL = NULL; - CFMutableDataRef base64Request = NULL; - CFStringRef base64RequestString = NULL; - CFStringRef peRequest = NULL; - CFIndex base64Len; - - base64Len = SecBase64Encode(NULL, CFDataGetLength(request), NULL, 0); - /* Don't bother doing all the work below if we know the end result will - exceed 255 bytes (minus one for the '/' separator makes 254). */ - if (base64Len + CFURLGetBytes(responder, NULL, 0) > 254) - return NULL; - - require(base64Request = CFDataCreateMutable(kCFAllocatorDefault, - base64Len), errOut); - CFDataSetLength(base64Request, base64Len); - SecBase64Encode(CFDataGetBytePtr(request), CFDataGetLength(request), - (char *)CFDataGetMutableBytePtr(base64Request), base64Len); - require(base64RequestString = CFStringCreateWithBytes(kCFAllocatorDefault, - CFDataGetBytePtr(base64Request), base64Len, kCFStringEncodingUTF8, - false), errOut); - /* percent-encode all reserved characters from RFC 3986 [2.2] */ - require(peRequest = CFURLCreateStringByAddingPercentEscapes( - kCFAllocatorDefault, base64RequestString, NULL, - CFSTR(":/?#[]@!$&'()*+,;="), kCFStringEncodingUTF8), errOut); -#if 1 - CFStringRef urlString = CFURLGetString(responder); - CFStringRef fullURL; - if (CFStringHasSuffix(urlString, CFSTR("/"))) { - fullURL = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%@%@"), urlString, peRequest); - } else { - fullURL = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%@/%@"), urlString, peRequest); - } - getURL = CFURLCreateWithString(kCFAllocatorDefault, fullURL, NULL); - CFRelease(fullURL); -#else - getURL = CFURLCreateWithString(kCFAllocatorDefault, peRequest, responder); -#endif - -errOut: - CFReleaseSafe(base64Request); - CFReleaseSafe(base64RequestString); - CFReleaseSafe(peRequest); - - return getURL; -} - -bool asyncHttpPost(CFURLRef responder, CFDataRef requestData /* , bool force_nocache */ , - uint64_t timeout, asynchttp_t *http) { - bool result = true; /* True, we didn't schedule any work. */ - /* resources to release on exit */ - CFURLRef getURL = NULL; - -/* Interesting tidbit from rfc5019 - When sending requests that are less than or equal to 255 bytes in - total (after encoding) including the scheme and delimiters (http://), - server name and base64-encoded OCSPRequest structure, clients MUST - use the GET method (to enable OCSP response caching). OCSP requests - larger than 255 bytes SHOULD be submitted using the POST method. - - Interesting tidbit from rfc2616: - Note: Servers ought to be cautious about depending on URI lengths - above 255 bytes, because some older client or proxy - implementations might not properly support these lengths. - - Given the second note I'm assuming that the note in rfc5019 is about the - length of the URI, not the length of the entire HTTP request. - - If we need to consider the entire request we need to have 17 bytes less, or - 17 + 25 = 42 if we are appending a "Cache-Control: no-cache CRLF" header - field. - - The 17 and 42 above are based on the request encoding from rfc2616 - Method SP Request-URI SP HTTP-Version CRLF (header CRLF)* CRLF - so in our case it's: - GET SP URI SP HTTP/1.1 CRLF CRLF - 17 + len(URI) bytes - or - GET SP URI SP HTTP/1.1 CRLF Cache-Control: SP no-cache CRLF CRLF - 42 + len(URI) bytes - */ - - /* First let's try creating a GET request. */ - getURL = createGetURL(responder, requestData); - if (getURL && CFURLGetBytes(getURL, NULL, 0) < 256) { - /* Get URI is less than 256 bytes encoded, making it safe even for - older proxy or caching servers, so let's use HTTP GET. */ - secdebug("http", "GET[%ld] %@", CFURLGetBytes(getURL, NULL, 0), getURL); - require_quiet(http->request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, - CFSTR("GET"), getURL, kCFHTTPVersion1_1), errOut); - } else { - /* GET Request too big to ensure error free transmission, let's - create a HTTP POST http->request instead. */ - secdebug("http", "POST %@ CRLF body", responder); - require_quiet(http->request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, - CFSTR("POST"), responder, kCFHTTPVersion1_1), errOut); - /* Set the body and required header fields. */ - CFHTTPMessageSetBody(http->request, requestData); - CFHTTPMessageSetHeaderFieldValue(http->request, kContentType, - kAppOcspRequest); - } - -#if 0 - if (force_nocache) { - CFHTTPMessageSetHeaderFieldValue(http->request, CFSTR("Cache-Control"), - CFSTR("no-cache")); - } -#endif - - result = asynchttp_request(NULL, timeout, http); - -errOut: - CFReleaseSafe(getURL); - - return result; -} - - -static void asynchttp_timer_proc(asynchttp_t *http CF_CONSUMED) { - CFStringRef req_meth = http->request ? CFHTTPMessageCopyRequestMethod(http->request) : NULL; - CFURLRef req_url = http->request ? CFHTTPMessageCopyRequestURL(http->request) : NULL; - secnotice("http", "Timeout during %@ %@.", req_meth, req_url); - CFReleaseSafe(req_url); - CFReleaseSafe(req_meth); - asynchttp_complete(http); -} - - -void asynchttp_free(asynchttp_t *http) { - if (http) { - CFReleaseNull(http->token); - CFReleaseNull(http->request); - CFReleaseNull(http->response); - CFReleaseNull(http->data); - CFReleaseNull(http->stream); - dispatch_release_null(http->timer); - } -} - -/* Return true, iff we didn't schedule any work, return false if we did. */ -bool asynchttp_request(CFHTTPMessageRef request, uint64_t timeout, asynchttp_t *http) { - secdebug("http", "request %@", request); - if (request) { - CFRetainAssign(http->request, request); - /* Set user agent. */ - CFHTTPMessageSetHeaderFieldValue(request, kUserAgent, kAppUserAgent); - } - - /* Create the stream for the request. */ - require_quiet(http->stream = CFReadStreamCreateForHTTPRequest( - kCFAllocatorDefault, http->request), errOut); - - /* Set a reasonable timeout */ - require_quiet(http->timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, http->queue), errOut); - dispatch_source_set_event_handler(http->timer, ^{ - asynchttp_timer_proc(http); - }); - // Set the timer's fire time to now + STREAM_TIMEOUT seconds with a .5 second fuzz factor. - uint64_t stream_timeout = timeout; - if (timeout == 0) { - stream_timeout = STREAM_TIMEOUT; - } - dispatch_source_set_timer(http->timer, dispatch_time(DISPATCH_TIME_NOW, stream_timeout), - DISPATCH_TIME_FOREVER, (int64_t)(500 * NSEC_PER_MSEC)); - dispatch_resume(http->timer); - - /* Set up possible proxy info */ - CFDictionaryRef proxyDict = CFNetworkCopySystemProxySettings(); - if (proxyDict) { - CFReadStreamSetProperty(http->stream, kCFStreamPropertyHTTPProxy, proxyDict); - CFRelease(proxyDict); - } - - /* Set source application property info */ - if (http->token) { - CFReadStreamSetProperty(http->stream, kCFStreamPropertySourceApplication, http->token); - } - - http->data = CFDataCreateMutable(kCFAllocatorDefault, 0); - - CFStreamClientContext stream_context = { .info = http }; - CFReadStreamSetClient(http->stream, - (kCFStreamEventHasBytesAvailable - | kCFStreamEventErrorOccurred - | kCFStreamEventEndEncountered), - handle_server_response, &stream_context); - CFReadStreamSetDispatchQueue(http->stream, http->queue); - - http->start_time = mach_absolute_time(); - CFReadStreamOpen(http->stream); - - return false; /* false -> something was scheduled. */ - -errOut: - /* Deschedule timer and free anything we might have retained so far. */ - asynchttp_free(http); - return true; -} diff --git a/OSX/sec/securityd/asynchttp.h b/OSX/sec/securityd/asynchttp.h deleted file mode 100644 index 5a417954..00000000 --- a/OSX/sec/securityd/asynchttp.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2009-2010,2012-2015 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@ - */ - -/*! - @header asynchttp - The functions provided in asynchttp.h provide an interface to - an asynchronous http get/post engine. -*/ - -#ifndef _SECURITYD_ASYNCHTTP_H_ -#define _SECURITYD_ASYNCHTTP_H_ - -#include -#include -#include -#include -#include -#include -#include - -__BEGIN_DECLS - -typedef struct asynchttp_s { - void(*completed)(struct asynchttp_s *http, CFTimeInterval maxAge); - void *info; - CFHTTPMessageRef request; - CFHTTPMessageRef response; - dispatch_queue_t queue; - uint64_t start_time; - /* The fields below should be considered private. */ - CFMutableDataRef data; - CFReadStreamRef stream; - dispatch_source_t timer; - CFDataRef token; -} asynchttp_t; - -/* Return false if work was scheduled and the callback will be invoked, - true if it wasn't or the callback was already called. */ -bool asyncHttpPost(CFURLRef cfUrl, CFDataRef postData, uint64_t timeout, asynchttp_t *http); - -/* Caller owns struct pointed to by http, but is responsible for calling - asynchttp_free() when it's done with it. */ -bool asynchttp_request(CFHTTPMessageRef request, uint64_t timeout, asynchttp_t *http); -void asynchttp_free(asynchttp_t *http); - -/* */ - - -__END_DECLS - -#endif /* !_SECURITYD_ASYNCHTTP_H_ */ diff --git a/OSX/sec/securityd/com.apple.secd.sb b/OSX/sec/securityd/com.apple.secd.sb index 15990dd1..f6a02c3a 100644 --- a/OSX/sec/securityd/com.apple.secd.sb +++ b/OSX/sec/securityd/com.apple.secd.sb @@ -30,10 +30,12 @@ (global-name "com.apple.system.opendirectoryd.api") (global-name "com.apple.SystemConfiguration.configd") (global-name "com.apple.security.cloudkeychainproxy3") - (global-name "com.apple.security.keychainsyncingoveridsproxy") + (global-name "com.apple.accountsd.accountmanager") + (global-name "com.apple.ak.auth.xpc") (global-name "com.apple.cdp.daemon") (global-name "com.apple.cloudd") (global-name "com.apple.apsd") + (global-name "com.apple.ak.anisette.xpc") (global-name "com.apple.windowserver.active")) ;; Used to send logs for MoiC. diff --git a/OSX/sec/securityd/entitlements.plist b/OSX/sec/securityd/entitlements.plist index fe8c7f7e..2b813b22 100644 --- a/OSX/sec/securityd/entitlements.plist +++ b/OSX/sec/securityd/entitlements.plist @@ -62,5 +62,11 @@ securityd + com.apple.private.sqlite.sqlite-encryption + + com.apple.accounts.appleaccount.fullaccess + + com.apple.authkit.client.private + diff --git a/OSX/sec/securityd/nameconstraints.c b/OSX/sec/securityd/nameconstraints.c index e841a7ae..40052ed2 100644 --- a/OSX/sec/securityd/nameconstraints.c +++ b/OSX/sec/securityd/nameconstraints.c @@ -31,6 +31,7 @@ #include #include #include +#include /* RFC 5280 Section 4.2.1.10: DNS name restrictions are expressed as host.example.com. Any DNS @@ -448,6 +449,33 @@ static void nc_compare_RFC822Name_to_subtrees(const void *value, void *context) } } +static bool certAllowsSSL(SecCertificateRef certificate) { + CFArrayRef ekus = SecCertificateCopyExtendedKeyUsage(certificate); + if (!ekus) { + return true; // No EKU -> any purpose + } + + const DERItem *serverEkus[] = { + &oidAnyExtendedKeyUsage, &oidExtendedKeyUsageServerAuth, + &oidExtendedKeyUsageMicrosoftSGC, &oidExtendedKeyUsageNetscapeSGC, + }; + + bool result = false; + for (uint8_t ix = 0; ix < sizeof(serverEkus)/sizeof(const DERItem *); ix++) { + CFDataRef ekuOid = CFDataCreate(NULL, serverEkus[ix]->data, serverEkus[ix]->length); + if (CFArrayContainsValue(ekus, CFRangeMake(0, CFArrayGetCount(ekus)), ekuOid)) { + result = true; + } + CFReleaseNull(ekuOid); + if (result) { + break; + } + } + + CFReleaseNull(ekus); + return result; +} + static void nc_compare_subject_to_subtrees(SecCertificateRef certificate, CFArrayRef subtrees, bool permit, match_t *match) { CFDataRef subject = SecCertificateCopySubjectSequence(certificate); @@ -467,16 +495,22 @@ static void nc_compare_subject_to_subtrees(SecCertificateRef certificate, CFArra CFReleaseNull(subject); update_match(permit, &x500_match, match); - /* Compare DNSName constraints */ - match_t dns_match = { false, permit }; - CFArrayRef dnsNames = SecCertificateCopyDNSNamesFromSubject(certificate); - if (dnsNames) { - CFRange dnsRange = { 0, CFArrayGetCount(dnsNames) }; - nc_san_match_context_t dnsContext = { subtrees, &dns_match, permit }; - CFArrayApplyFunction(dnsNames, dnsRange, nc_compare_DNSName_to_subtrees, &dnsContext); + /* These checks are unnecessary if Common Names aren't used to match SSLHostnames. () + * In the meantime, this hack makes non-SSL certs with DNS-like CNs work. () */ + /* Compare DNSName constraints -- if there's no DNS names in the SAN and this cert can be used for SSL Server Auth*/ + CFArrayRef sanDnsNames = SecCertificateCopyDNSNamesFromSAN(certificate); + if (certAllowsSSL(certificate) && (!sanDnsNames || CFArrayGetCount(sanDnsNames) == 0)) { + match_t dns_match = { false, permit }; + CFArrayRef dnsNames = SecCertificateCopyDNSNamesFromSubject(certificate); + if (dnsNames) { + CFRange dnsRange = { 0, CFArrayGetCount(dnsNames) }; + nc_san_match_context_t dnsContext = { subtrees, &dns_match, permit }; + CFArrayApplyFunction(dnsNames, dnsRange, nc_compare_DNSName_to_subtrees, &dnsContext); + } + CFReleaseNull(dnsNames); + update_match(permit, &dns_match, match); } - CFReleaseNull(dnsNames); - update_match(permit, &dns_match, match); + CFReleaseNull(sanDnsNames); /* Compare IPAddresss constraints */ match_t ip_match = { false, permit }; diff --git a/OSX/sec/securityd/policytree.c b/OSX/sec/securityd/policytree.c index 15efe996..2dacf7ef 100644 --- a/OSX/sec/securityd/policytree.c +++ b/OSX/sec/securityd/policytree.c @@ -123,7 +123,10 @@ policy_tree_t policy_tree_create(const oid_t *p_oid, policy_qualifier_t p_q) { /* Walk the nodes in a tree at depth and invoke callback for each one. */ bool policy_tree_walk_depth(policy_tree_t root, int depth, bool(*callback)(policy_tree_t, void *), void *ctx) { - policy_tree_t stack[depth + 1]; + policy_tree_t *stack = (policy_tree_t *)malloc(sizeof(policy_tree_t) * (depth + 1)); + if (!stack) { + return false; + } int stack_ix = 0; stack[stack_ix] = root; policy_tree_t node; @@ -159,6 +162,7 @@ bool policy_tree_walk_depth(policy_tree_t root, int depth, } } } + free(stack); return match; } diff --git a/OSX/sec/securityd/spi.c b/OSX/sec/securityd/spi.c index 9fb3b586..cf2f3d48 100644 --- a/OSX/sec/securityd/spi.c +++ b/OSX/sec/securityd/spi.c @@ -68,11 +68,13 @@ static struct securityd securityd_spi = { .soscc_TryUserCredentials = SOSCCTryUserCredentials_Server, .soscc_SetUserCredentials = SOSCCSetUserCredentials_Server, .soscc_SetUserCredentialsAndDSID = SOSCCSetUserCredentialsAndDSID_Server, + .soscc_SetUserCredentialsAndDSIDWithAnalytics = SOSCCSetUserCredentialsAndDSIDWithAnalytics_Server, .soscc_CanAuthenticate = SOSCCCanAuthenticate_Server, .soscc_PurgeUserCredentials = SOSCCPurgeUserCredentials_Server, .soscc_ThisDeviceIsInCircle = SOSCCThisDeviceIsInCircle_Server, .soscc_RequestToJoinCircle = SOSCCRequestToJoinCircle_Server, .soscc_RequestToJoinCircleAfterRestore = SOSCCRequestToJoinCircleAfterRestore_Server, + .soscc_RequestToJoinCircleAfterRestoreWithAnalytics = SOSCCRequestToJoinCircleAfterRestoreWithAnalytics_Server, .soscc_RequestEnsureFreshParameters = SOSCCRequestEnsureFreshParameters_Server, .soscc_GetAllTheRings = SOSCCGetAllTheRings_Server, .soscc_ApplyToARing = SOSCCApplyToARing_Server, @@ -82,11 +84,14 @@ static struct securityd securityd_spi = { .soscc_SetToNew = SOSCCAccountSetToNew_Server, .soscc_ResetToOffering = SOSCCResetToOffering_Server, .soscc_ResetToEmpty = SOSCCResetToEmpty_Server, + .soscc_ResetToEmptyWithAnalytics = SOSCCResetToEmptyWithAnalytics_Server, .soscc_View = SOSCCView_Server, .soscc_ViewSet = SOSCCViewSet_Server, - .soscc_SecurityProperty = SOSCCSecurityProperty_Server, + .soscc_ViewSetWithAnalytics = SOSCCViewSetWithAnalytics_Server, .soscc_RemoveThisDeviceFromCircle = SOSCCRemoveThisDeviceFromCircle_Server, + .soscc_RemoveThisDeviceFromCircleWithAnalytics = SOSCCRemoveThisDeviceFromCircleWithAnalytics_Server, .soscc_RemovePeersFromCircle = SOSCCRemovePeersFromCircle_Server, + .soscc_RemovePeersFromCircleWithAnalytics = SOSCCRemovePeersFromCircleWithAnalytics_Server, .soscc_LoggedOutOfAccount = SOSCCLoggedOutOfAccount_Server, .soscc_BailFromCircle = SOSCCBailFromCircle_Server, .soscc_AcceptApplicants = SOSCCAcceptApplicants_Server, @@ -105,13 +110,7 @@ static struct securityd securityd_spi = { .soscc_ProcessSyncWithAllPeers = SOSCCProcessSyncWithAllPeers_Server, .soscc_EnsurePeerRegistration = SOSCCProcessEnsurePeerRegistration_Server, .sec_roll_keys = _SecServerRollKeysGlue, - .soscc_CopyDeviceID = SOSCCCopyDeviceID_Server, - .soscc_SetDeviceID = SOSCCSetDeviceID_Server, - .soscc_CheckIDSRegistration = SOSCCIDSServiceRegistrationTest_Server, - .soscc_PingTest = SOSCCIDSPingTest_Server, - .soscc_GetIDSIDFromIDS = SOSCCIDSDeviceIDIsAvailableTest_Server, .sec_keychain_sync_update_message = _SecServerKeychainSyncUpdateMessage, - .soscc_HandleIDSMessage = SOSCCHandleIDSMessage_Server, .sec_get_log_settings = SecCopyLogSettings_Server, .sec_set_xpc_log_settings = SecSetXPCLogSettings_Server, .sec_set_circle_log_settings = SecSetCircleLogSettings_Server, @@ -120,10 +119,10 @@ static struct securityd securityd_spi = { .soscc_SetNewPublicBackupKey = SOSCCSetNewPublicBackupKey_Server, .soscc_RegisterSingleRecoverySecret = SOSCCRegisterSingleRecoverySecret_Server, .soscc_WaitForInitialSync = SOSCCWaitForInitialSync_Server, + .soscc_WaitForInitialSyncWithAnalytics = SOSCCWaitForInitialSyncWithAnalytics_Server, .soscc_CopyYetToSyncViewsList = SOSCCCopyYetToSyncViewsList_Server, .soscc_SetEscrowRecords = SOSCCSetEscrowRecord_Server, .soscc_CopyEscrowRecords = SOSCCCopyEscrowRecord_Server, - .soscc_PeerAvailability = SOSCCCheckPeerAvailability_Server, .sosbskb_WrapToBackupSliceKeyBagForView = SOSWrapToBackupSliceKeyBagForView_Server, .soscc_CopyAccountState = SOSCCCopyAccountState_Server, .soscc_DeleteAccountState = SOSCCDeleteAccountState_Server, @@ -134,10 +133,7 @@ static struct securityd securityd_spi = { .sec_item_update_token_items = _SecItemUpdateTokenItems, .sec_delete_items_with_access_groups = _SecItemServerDeleteAllWithAccessGroups, .soscc_IsThisDeviceLastBackup = SOSCCkSecXPCOpIsThisDeviceLastBackup_Server, - .soscc_requestSyncWithPeerOverKVS = SOSCCRequestSyncWithPeerOverKVS_Server, - .soscc_requestSyncWithPeerOverKVSIDOnly = SOSCCRequestSyncWithPeerOverKVSUsingIDOnly_Server, .soscc_SOSCCPeersHaveViewsEnabled = SOSCCPeersHaveViewsEnabled_Server, - .socc_clearPeerMessageKeyInKVS = SOSCCClearPeerMessageKeyInKVS_Server, .soscc_RegisterRecoveryPublicKey = SOSCCRegisterRecoveryPublicKey_Server, .soscc_CopyRecoveryPublicKey = SOSCCCopyRecoveryPublicKey_Server, .soscc_CopyBackupInformation = SOSCCCopyBackupInformation_Server, diff --git a/OSX/shared_regressions/shared_regressions.h b/OSX/shared_regressions/shared_regressions.h index 9a5f7497..52740b97 100644 --- a/OSX/shared_regressions/shared_regressions.h +++ b/OSX/shared_regressions/shared_regressions.h @@ -31,6 +31,8 @@ ONE_TEST(si_27_sectrust_exceptions) ONE_TEST(si_28_sectrustsettings) ONE_TEST(si_29_sectrust_sha1_deprecation) ONE_TEST(si_32_sectrust_pinning_required) +ONE_TEST(si_34_cms_timestamp) +ONE_TEST(si_35_cms_expiration_time) ONE_TEST(si_44_seckey_gen) ONE_TEST(si_44_seckey_rsa) ONE_TEST(si_44_seckey_ec) @@ -39,6 +41,7 @@ ONE_TEST(si_44_seckey_aks) #if TARGET_OS_IOS && !TARGET_OS_SIMULATOR ONE_TEST(si_44_seckey_fv) #endif +ONE_TEST(si_44_seckey_proxy) ONE_TEST(si_60_cms) ONE_TEST(si_61_pkcs12) ONE_TEST(si_62_csr) @@ -62,6 +65,7 @@ ONE_TEST(si_83_seccertificate_sighashalg) ONE_TEST(si_85_sectrust_ssl_policy) ONE_TEST(si_87_sectrust_name_constraints) ONE_TEST(si_88_sectrust_valid) +ONE_TEST(si_89_cms_hash_agility) ONE_TEST(si_97_sectrust_path_scoring) ONE_TEST(rk_01_recoverykey) diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/DODInteroperabilityRootCA2.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/DODInteroperabilityRootCA2.cer deleted file mode 100644 index c04f86f2f1c4659b2ca85a8bef47290cdcffdb89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1778 zcmXqLVtZ%M#CmN3GZP~d6O-y1170>xtu~Lg@4SqR+^h@+;fCA>oNUaYENsF|p}~d{ z24Wx%moR^*Ua+2mdwyAJQC@CpUWp;E0XIm7TbRWyz}wSM-ar<_Wfm55OHD~FO3YDk zD#}brPgQVsR4_6yG&YbE=QT7lurM?=G&M0dF^d9nEn!?E<0yk1VlCz|;DT7p?2_+d zh~R--p>CiGafKXEPQf#;B(*5N0O*>e%$&@UN`;{O{1S+Rni!Rkea^_rz}&>h&tTBR z$i>ve$jI>h*oEfF&$yd4Uualw^LntRXWo|3!}lfX9&Iiz+LEy_?Z%AcSNr^-cX>rum-0byY+E@Jk zRWER~cU+7eAI68c+KFfoXAoU*o|aCamFjx=TQ{XX_3rgtFR<}abZNOj$z!ok zD(MwG+rF9cJH7wE_`vRCaa);~85tNCH!-g@XkuPzzz+;mSz$)T|17Kq%s|SZu>&Nc zz|z=YP-noy#+A_K!I%n6Qq0UKJRTIDDhiJmg(rx@6GGt$qwqvfckkCSrP(?_n7)YQP z1rItN78DtzK;>aYkx@nH=ix+=5kit-Ly-|il3_=Y5kZpSK#@Uq0hdAJd{BVMu{2IM zXq>X3aiW3c5_1Dnvhu8fOcJSe1; zS%5`ngUIf4C56oVq{=optnG0fmWLazH|ytm_Wya z3t3q{7BLo)|3B6VcTdu;oaDH;EJmks-mIf@Dv*mbU||j{(ij<97x}DyF#C#nrr(1v ztoeGO6Qa)b=k_r>&sT0Xo_H@Mck^HC@RmrH%lyp`!!DT=UpzK{x!ci#$xOFTPd&h! zV{vX@qp*kf`u^oHvS(}UpK#u8zF!(Uv1`-&7^~;3{b$t|fBgGlt4)GNnbr5*$F?pr zQ@>Ibmow?kPla>0ThcRs9B7K1(Hk4kST}*KG;!XWC+!h7&)@dkxaF$S@YGIM%j%W9 z=Hoqgr)=7DBSQR<{mdOl(oJ2ys(ii>p0Rb}`c2=xWJGJEU9@ku__S_szqwD~n3~M4 zmmk*V`u1H~sr%=R&Hi=gWW|qNxshOOUzS*!_HAFqHup8>yqsM`!uB^#5@_-~cnbiQ C0uiVH diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/ECARootCA4.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/ECARootCA4.cer deleted file mode 100644 index f950eba68d959260e2c92ed25e1d17fae3b3e142..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1407 zcmXqLVy!l4Vo6@W%*4n91QQH+**LY@JlekVGBR?rG8p6-avN~6F^96S2{VNT8%h|6 zfjC^k{GocmdJ69OWvNAZxv6<2hCBvbAQ^69W|w>yBwm2Gr=hxmDoBo5SPm$s;F(vF zT9jXqT9lZSnUh&ksSuQ(U!vgbs9w>O>r}U9I+di9Vs=YB}D3&@~K6UL=9q*4Knr1HyWA1&8=`V|3&3Ntn z^Rw!!zicTEa57PC508=ynQ1+n@zv40Qx|V2+V-Ykq1LL_UmsUmOc7;gVrFDuT-?Ou zV$j6oU?2|+Ls?}OU=nB$`Tt{`aQ7tb%1Mrk%VKmI=gm4gr@}xMq=1h_j77vadTD-D zXo7a5x0=YA%Kcuux{dZ4@PVZH85#exumDpVn}IusFVEs&U}s>nz-oa-n^{IlNr9EV zesWQcUP@+hqF!!h4v3@g;_u?=7vdV^AK)6~=;Z0+84?-f?;qmqXru>}HmG6a&}L&~ zWo2h%WGOJnGw_1(4Vc>Ou$h@zTwI!(Qj(9y;CRmvy#n)O0|mHQjBO%Nv+|RR3*Zhk z$Od^sfhENt$$*EAE1}JUF%{@N9u^cHD+-Sdg~yJ<<3QnYqVTv3gg}-FgTj!*fDK47 zF)|u>g2d!NV)h2M3#<(+mzW!vl9f>m_(4XgfQ(`_U~XV!Km;WtHw!SD46NY6!P=&W zJ7|+C^?^AJ5=SQSo=)JPL@il>IgOE__NRhyirdAKn#W9=Wq+Dgs=sM>)BZ4{_Pv=8 zhp+Mj;~tM^A7hhFUgAwl+0n9}&1i%Dmf5#YaO~-7oh|mx;$eFq^RxFk^>rHT?3w;7 ztsB3nO-ePm>FD{$uS-tx!SxxB=gmkki&)qF@7-^vXDwdqqm7x0@5-grz5A@n;?aF& zPmJ-h@UN`uKgBfbmgUWVP+gmx?69w8`J-zJTxY~?MowA3d0PpCY-tt8V%_3^xb;)s z^L@DbX>rm%1}U?@mjf5`vg`|Yd|h$wf&0sVkkjjIw<$2nsGCfEZM>S%v2@GaeU1%1 lJKA=y)Z1ope>>-%H4LJc1j^OQFB}Yf&i5)wqFdtpDFEjCx~>2K diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/FederalBridgeCA2013.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/FederalBridgeCA2013.cer deleted file mode 100644 index b6bdc37bf383b8676fd1d925f619d445bb85662f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1641 zcmXqLVoNn>V)b3X%*4pV#H6#pfR~L^tIebBJ1-+6H!Fidq#?HfCmVAp3!5-gXt1G# zff$IxCCneH7p$k?o?n()l$V>DS7OL(zzve&7G`k^@b)xRG>`{znS~|XQd3fk5_1%s z^K*0a^ArN|b25`F6`UOnmE(n z{Y%h4*+NFHhJ$C`H!aa*r6dud=ku?;3edY!XP2V-L{CO~$J_YSEuR@g{drX;=@bSi z*}N9a+^l2q`9bl*8EU1=bi-D%uAhC(2VWcg-x|soDBZ zI?#_(Lx)}4tFp(@^++)H*{4^Q?VfCW!+hG|4cgI1k3RE^af~iq%ye6HUh#!xXP%sx zC3T#Uee#C;uXp^dzq49m%B1ezFFcx@0shg24{rs;E#80s&XTSV?A}bwj0}v6o0!cF znwX6Z_)oG9f3`w!cMLFOCMwX97j74Pkxst+W6Te6! zSJ8NfgoHcV8@4<_E?j_RD6nv0WH=y~tNx+VJ;<%)L`SUNoMmNy|NLydRB6Me`1{OX zb;~`Ar6#6?uZU|X+~AxxSL=tM`!1fki1_V+{mMJ<3cr{5)cGaQJhIX2NWoh7H{DXf zh0pap(~iAwk=FU_9BU(3?Whpl7gcnXvE`f5SH_Q4C+hmY{JLfu3}S=v|C3}x^He#^zMh@y65eWW`ihg$N?a7*M#*4Q%o?X5$Dep>poFM=TquK=k diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist b/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist index 75bffee2..9b6326ac 100644 --- a/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist +++ b/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist @@ -649,11 +649,6 @@ PolicyIdentifier 1.2.840.113635.100.1.33 - Properties - - SecPolicyName - test.nosuchdomain - Leaf generic_apple_server @@ -707,8 +702,6 @@ 1.2.840.113635.100.1.3 Properties - SecPolicyName - com.apple.ist.ds.appleconnect2.production.vpn.8F2B3ADCD72ED2EA08DDC26AD0255A983B1DEBEB SecPolicyClient @@ -1240,7 +1233,7 @@ Anchors AppleRootCA VerifyDate - 2015-04-20T19:00:00Z + 2018-04-20T19:00:00Z ExpectedResult 4 ChainLength @@ -2289,30 +2282,6 @@ VerifyDate 2016-12-10T04:38:00Z - - MajorTestName - DOD - MinorTestName - SHA2 - Policies - - PolicyIdentifier - 1.2.840.113635.100.1.2 - - Leaf - ECARootCA4 - Intermediates - - FederalBridgeCA2013 - DODInteroperabilityRootCA2 - - Anchors - FederalCommonPolicyCA - ExpectedResult - 4 - VerifyDate - 2016-12-10T04:38:00Z - MajorTestName DOD @@ -2877,5 +2846,93 @@ ExpectedResult 4 + + MajorTestName + BAA_SCRT + MinorTestName + Positive + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.84 + + Leaf + baa_scrt_leaf + Intermediates + baa_system_subca1 + Anchors + baa_system_root + VerifyDate + 2018-05-09T13:00:00Z + ExpectedResult + 4 + + + MajorTestName + AssetReceipt + MinorTestName + Positive-TemporallyValid + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.89 + + Leaf + asset_receipt + Intermediates + AppleSystemIntegration2CA + Anchors + AppleRootCA + VerifyDate + 2018-04-10T06:00:00Z + ExpectedResult + 4 + ChainLength + 3 + + + MajorTestName + AssetReceipt + MinorTestName + Positive-TemporallyInvalid + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.89 + + Leaf + asset_receipt + Intermediates + AppleSystemIntegration2CA + Anchors + AppleRootCA + VerifyDate + 2019-06-02T06:00:00Z + ExpectedResult + 4 + ChainLength + 3 + + + MajorTestName + AssetReceipt + MinorTestName + Negative + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.89 + + Leaf + ppq_signing + Intermediates + AppleSystemIntegration2CA + Anchors + AppleRootCA + VerifyDate + 2017-02-18T00:19:45Z + ExpectedResult + 5 + diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/asset_receipt.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/asset_receipt.cer new file mode 100644 index 0000000000000000000000000000000000000000..6315e5a000b88cbc3281186a99734cb21c389571 GIT binary patch literal 1235 zcmXqLVmWWn#Jqh0GZP~d6G!Tm)}1FZHEtU4vTW~PB?>{Q$*GwIB?`fr>3NxX>4t>uXkt`C4gf}02IeM4 zeg=akMlPl%Mn;B{$-B48EjZiww_?f^N&QLLqMS{NTwL=UPRwE37k{ZwyDceq*YWUm zmop~s-I=+fW66ibYyEGFNp4uWgnL!CxFpx~B)hU#RrO03?VqiDhBwPy${?Y5%@j7b zsSM9#8|weHt$6ZW*6ELuSw!v4@|ur3dnfPQ6#4Q|vGbM1uOG#&x~Z?_xGLJSp7YMi zb@EE*cf5OE+BW;vakF`4nygh~JZ{@yeQ_SL>@z2cCabQebr@bywF{ zvzKcnrcLRV;R-Ev?YkE7Zr5BTf#X})mW8ow`YBTRFs0g`VcOdJdJp_>_5Ra2_W9B) z#R?;tTDFA_QJ4Lh6lbLr+kfs2d&G_l$;2RJy~Fc$?~y?v52hkEH4n@ zK9-iaw_Y$a`{S+cvlT%n34XO<)Va{V>GRWo04#~(YR!D{?+f)T0 zw86Pf$9R~1&VF*(BMff%0UVpNU-Pu z1r7K>I`~08XJKYyZ!qA8`-RPxg$bB3QS&J>ra zmvdrHW?FtxUS^_!oH(zcg@LJorGbHwg{fH-gllMEU|`bJSQr=@ z=z?ey6Bi3(3qxZQLnAXoDFX?R8g3pzCr3vG=hUK-%(Tp8u+w1H65*Ce17S9Hu!or# zp+0A3WM_6_VEM~kS60HdsmIo2@~Q73JGrBins)9Gua{?JIjWkw%rwU^RVO>r{^I!DXBRS4i^t| zesVU1Er~FUorTAMYkyY-(8q>GdIrczkJ*F4z?DfsWlO~@cPZ87S(%b%bM&8I`lx<- z&D#EB9CM|3avh(%_F__GxL&|_-cxz8(PyRJ>k4P)-}J9B$~bZ6*XG@uypC|X1bP7g DX+p+K literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/baa_system_root.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/baa_system_root.cer new file mode 100644 index 0000000000000000000000000000000000000000..127b49c288db1575e3d976c13cdedfa7e5e98063 GIT binary patch literal 548 zcmXqLVp1?@VqCg_nTe5!iKF6&+ttm{5#k11Y#dr`9_MUXn3)Yi4K)qa*_cCFn0XYO z5{omF6&y=SQj1FxOEUBG6oM;@OHy+cg7WiA6r3Fmg$)EjO1XHr9199^QWZS&lJ#JM z96Vgki8+~R`9*n|i3W1wyoTlmCPoGZ21Z5(mQmuo#zqFlKqeSO(aPE~0|7R6u-}*% z*;ut3Ss0XN@LT zY%{f-TWR5q#ZCqe2K>OFkrifS{LjK_zzn1eWI+OaEMhDo|1MrU#KF#db*GKVrrm#Q ztY)f8_Z#qmr1?SWS%C4wh8!!*nG6PLOoj~0f_-oAIoT-O`sL1lp0YVE!k=E69!c9& zsjIm9&$h{lQdt(W{%t7+RJ>dn7ARTqe*1?+_`Hc1A6uE-1!dxW=668 literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/baa_system_subca1.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/baa_system_subca1.cer new file mode 100644 index 0000000000000000000000000000000000000000..c50a09cac8d9eed953286a53c20fb6a7e471a6a2 GIT binary patch literal 554 zcmXqLVp20`VqCL;nTe5!iNi%)oUKbJG{b<4jYF%=+oNoIbYLU3hqNouY_P=0=ig0rKcuz?^*DHjiyV?jYqs)A=;vK~y3 zgNMsGF()%EzbG#=(Lhd|*U;R+#K^$Fz{J?ZBubpu*vP=x2*d}1DB`RQE=>a23bTO- zYa;A0VE5fRMnDtqIT z`&!!C=lhL4t1r8E{X8kxB5=V6o3gl9xms^oXoWRqP)z+ ziJ$fAuN=B}%|PK;jmZh4$tmX+IjDRoc;_T}DDRHh=I46xr((4j4E6I@{hxh)tCe@^ zq=|EC&M#Mqmygc$vlQyn;&(l9u(18{_neTpU7la(hR?HS-g4(nSzP1y-n*NHdDcy@|MBGihXRppcWdP&zIztV zevy7+gWxi)M}Hp9E@l^enApm(O6U9RO&#o+Nw1Gq7nBzt3+QY4WD=uV^-E89_RNl) zUv_o!Nj?V4MK65_xGh)hVWGERRdYkhr#E(XQCqIOyrOev&FQ)O1?vu`$t|&M(kc|{ z%C`F($J}HawtJ(!{R6!{XPKB885kEgF;*KiF_s(10z*lbk420{g#AqYyrr`aJ>D&q zbKmsmKXG6FQklu#Ox5+Q3k-xos#IBc47k`hwAmP0S=pHx4H`FsL{1NlDCSVcF+6iF>={G+QhLa3blfJv=h z#iua$$U+sR4J;d8FupZkuEq}A>_fF6ZQMIrbsNAjlSB^A-nHt<@q@YTYtL3ZSDSK9 zciN99mA_-ruAL4 Qw7_H0dE$RXa+nyI0UQ%}o&W#< delta 705 zcmV;y0zUn}35Ez4FoFaEFoFW=paTK{0s;t9&~NIm-?ssg7lTAJFf}nXFfcMWG%;Ei z4KXz^HZe3XFfuqaFyhvkvIZgl+3zJKnT395#vBT{~@qd3ts{GX+)W9K3285YwnoTb2qyy?~w;THu ztGa+w4YkK7#-T1dTbiWh#EDOJ*mBTgM1<0=cJUn^xRnY(_*0ogWXp$p z@ba69Mispp7zzOmu86{dYDMAno``QR>@TAg4Uy(aYs#dRDVzt(d4Tgco7_i@-i6nE zE~oV#k>Iz!YAi-E0s{d60i%J*FoDJ}9R>qc9S#H*1Qc0qs$OV&Gy0vY&{M*u^)n~* zL`9QR0(%+bs6@*pE)J z?~|oUcuR&Jm*wOHG7^o;yShl>?sQ;=!rLandO{opsc-}$qlfl%%7zd!qCzfRVqM!D zY>3Og8e!ysV~dUB5ZX(3tyCs8S_j=c1r^K|((&fgi^d8}afn(h&)J5BosPQZn%S_; z1NU8`g_Yw+K!0;f_cGzdH(tXZ@B{#*9OKt@Wx=3nR?x1Y+S8>>Bo|}Q=yFl(15xcW z2Ovp7*Qlw283%$H_{w8KT&9;3Mr``k%X3E3H1)_FPg#@NJZQk=yS^`Sdw`bnG{hn( n`k5M)wu%T0>yo5&Yu5gSrKP-&ycUKajOEbqs-rYw6#{>*`p`3$ diff --git a/OSX/shared_regressions/si-44-seckey-aks.m b/OSX/shared_regressions/si-44-seckey-aks.m index 05961b21..6ba2ecf9 100644 --- a/OSX/shared_regressions/si-44-seckey-aks.m +++ b/OSX/shared_regressions/si-44-seckey-aks.m @@ -8,6 +8,8 @@ #import #if !TARGET_OS_OSX #import "MobileGestalt.h" +#else +#import #endif #import "shared_regressions.h" @@ -88,6 +90,9 @@ static void attestationTest(void) { id sik = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeSIK, (void *)&error)); ok(sik != nil, "get SIk key: %@", error); + id pubSIK = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sik)); + ok(pubSIK != nil, "get SIK pubkey"); + error = nil; NSData *attSIKPlain = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)uik, (void *)&error)); ok(attSIKPlain != nil, "SIK attesting UIK, no nonce: %@", error); @@ -101,29 +106,97 @@ static void attestationTest(void) { ok(SecKeySetParameter((__bridge SecKeyRef)sik, kSecKeyParameterSETokenAttestationNonce, (__bridge CFPropertyListRef)nonce, (void *)&error), "Set nonce to SIK: %@", error); NSData *attSIKNonce = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)uik, (void *)&error)); ok(attSIKNonce != nil, "SIK attesting UIK, with nonce: %@", error); -// NSRange found = [attSIKNonce rangeOfData:nonce options:0 range:NSMakeRange(0, attSIKNonce.length)]; -// ok(found.location != NSNotFound, "nonce found in SIK-attested data"); error = nil; ok(SecKeySetParameter((__bridge SecKeyRef)uik, kSecKeyParameterSETokenAttestationNonce, (__bridge CFPropertyListRef)nonce, (void *)&error), "Set nonce to UIK: %@", error); NSData *attUIKNonce = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)uik, (__bridge SecKeyRef)privKey, (void *)&error)); ok(attUIKNonce != nil, "SIK attesting UIK, with nonce: %@", error); -// found = [attUIKNonce rangeOfData:nonce options:0 range:NSMakeRange(0, attUIKNonce.length)]; -// ok(found.location != NSNotFound, "nonce found in UIK-attested data"); + + error = nil; + id sysUikC = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeUIKCommitted, (void *)&error)); + if (sysUikC == nil) { + // Platform does not support system UIK, so just fake test rounds to avoid testplan counting failures. + for (int i = 0; i < 19; i++) { + ok(true); + } + } else { + ok(sysUikC != nil, "get UIK-committed key, error: %@", error); + error = nil; + id sysUikP = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeUIKProposed, (void *)&error)); + ok(sysUikP != nil, "get UIK-proposed key: %@", error); + + error = nil; + NSData *attUIKC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error)); + ok(attUIKC != nil, "Sys-UIK-committed attesting privKey: %@", error); + + error = nil; + NSData *attUIKP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error)); + ok(attUIKP != nil, "Sys-UIK-proposed attesting privKey: %@", error); + + id pubUIKP = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikP)); + ok(pubUIKP != nil, "Sys-UIK-proposed copy public key"); + id pubUIKC = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikC)); + ok(pubUIKC != nil, "Sys-UIK-proposed copy public key"); + ok([pubUIKP isEqual:pubUIKC], "Sys-UIK proposed and committed are same before bump"); + + BOOL res = SecKeyControlLifetime((__bridge SecKeyRef)sysUikC, kSecKeyControlLifetimeTypeBump, (void *)&error); + ok(res, "bumping sys-uik: %@", error); + + error = nil; + NSData *attUIKCN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error)); + ok(attUIKCN != nil, "Sys-UIK-committed attesting privKey: %@", error); + + error = nil; + NSData *attUIKPN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error)); + ok(attUIKPN != nil, "Sys-UIK-proposed attesting privKey: %@", error); + + id pubUIKPN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikP)); + ok(pubUIKPN != nil, "Sys-UIK-proposed copy public key"); + ok(![pubUIKPN isEqual:pubUIKC], "Sys-UIK proposed and committed differ after bump"); + + res = SecKeyControlLifetime((__bridge SecKeyRef)sysUikP, kSecKeyControlLifetimeTypeCommit, (void *)&error); + ok(res, "committing sys-uik: %@", error); + + error = nil; + NSData *attUIKCNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error)); + ok(attUIKCNN != nil, "Sys-UIK-committed attesting privKey: %@", error); + + error = nil; + NSData *attUIKPNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error)); + ok(attUIKPNN != nil, "Sys-UIK-proposed attesting privKey: %@", error); + + id pubUIKCN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikC)); + ok(pubUIKCN != nil, "Sys-UIK-committed copy public key"); + ok([pubUIKPN isEqual:pubUIKC], "Sys-UIK proposed and committed same after commit"); + + // Attest system-UIK with SIK + NSData *attSIKUIKP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysUikP, (void *)&error)); + ok(attSIKUIKP != nil, "SIK attesting Sys-UIK-proposed, error: %@", error); + + NSData *attSIKUIKC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysUikC, (void *)&error)); + ok(attSIKUIKC != nil, "SIK attesting Sys-UIK-committed, error: %@", error); + } } int si_44_seckey_aks(int argc, char *const *argv) { @autoreleasepool { BOOL testPKA = YES; #if !TARGET_OS_OSX - id hasPKA = (__bridge_transfer id)MGCopyAnswer(kMGQHasPKA, NULL); - if(![hasPKA isKindOfClass:NSNumber.class] || ![(NSNumber *)hasPKA boolValue]) { + NSNumber *hasPKA = (__bridge_transfer id)MGCopyAnswer(kMGQHasPKA, NULL); + if(![hasPKA isKindOfClass:NSNumber.class] || ![hasPKA boolValue]) { testPKA = NO; } #else + if (remote_device_copy_unique_of_type(REMOTE_DEVICE_TYPE_EOS) == nil && remote_device_copy_unique_of_type(REMOTE_DEVICE_TYPE_BRIDGE_COPROC) == nil) { + // macOS without SEP cannot run attestations at all. + plan_tests(1); + ok(true); + return 0; + } + testPKA = NO; #endif - plan_tests(testPKA ? 46 : 31); + plan_tests(testPKA ? 66 : 51); secKeySepTest(testPKA); attestationTest(); return 0; diff --git a/OSX/shared_regressions/si-44-seckey-fv.m b/OSX/shared_regressions/si-44-seckey-fv.m index 6442b20f..6f7f5e04 100644 --- a/OSX/shared_regressions/si-44-seckey-fv.m +++ b/OSX/shared_regressions/si-44-seckey-fv.m @@ -13,7 +13,7 @@ static void testFileVaultKeyRawSign() { id key = CFBridgingRelease(SecKeyCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey)); id certificate = CFBridgingRelease(SecCertificateCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey)); - id pubKey = CFBridgingRelease(SecCertificateCopyPublicKey((SecCertificateRef)certificate)); + id pubKey = CFBridgingRelease(SecCertificateCopyKey((SecCertificateRef)certificate)); uint8_t hash[20] = { 0 }; uint8_t signature[256] = { 0 }; @@ -29,7 +29,7 @@ static void testFileVaultKeySign() { NSError *error; id key = CFBridgingRelease(SecKeyCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey)); id certificate = CFBridgingRelease(SecCertificateCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey)); - id pubKey = CFBridgingRelease(SecCertificateCopyPublicKey((SecCertificateRef)certificate)); + id pubKey = CFBridgingRelease(SecCertificateCopyKey((SecCertificateRef)certificate)); algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1; error = nil; diff --git a/OSX/shared_regressions/si-44-seckey-proxy.m b/OSX/shared_regressions/si-44-seckey-proxy.m new file mode 100644 index 00000000..c0aa33aa --- /dev/null +++ b/OSX/shared_regressions/si-44-seckey-proxy.m @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2016 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@ + */ + + +#import +#import +#import +#import + +#import "shared_regressions.h" + +static void test_key_proxy_connect() { + NSError *error; + id serverKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @(256)}, (void *)&error)); + ok(serverKey != NULL, "generated local ec256 keypair"); + SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey]; + SecKeyRef localKey = [SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]; + isnt(localKey, NULL, "connected to remote key, error %@", error); + ok(CFGetTypeID(localKey) == SecKeyGetTypeID(), "Connected key is really SecKey"); + + // Try another connection to the proxy. + SecKeyRef secondKey = [SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]; + isnt(secondKey, NULL, "2nd connection should not be refused"); + isnt(SecKeyGetBlockSize(secondKey), (size_t)0, "2nd connections working normally"); + + // Even after deleting (not invalidating!) proxy, existing connections should work right. + NSXPCListenerEndpoint *endpoint = keyProxy.endpoint; + keyProxy = nil; + + // However, connection to it should not be possible any more. + CFRelease(secondKey); + secondKey = [SecKeyProxy createKeyFromEndpoint:endpoint error:&error]; + is(secondKey, NULL, "connecting to deleted proxy should not be possible"); + + // Create new proxy and invalidate it (idempotent, so we try invalidate multiple times). + keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey]; + [keyProxy invalidate]; + [keyProxy invalidate]; + secondKey = [SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]; + is(secondKey, NULL, "connection to invalidated proxy should be refused."); + + // Invalidate connected proxy, make sure that remote key does not work as expected. + keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey]; + secondKey = [SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]; + isnt(secondKey, NULL, "connecting to proxy failed."); + + is(SecKeyGetBlockSize((__bridge SecKeyRef)serverKey), SecKeyGetBlockSize(secondKey), "connected key should work fine"); + [keyProxy invalidate]; + is(SecKeyGetBlockSize(secondKey), (size_t)0, "disconnected key should fail"); + CFRelease(secondKey); +} +static const int TestKeyProxyConnectCount = 10; + +static void test_key_proxy_simple_ops() { + NSError *error; + id serverKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @(256)}, (void *)&error)); + SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey]; + id localKey = CFBridgingRelease([SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]); + NSDictionary *serverAttributes = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)serverKey)); + NSDictionary *localAttributes = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)localKey)); + isnt(localAttributes, nil, "attributes for local remote key failed"); + ok([serverAttributes isEqual:localAttributes], "local and remote attributes should be identical"); + + // Just call description, there is no sane way to test the contents, not crashing is enough. + CFBridgingRelease(CFCopyDescription((SecKeyRef)localKey)); + + is(SecKeyGetAlgorithmId((__bridge SecKeyRef)serverKey), SecKeyGetAlgorithmId((__bridge SecKeyRef)localKey), "GetAlgorithmId failed for remote"); +} +static const int TestKeyProxySimpleOpsCount = 3; + +static void test_crypto_sign(id key1, id key2, SecKeyAlgorithm algorithm) { + id pk1 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key1)); + isnt(pk1, nil, "failed to get pubkey from key %@", key1); + id pk2 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key2)); + isnt(pk2, nil, "failed to get pubkey from key %@", key2); + + NSData *message = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding]; + NSError *error; + NSData *signature1 = CFBridgingRelease(SecKeyCreateSignature((SecKeyRef)key1, algorithm, (CFDataRef)message, (void *)&error)); + isnt(signature1, nil, "failed to sign data with algorithm %@: %@", algorithm, error); + ok(SecKeyVerifySignature((SecKeyRef)pk2, algorithm, (CFDataRef)message, (CFDataRef)signature1, (void *)&error), "failed to verify data with algorithm %@: %@", algorithm, error); + + message = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding]; + error = nil; + NSData *signature2 = CFBridgingRelease(SecKeyCreateSignature((SecKeyRef)key2, algorithm, (CFDataRef)message, (void *)&error)); + isnt(signature2, nil, "failed to sign data with algorithm %@: %@", algorithm, error); + ok(SecKeyVerifySignature((SecKeyRef)pk1, algorithm, (CFDataRef)message, (CFDataRef)signature1, (void *)&error), "failed to verify data with algorithm %@: %@", algorithm, error); +} +static const int TestKeyCryptoSignCount = 6; + +static void test_crypto_encrypt(id key1, id key2, SecKeyAlgorithm algorithm) { + id pk1 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key1)); + isnt(pk1, nil, "failed to get pubkey from key %@", key1); + id pk2 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key2)); + isnt(pk2, nil, "failed to get pubkey from key %@", key2); + + NSData *message = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding]; + NSError *error; + NSData *ciphertext1 = CFBridgingRelease(SecKeyCreateEncryptedData((SecKeyRef)pk1, algorithm, (CFDataRef)message, (void *)&error)); + isnt(ciphertext1, nil, "failed to encrypt data with algorithm %@: %@", algorithm, error); + NSData *plaintext1 = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)key2, algorithm, (CFDataRef)ciphertext1, (void *)&error)); + ok([plaintext1 isEqualToData:message], "encrypt/decrypt differs from message: %@ vs %@", message, plaintext1); + + message = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding]; + error = nil; + NSData *ciphertext2 = CFBridgingRelease(SecKeyCreateEncryptedData((SecKeyRef)pk2, algorithm, (CFDataRef)message, (void *)&error)); + isnt(ciphertext2, nil, "failed to encrypt data with algorithm %@: %@", algorithm, error); + NSData *plaintext2 = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)key1, algorithm, (CFDataRef)ciphertext2, (void *)&error)); + ok([plaintext2 isEqualToData:message], "encrypt/decrypt differs from message: %@ vs %@", message, plaintext2); +} +static const int TestKeyCryptoEncryptCount = 6; + +static void test_crypto_kxchg(id key1, id key2, SecKeyAlgorithm algorithm) { + id pk1 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key1)); + isnt(pk1, nil, "failed to get pubkey from key %@", key1); + id pk2 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key2)); + isnt(pk2, nil, "failed to get pubkey from key %@", key2); + + NSError *error; + NSData *result1 = CFBridgingRelease(SecKeyCopyKeyExchangeResult((SecKeyRef)key1, algorithm, (SecKeyRef)pk2, (CFDictionaryRef)@{}, (void *)&error)); + isnt(result1, nil, "failed to keyexchange data with algorithm %@: %@", algorithm, error); + NSData *result2 = CFBridgingRelease(SecKeyCopyKeyExchangeResult((SecKeyRef)key2, algorithm, (SecKeyRef)pk1, (CFDictionaryRef)@{}, (void *)&error)); + isnt(result1, nil, "failed to keyexchange data with algorithm %@: %@", algorithm, error); + ok([result1 isEqualToData:result2], "keyexchange results differ!"); +} +static const int TestKeyCryptoKeyExchange = 5; + +static void test_key_proxy_crypto_ops_RSA() { + NSError *error; + id serverKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @(2048)}, (void *)&error)); + ok(serverKey != NULL, "generated local rsa2048 keypair: %@", error); + SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey]; + id localKey = CFBridgingRelease([SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]); + isnt(localKey, NULL, "connected to remote key, error %@", error); + + test_crypto_sign(localKey, serverKey, kSecKeyAlgorithmRSASignatureMessagePSSSHA1); + test_crypto_sign(serverKey, localKey, kSecKeyAlgorithmRSASignatureMessagePSSSHA256); + + test_crypto_encrypt(localKey, serverKey, kSecKeyAlgorithmRSAEncryptionOAEPSHA1); + test_crypto_encrypt(serverKey, localKey, kSecKeyAlgorithmRSAEncryptionOAEPSHA256); +} +static const int TestKeyCryptoOpsRSACount = 2 + TestKeyCryptoSignCount * 2 + TestKeyCryptoEncryptCount * 2; + +static void test_key_proxy_crypto_ops_EC() { + NSError *error; + id serverKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @(256)}, (void *)&error)); + ok(serverKey != NULL, "generated local ec256 keypair: %@", error); + SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey]; + id localKey = CFBridgingRelease([SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]); + isnt(localKey, NULL, "connected to remote key, error %@", error); + + test_crypto_sign(localKey, serverKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA1); + test_crypto_sign(serverKey, localKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256); + + test_crypto_encrypt(localKey, serverKey, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM); + test_crypto_encrypt(serverKey, localKey, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM); + + test_crypto_kxchg(localKey, serverKey, kSecKeyAlgorithmECDHKeyExchangeStandard); +} +static const int TestKeyCryptoOpsECCount = 2 + TestKeyCryptoSignCount * 2 + TestKeyCryptoEncryptCount * 2 + TestKeyCryptoKeyExchange * 1; + +/* + Bag Attributes + friendlyName: uranusLeaf + localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23 + subject=/CN=uranusLeaf/emailAddress=uranus@uranus.com + issuer=/CN=plutoCA/emailAddress=pluto@pluto.com + */ +static const uint8_t _c1[] = { + 0x30, 0x82, 0x02, 0xe0, 0x30, 0x82, 0x01, 0xc8, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, + 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x30, 0x32, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43, + 0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x0c, 0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40, + 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31, + 0x32, 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, + 0x35, 0x5a, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32, + 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, 0x35, + 0x5a, 0x30, 0x37, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x75, 0x72, + 0x61, 0x6e, 0x75, 0x73, 0x4c, 0x65, 0x61, 0x66, + 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c, + 0x11, 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x40, + 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 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, 0xa6, 0x82, 0x8e, 0xc6, 0x7e, + 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, 0x35, + 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, 0xa8, + 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, 0x80, + 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, 0x93, + 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, 0xd7, + 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, 0xfb, + 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, 0xac, + 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, 0x2a, + 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, 0xc3, + 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, 0x78, + 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, 0x9b, + 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, 0xf6, + 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, 0xe7, + 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, 0xdc, + 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, 0xaa, + 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, 0xe2, + 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, 0x4f, + 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, 0x04, + 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, 0xb2, + 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, 0x71, + 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, 0x44, + 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, 0x48, + 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, 0x4b, + 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, 0x47, + 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, 0x08, + 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, 0x32, + 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, 0x26, + 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, 0x23, + 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, 0xd4, + 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, 0x9e, + 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, 0xf8, + 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x17, 0xa5, 0x22, 0xed, + 0xb8, 0x3e, 0x1f, 0x11, 0x99, 0xc5, 0xba, 0x28, + 0x3e, 0x7e, 0xa6, 0xeb, 0x02, 0x81, 0x06, 0xa1, + 0xc6, 0x80, 0xb9, 0x7e, 0x5c, 0x5a, 0x63, 0xe0, + 0x8d, 0xeb, 0xd0, 0xec, 0x9c, 0x3a, 0x94, 0x64, + 0x7c, 0x13, 0x54, 0x0d, 0xd6, 0xe3, 0x27, 0x88, + 0xa6, 0xd2, 0x4b, 0x36, 0xdd, 0x2e, 0xfa, 0x94, + 0xe5, 0x03, 0x27, 0xc9, 0xa6, 0x31, 0x02, 0xea, + 0x40, 0x77, 0x2e, 0x93, 0xc4, 0x4d, 0xe2, 0x70, + 0xe2, 0x67, 0x1c, 0xa8, 0x0d, 0xcd, 0x1a, 0x72, + 0x86, 0x2c, 0xea, 0xdc, 0x7f, 0x8c, 0x49, 0x2c, + 0xe7, 0x99, 0x13, 0xda, 0x3f, 0x58, 0x9e, 0xf5, + 0x4d, 0x3c, 0x8c, 0x1c, 0xed, 0x85, 0xa7, 0xe2, + 0xae, 0xda, 0x5f, 0xbe, 0x36, 0x1c, 0x9f, 0x5a, + 0xa0, 0xdc, 0x2a, 0xc0, 0xee, 0x71, 0x07, 0x26, + 0x8b, 0xe8, 0x8a, 0xf8, 0x2d, 0x36, 0x78, 0xc9, + 0x79, 0xfa, 0xbe, 0x98, 0x59, 0x95, 0x12, 0x24, + 0xf1, 0xda, 0x20, 0xc7, 0x78, 0xf9, 0x7c, 0x6a, + 0x24, 0x43, 0x82, 0xa8, 0x0f, 0xb1, 0x7d, 0x94, + 0xaa, 0x30, 0x35, 0xe5, 0x69, 0xdc, 0x0a, 0x0e, + 0xaf, 0x10, 0x5e, 0x1a, 0x81, 0x50, 0x5c, 0x7e, + 0x24, 0xb3, 0x07, 0x65, 0x4b, 0xc1, 0x7e, 0xc6, + 0x38, 0xdb, 0xd3, 0x6a, 0xf0, 0xd8, 0x85, 0x61, + 0x9a, 0x9f, 0xfe, 0x02, 0x46, 0x29, 0xb2, 0x9a, + 0xe2, 0x04, 0xe7, 0x72, 0xcc, 0x87, 0x46, 0xba, + 0x7d, 0xa8, 0xf9, 0xd0, 0x0f, 0x29, 0xfc, 0xfd, + 0xd1, 0xd0, 0x7f, 0x36, 0xc1, 0xd8, 0x7d, 0x88, + 0x03, 0x62, 0xf5, 0x8c, 0x00, 0xb5, 0xc2, 0x81, + 0x44, 0x67, 0x58, 0x11, 0xb4, 0x3a, 0xbb, 0xd1, + 0x8c, 0x94, 0x20, 0x60, 0xea, 0xa0, 0xac, 0xc1, + 0xf1, 0x08, 0x54, 0xb8, 0xf6, 0x5e, 0xac, 0xf1, + 0xec, 0x78, 0x69, 0x9d, 0x7e, 0x4d, 0x06, 0x3b, + 0x9b, 0x78, 0x78, 0x10 +}; + +/* + Bag Attributes + friendlyName: uranusLeaf + localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23 + Key Attributes: + */ +static const uint8_t _k1[] = { + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6, + 0x7e, 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, + 0x35, 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, + 0xa8, 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, + 0x80, 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, + 0x93, 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, + 0xd7, 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, + 0xfb, 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, + 0xac, 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, + 0x2a, 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, + 0xc3, 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, + 0x78, 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, + 0x9b, 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, + 0xf6, 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, + 0xe7, 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, + 0xdc, 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, + 0xaa, 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, + 0xe2, 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, + 0x4f, 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, + 0x04, 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, + 0xb2, 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, + 0x71, 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, + 0x44, 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, + 0x48, 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, + 0x4b, 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, + 0x47, 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, + 0x08, 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, + 0x32, 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, + 0x26, 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, + 0x23, 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, + 0xd4, 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, + 0x9e, 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, + 0xf8, 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x01, 0x00, 0x4d, 0x27, 0xf2, + 0x40, 0xc8, 0x3f, 0x5c, 0x87, 0x3c, 0xd9, 0xde, + 0xa6, 0xa5, 0x93, 0xea, 0xbd, 0x36, 0xf8, 0xd9, + 0xad, 0xc7, 0xda, 0x07, 0x7a, 0xec, 0x31, 0x02, + 0x41, 0x09, 0x3a, 0x34, 0x32, 0x82, 0x0b, 0x5b, + 0x7b, 0xe6, 0xa4, 0x2a, 0xe7, 0x14, 0xef, 0x43, + 0x36, 0x61, 0xbe, 0x20, 0x4b, 0x82, 0x43, 0x63, + 0x98, 0x80, 0x82, 0x19, 0x61, 0x71, 0x99, 0xaa, + 0xf8, 0x59, 0xfd, 0xde, 0xa0, 0x03, 0xa8, 0xab, + 0x9a, 0xec, 0x28, 0xac, 0x63, 0x79, 0x75, 0x84, + 0x03, 0xac, 0x45, 0x5e, 0x04, 0x15, 0xb3, 0x47, + 0xa2, 0x8f, 0x28, 0xb0, 0x72, 0xd0, 0x06, 0x02, + 0xaf, 0x1e, 0x0a, 0x0a, 0xe9, 0x11, 0x35, 0x4a, + 0x04, 0x42, 0xb5, 0x0f, 0xd2, 0xcf, 0x4d, 0xdf, + 0xdb, 0xef, 0x58, 0xbd, 0xf3, 0xa5, 0x3b, 0x11, + 0x3f, 0xc5, 0x47, 0x81, 0x85, 0xad, 0xd7, 0x1f, + 0x58, 0x06, 0x42, 0xdc, 0x37, 0x3c, 0xdb, 0x98, + 0x33, 0xa1, 0xc6, 0x80, 0x07, 0xe0, 0x2b, 0xc5, + 0xf5, 0x60, 0x35, 0x6a, 0xa2, 0x06, 0x40, 0x4a, + 0xac, 0x64, 0x02, 0x58, 0x4d, 0x07, 0xe3, 0x69, + 0xd7, 0xe0, 0x8f, 0xb5, 0xf4, 0xbc, 0xfa, 0xab, + 0x1a, 0xb0, 0xfa, 0x29, 0xf8, 0xca, 0xde, 0x78, + 0xf0, 0x89, 0xe2, 0xf9, 0xb7, 0x68, 0x5b, 0x0e, + 0xdc, 0x4e, 0x8a, 0x56, 0x8d, 0x33, 0x20, 0x2e, + 0xed, 0x2e, 0xab, 0x6f, 0xba, 0x77, 0xef, 0xe6, + 0x12, 0x62, 0x49, 0x9e, 0x87, 0x76, 0x1c, 0x1e, + 0xf4, 0x0e, 0x9e, 0x78, 0x98, 0x91, 0x1a, 0xe3, + 0xb4, 0x51, 0x4b, 0x8c, 0x2f, 0x08, 0x97, 0x8f, + 0xf9, 0x68, 0x61, 0x40, 0xcd, 0xb6, 0x10, 0xb4, + 0xfb, 0x75, 0xb4, 0x20, 0xc1, 0x5a, 0xda, 0x64, + 0xfd, 0x51, 0x06, 0x85, 0x9a, 0x9e, 0x5d, 0x82, + 0x14, 0xd4, 0x41, 0x4e, 0x75, 0x10, 0xb5, 0x7b, + 0xd0, 0x4c, 0xd1, 0x00, 0x01, 0x02, 0x81, 0x81, + 0x00, 0xcf, 0x8e, 0x68, 0x04, 0x67, 0x09, 0xa9, + 0x6e, 0xff, 0x11, 0x8c, 0xe5, 0xe4, 0x16, 0xdd, + 0xb6, 0xa6, 0x55, 0xca, 0x4b, 0x0b, 0xbb, 0xb7, + 0xf5, 0xe5, 0x73, 0xf3, 0x24, 0x84, 0x29, 0xb2, + 0xc3, 0xbc, 0x7f, 0x2b, 0x4a, 0xc7, 0xdf, 0x46, + 0x8e, 0xe1, 0x35, 0x69, 0x1b, 0x8e, 0x9f, 0x6b, + 0x4d, 0xf3, 0x65, 0xae, 0x3d, 0x87, 0x2b, 0xc9, + 0xf0, 0x8c, 0xf2, 0x88, 0x2f, 0x1b, 0x79, 0x80, + 0xd2, 0xb2, 0x64, 0x0a, 0xcc, 0x66, 0x69, 0x4c, + 0xa1, 0x85, 0xc4, 0x6a, 0x94, 0x46, 0x70, 0x69, + 0xbc, 0x8c, 0x1c, 0x62, 0x65, 0x4d, 0x68, 0xcc, + 0xe3, 0x3c, 0x6c, 0xe7, 0xd1, 0x09, 0xed, 0xdd, + 0x42, 0x10, 0x11, 0x6b, 0xdd, 0x7c, 0xe3, 0xe1, + 0x3b, 0x3b, 0x0d, 0x01, 0x6d, 0xca, 0x2f, 0x4b, + 0x45, 0x5e, 0x76, 0x5d, 0x5c, 0x6f, 0x53, 0xa4, + 0x38, 0x74, 0x75, 0x94, 0x2c, 0xda, 0xf8, 0xa6, + 0x01, 0x02, 0x81, 0x81, 0x00, 0xcd, 0x5f, 0x9d, + 0x6c, 0x94, 0xf6, 0x44, 0x37, 0x72, 0xfe, 0xcf, + 0xbe, 0x82, 0x96, 0x24, 0x22, 0x12, 0x07, 0x6f, + 0xd1, 0x57, 0x7b, 0xc7, 0x63, 0x20, 0xf5, 0x93, + 0x79, 0x70, 0x0b, 0xe4, 0x38, 0x19, 0x62, 0x7b, + 0x89, 0x3e, 0x45, 0xdf, 0xd6, 0xae, 0x9d, 0x0d, + 0xa8, 0x76, 0xc1, 0xbd, 0x04, 0x2b, 0xaa, 0x30, + 0x6a, 0xac, 0x65, 0x91, 0x61, 0xf0, 0xf8, 0x5d, + 0xa3, 0x53, 0xa4, 0xfb, 0x99, 0xac, 0x46, 0x7a, + 0x12, 0x4b, 0xf7, 0xa7, 0x48, 0x41, 0x61, 0x48, + 0x26, 0x5c, 0x68, 0x2f, 0x73, 0x91, 0xe4, 0x74, + 0xcd, 0xc9, 0x8b, 0xe7, 0x26, 0xe4, 0x35, 0xde, + 0x32, 0x6b, 0x24, 0x49, 0xf2, 0x04, 0x67, 0x3d, + 0x31, 0x8f, 0x22, 0xe5, 0x49, 0xae, 0x49, 0x94, + 0xb3, 0x45, 0x2b, 0xed, 0x6f, 0x9c, 0xc7, 0x80, + 0xf0, 0x42, 0xd5, 0x8f, 0x27, 0xd6, 0xd6, 0x49, + 0xf2, 0x16, 0xcc, 0x4b, 0x39, 0x02, 0x81, 0x81, + 0x00, 0xbb, 0xb7, 0xd7, 0x59, 0xcb, 0xfb, 0x10, + 0x13, 0xc4, 0x7b, 0x92, 0x0c, 0x45, 0xcb, 0x6c, + 0x81, 0x0a, 0x55, 0x63, 0x1d, 0x96, 0xa2, 0x13, + 0xd2, 0x40, 0xd1, 0x2a, 0xa1, 0xe7, 0x2a, 0x73, + 0x74, 0xd6, 0x61, 0xc9, 0xbc, 0xdb, 0xa2, 0x93, + 0x85, 0x1c, 0x28, 0x9b, 0x44, 0x82, 0x2c, 0xaa, + 0xf7, 0x18, 0x60, 0xe9, 0x42, 0xda, 0xa2, 0xff, + 0x04, 0x21, 0xe6, 0x24, 0xc7, 0x3e, 0x39, 0x19, + 0x0a, 0xf6, 0xae, 0xc6, 0x99, 0x71, 0x32, 0x61, + 0x4d, 0x60, 0xd7, 0x71, 0x71, 0x63, 0x77, 0xbe, + 0x19, 0xfa, 0x3a, 0x9d, 0xbf, 0x73, 0x50, 0x8a, + 0xa6, 0x26, 0x7b, 0x74, 0xfa, 0x39, 0xd9, 0xb9, + 0x18, 0x4b, 0xc2, 0x05, 0xe5, 0x8f, 0x53, 0xe6, + 0xdc, 0x14, 0x1f, 0x42, 0x20, 0x93, 0x11, 0x4d, + 0x29, 0x93, 0x32, 0xc8, 0x63, 0x96, 0x88, 0x76, + 0x69, 0x5c, 0xe3, 0x0e, 0xbd, 0xb6, 0xd9, 0xd6, + 0x01, 0x02, 0x81, 0x80, 0x62, 0xa2, 0xed, 0x84, + 0xdc, 0xf6, 0x7a, 0x44, 0xf7, 0x62, 0x12, 0x7c, + 0xb9, 0x53, 0x4a, 0xff, 0x62, 0x11, 0x58, 0x4e, + 0xfe, 0xe9, 0x60, 0x15, 0xe8, 0x1a, 0x8a, 0x3d, + 0xe4, 0xe6, 0x91, 0x31, 0xb0, 0x5f, 0x70, 0x5d, + 0xb6, 0x1e, 0xf1, 0x26, 0xb6, 0xae, 0x8f, 0x84, + 0xbd, 0xa4, 0xc7, 0x17, 0x5d, 0xb1, 0x5b, 0x97, + 0xa0, 0x3d, 0x17, 0xda, 0x26, 0x55, 0xe3, 0x03, + 0x32, 0x85, 0x26, 0xa1, 0xe3, 0xef, 0xe5, 0x69, + 0x2c, 0x3b, 0x41, 0x88, 0x9e, 0x7e, 0x0e, 0x9c, + 0xfd, 0xfc, 0xbb, 0xed, 0x91, 0xc0, 0x5b, 0xa9, + 0x0a, 0x87, 0xba, 0xf9, 0x1e, 0xda, 0x10, 0x61, + 0xbe, 0xbb, 0xab, 0x18, 0x25, 0xad, 0x3f, 0xe2, + 0xb1, 0x90, 0x5c, 0xf7, 0x4a, 0x51, 0xe4, 0xad, + 0x45, 0x27, 0x97, 0xdd, 0xe7, 0x3a, 0x9a, 0x5e, + 0xca, 0x7a, 0xaf, 0x4a, 0xbf, 0x10, 0x24, 0x6b, + 0xb5, 0x2f, 0x61, 0x61, 0x02, 0x81, 0x81, 0x00, + 0x85, 0x7c, 0x78, 0xa5, 0x11, 0xdf, 0xc3, 0x6a, + 0x38, 0x48, 0xfa, 0x7e, 0x48, 0xf0, 0x5a, 0x58, + 0xe2, 0xc5, 0x83, 0x4e, 0x38, 0x3f, 0x4a, 0x2b, + 0x07, 0x57, 0x31, 0xe7, 0xbe, 0x50, 0xb1, 0xbb, + 0x24, 0xf3, 0x3d, 0x8b, 0x53, 0xb7, 0xd1, 0x47, + 0x72, 0x5e, 0xd5, 0xd6, 0x4c, 0xce, 0x2c, 0x46, + 0x61, 0x9a, 0xaa, 0xc3, 0x0e, 0xd4, 0x23, 0x2c, + 0xdd, 0xf5, 0xb7, 0xad, 0x38, 0x52, 0x17, 0xc4, + 0x16, 0xbb, 0xda, 0x1c, 0x61, 0xb1, 0xca, 0x8d, + 0xb2, 0xa0, 0xbe, 0x4f, 0x3d, 0x19, 0x0e, 0xe0, + 0x0e, 0x52, 0xad, 0xf3, 0xaf, 0xd9, 0xcc, 0x78, + 0xc2, 0xb1, 0x5e, 0x05, 0x5e, 0xf2, 0x27, 0x84, + 0x15, 0xe4, 0x8f, 0xca, 0xc5, 0x92, 0x43, 0xe0, + 0x24, 0x8d, 0xf2, 0x5d, 0x55, 0xcc, 0x9d, 0x2f, + 0xa9, 0xf6, 0x9b, 0x67, 0x6a, 0x87, 0x74, 0x36, + 0x34, 0x7c, 0xd4, 0x9d, 0xff, 0xad, 0xee, 0x69 +}; + +static void test_key_proxy_identity() { + id certificate = CFBridgingRelease(SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)[NSData dataWithBytes:_c1 length:sizeof(_c1)])); + isnt(certificate, nil, "created certificate"); + NSError *error; + id key = CFBridgingRelease(SecKeyCreateWithData((CFDataRef)[NSData dataWithBytes:_k1 length:sizeof(_k1)], (CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate}, (void *)&error)); + isnt(key, nil, "create key: %@", error); + id identity = CFBridgingRelease(SecIdentityCreate(kCFAllocatorDefault, (__bridge SecCertificateRef)certificate, (__bridge SecKeyRef)key)); + isnt(identity, nil, "create identity"); + + SecKeyProxy *identityProxy = [[SecKeyProxy alloc] initWithIdentity:(SecIdentityRef)identity]; + isnt(identityProxy, nil, "create identity proxy"); + + id localIdentity = CFBridgingRelease([SecKeyProxy createIdentityFromEndpoint:identityProxy.endpoint error:&error]); + isnt(localIdentity, nil, "create remote identity"); + + id localKey; + id localCertificate; + SecIdentityCopyPrivateKey((__bridge SecIdentityRef)identity, (void *)&localKey); + SecIdentityCopyCertificate((__bridge SecIdentityRef)identity, (void *)&localCertificate); + isnt(localKey, nil, "got key from localIdentity"); + isnt(localCertificate, nil, "got certificate from localIdentity"); + + ok([certificate isEqual:localCertificate], "Certificates are the same"); + is(SecKeyGetBlockSize((SecKeyRef)key), SecKeyGetBlockSize((SecKeyRef)localKey), "Keys are the same"); + + // Check that it is not possible to get identity from key proxy + SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)key]; + error = nil; + id secondIdentity = CFBridgingRelease([SecKeyProxy createIdentityFromEndpoint:keyProxy.endpoint error:&error]); + is(secondIdentity, nil, "connecting identity to key proxy should not be possible."); +} +static const int TestKeyProxyIdentityCount = 10; + +static const int TestCount = +TestKeyProxyConnectCount + +TestKeyProxySimpleOpsCount + +TestKeyCryptoOpsRSACount + +TestKeyCryptoOpsECCount + +TestKeyProxyIdentityCount; + +int si_44_seckey_proxy(int argc, char *const *argv) { + plan_tests(TestCount); + + @autoreleasepool { + test_key_proxy_connect(); + test_key_proxy_simple_ops(); + test_key_proxy_crypto_ops_RSA(); + test_key_proxy_crypto_ops_EC(); + test_key_proxy_identity(); + } + + return 0; +} diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/CA_alpha.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/CA_alpha.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/CA_alpha.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/CA_alpha.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/CA_beta.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/CA_beta.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/CA_beta.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/CA_beta.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/digicert_sha2_ev_server_ca.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/digicert_sha2_ev_server_ca.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/digicert_sha2_ev_server_ca.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/digicert_sha2_ev_server_ca.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/pilot_3055998.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/pilot_3055998.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/pilot_3055998.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/pilot_3055998.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/pilot_3055998_issuer.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/pilot_3055998_issuer.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/pilot_3055998_issuer.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/pilot_3055998_issuer.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/serverA.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/serverA.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/serverA.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/serverA.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/serverD.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/serverD.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/serverD.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/serverD.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/serverF.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/serverF.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/serverF.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/serverF.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_1601.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_1601.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_1601.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_1601.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_1603.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_1603.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_1603.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_1603.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_1604.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_1604.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_1604.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_1604.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_1701.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_1701.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_1701.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_1701.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_1704.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_1704.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_1704.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_1704.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_1705.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_1705.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_1705.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_1705.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_1801.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_1801.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_1801.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_1801.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_1804.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_1804.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_1804.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_1804.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_1805.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_1805.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_1805.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_1805.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/server_2001.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/server_2001.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/server_2001.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/server_2001.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_00008013.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_00008013.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_00008013.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_00008013.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_00008013_issuer.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_00008013_issuer.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_00008013_issuer.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_00008013_issuer.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_5555bc4f.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_5555bc4f.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_5555bc4f.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_5555bc4f.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_5555bc4f_issuer.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_5555bc4f_issuer.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_5555bc4f_issuer.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_5555bc4f_issuer.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_aaaae152.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_aaaae152.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_aaaae152.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_aaaae152.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_fff9b5f6.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_fff9b5f6.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_fff9b5f6.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_fff9b5f6.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_fff9b5f6_issuer.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_fff9b5f6_issuer.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_fff9b5f6_issuer.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/whitelist_fff9b5f6_issuer.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/www_digicert_com_2015.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/www_digicert_com_2015.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/www_digicert_com_2015.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/www_digicert_com_2015.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/www_digicert_com_2016.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/www_digicert_com_2016.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/www_digicert_com_2016.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/www_digicert_com_2016.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/www_paypal_com.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/www_paypal_com.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/www_paypal_com.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/www_paypal_com.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct-data/www_paypal_com_issuer.crt b/OSX/shared_regressions/si-82-sectrust-ct-data/www_paypal_com_issuer.cer similarity index 100% rename from OSX/shared_regressions/si-82-sectrust-ct-data/www_paypal_com_issuer.crt rename to OSX/shared_regressions/si-82-sectrust-ct-data/www_paypal_com_issuer.cer diff --git a/OSX/shared_regressions/si-82-sectrust-ct.m b/OSX/shared_regressions/si-82-sectrust-ct.m index 3213623f..66867cde 100644 --- a/OSX/shared_regressions/si-82-sectrust-ct.m +++ b/OSX/shared_regressions/si-82-sectrust-ct.m @@ -38,7 +38,7 @@ static void test_ct_trust(CFArrayRef certs, CFArrayRef scts, CFTypeRef ocsprespo - isnt(policy = SecPolicyCreateSSL(false, hostname), NULL, "create policy"); + isnt(policy = SecPolicyCreateSSL(true, hostname), NULL, "create policy"); isnt(policies = CFArrayCreate(kCFAllocatorDefault, (const void **)&policy, 1, &kCFTypeArrayCallBacks), NULL, "create policies"); ok_status(SecTrustCreateWithCertificates(certs, policies, &trust), "create trust"); @@ -102,7 +102,7 @@ errOut: static SecCertificateRef SecCertificateCreateFromResource(NSString *name) { - NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:@".crt" subdirectory:@"si-82-sectrust-ct-data"]; + NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:@".cer" subdirectory:@"si-82-sectrust-ct-data"]; NSData *certData = [NSData dataWithContentsOfURL:url]; @@ -194,7 +194,7 @@ static void tests() /* Case 1: coreos-ct-test embedded SCT - only 1 SCT - so not CT qualified */ isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); CFArrayAppendValue(certs, certF); - test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307, + test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, NULL, date_20150307, false, false, false, "coreos-ct-test 1"); CFReleaseNull(certs); @@ -203,7 +203,7 @@ static void tests() CFArrayAppendValue(certs, certD); isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array"); CFArrayAppendValue(scts, proofD); - test_ct_trust(certs, scts, NULL, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307, + test_ct_trust(certs, scts, NULL, anchors, trustedLogs, NULL, date_20150307, false, false, false, "coreos-ct-test 2"); CFReleaseNull(certs); CFReleaseNull(scts); @@ -216,95 +216,48 @@ static void tests() false, false, false, "digicert 2015"); CFReleaseNull(certs); - /* case 4: paypal.com cert - not CT, but EV */ - isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); - CFArrayAppendValue(certs, www_paypal_com_cert); - CFArrayAppendValue(certs, www_paypal_com_issuer_cert); - test_ct_trust(certs, NULL, NULL, NULL, trustedLogs, CFSTR("www.paypal.com"), date_20150307, - false, false, false, "paypal"); - CFReleaseNull(certs); - - /* Case 5: coreos-ct-test standalone SCT - 2 SCTs - CT qualified */ + /* Case 4: coreos-ct-test standalone SCT - 2 SCTs - CT qualified */ isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); CFArrayAppendValue(certs, certA); isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array"); CFArrayAppendValue(scts, proofA_1); CFArrayAppendValue(scts, proofA_2); - test_ct_trust(certs, scts, NULL, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307, + test_ct_trust(certs, scts, NULL, anchors, trustedLogs, NULL, date_20150307, true, false, false, "coreos-ct-test 3"); CFReleaseNull(certs); CFReleaseNull(scts); - - /* Case 6: Test with an invalid OCSP response */ + /* Case 5: Test with an invalid OCSP response */ isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); CFArrayAppendValue(certs, certA); isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array"); CFArrayAppendValue(scts, proofA_1); - test_ct_trust(certs, scts, invalid_ocsp, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307, + test_ct_trust(certs, scts, invalid_ocsp, anchors, trustedLogs, NULL, date_20150307, false, false, false, "coreos-ct-test 4"); CFReleaseNull(certs); CFReleaseNull(scts); - /* Case 7: Test with a valid OCSP response */ + /* Case 6: Test with a valid OCSP response */ isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); CFArrayAppendValue(certs, certA); isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array"); CFArrayAppendValue(scts, proofA_1); - test_ct_trust(certs, scts, valid_ocsp, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307, + test_ct_trust(certs, scts, valid_ocsp, anchors, trustedLogs, NULL, date_20150307, false, false, false, "coreos-ct-test 5"); CFReleaseNull(certs); CFReleaseNull(scts); - /* Case 8: Test with a bad hash OCSP response */ + /* Case 7: Test with a bad hash OCSP response */ isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); CFArrayAppendValue(certs, certA); isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array"); CFArrayAppendValue(scts, proofA_1); - test_ct_trust(certs, scts, bad_hash_ocsp, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307, + test_ct_trust(certs, scts, bad_hash_ocsp, anchors, trustedLogs, NULL, date_20150307, false, false, false, "coreos-ct-test 6"); CFReleaseNull(certs); CFReleaseNull(scts); - /* Case 9: Previously WhiteListed EV cert (expired in Feb 2016, so not on final whitelist)*/ - isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); - CFArrayAppendValue(certs, pilot_cert_3055998); - CFArrayAppendValue(certs, pilot_cert_3055998_issuer); - test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.ssbwingate.com"), date_20150307, - false, false, false, "previously whitelisted cert"); - CFReleaseNull(certs); - - /* Case 10-13: WhiteListed EV cert */ - isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); - CFArrayAppendValue(certs, whitelist_00008013); - CFArrayAppendValue(certs, whitelist_00008013_issuer); - test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("clava.com"), date_20150307, - false, false, false, "whitelisted cert 00008013"); - CFReleaseNull(certs); - - isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); - CFArrayAppendValue(certs, whitelist_5555bc4f); - CFArrayAppendValue(certs, whitelist_5555bc4f_issuer); - test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("lanai.dartmouth.edu"), - date_20150307, false, false, false, "whitelisted cert 5555bc4f"); - CFReleaseNull(certs); - - isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); - CFArrayAppendValue(certs, whitelist_aaaae152); - CFArrayAppendValue(certs, whitelist_5555bc4f_issuer); // Same issuer (Go Daddy) as above - test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.falymusic.com"), - date_20150307, false, false, false, "whitelisted cert aaaae152"); - CFReleaseNull(certs); - - isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); - CFArrayAppendValue(certs, whitelist_fff9b5f6); - CFArrayAppendValue(certs, whitelist_fff9b5f6_issuer); - test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.defencehealth.com.au"), - date_20150307, false, false, false, "whitelisted cert fff9b5f6"); - CFReleaseNull(certs); - - - /* case 14: Current (April 2016) www.digicert.com cert: 3 embedded SCTs, CT qualified */ + /* case 8: Current (April 2016) www.digicert.com cert: 3 embedded SCTs, CT qualified */ isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); CFArrayAppendValue(certs, www_digicert_com_2016_cert); CFArrayAppendValue(certs, digicert_sha2_ev_server_ca); @@ -319,7 +272,7 @@ static void tests() isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array for " #x); \ isnt(cfCert = SecCertificateCreateFromResource(@#x), NULL, "create cfCert from " #x); \ CFArrayAppendValue(certs, cfCert); \ - test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307, true, false, false, #x); \ + test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, NULL, date_20150307, true, false, false, #x); \ CFReleaseNull(certs); \ CFReleaseNull(cfCert); \ } while (0) @@ -374,7 +327,7 @@ static void tests() int si_82_sectrust_ct(int argc, char *const *argv) { - plan_tests(329); + plan_tests(268); tests(); diff --git a/OSX/shared_regressions/si-88-sectrust-valid.m b/OSX/shared_regressions/si-88-sectrust-valid.m index ee7e2ece..b8d67982 100644 --- a/OSX/shared_regressions/si-88-sectrust-valid.m +++ b/OSX/shared_regressions/si-88-sectrust-valid.m @@ -16,8 +16,17 @@ #include "shared_regressions.h" -static void test_valid_trust(SecCertificateRef leaf, SecCertificateRef ca, CFArrayRef anchors, - CFDateRef date, CFIndex policyID, SecTrustResultType expected, const char *test_name) +enum { + kBasicPolicy = 0, + kSSLServerPolicy = 1, +}; + +/* number of tests in the test_valid_trust function */ +#define TVT_COUNT 8 + +static void test_valid_trust(SecCertificateRef leaf, SecCertificateRef ca, SecCertificateRef subca, + CFArrayRef anchors, CFDateRef date, CFIndex policyID, + SecTrustResultType expected, const char *test_name) { CFArrayRef policies=NULL; SecPolicyRef policy=NULL; @@ -34,9 +43,12 @@ static void test_valid_trust(SecCertificateRef leaf, SecCertificateRef ca, CFArr if (ca) { CFArrayAppendValue(certs, ca); } + if (subca) { + CFArrayAppendValue(certs, subca); + } } - if (policyID == 1) { + if (policyID == kSSLServerPolicy) { isnt(policy = SecPolicyCreateSSL(true, NULL), NULL, "create ssl policy"); } else { isnt(policy = SecPolicyCreateBasicX509(), NULL, "create basic policy"); @@ -80,7 +92,10 @@ static SecCertificateRef SecCertificateCreateFromResource(NSString *name) return SecCertificateCreateWithPEM(kCFAllocatorDefault, (__bridge CFDataRef)certData); } -static void tests() +/* number of tests in date_constraints_tests function, plus calls to test_valid_trust */ +#define DC_COUNT (12+(TVT_COUNT*6)) + +static void date_constraints_tests() { SecCertificateRef ca_na=NULL, ca_nb=NULL, root=NULL; SecCertificateRef leaf_na_ok1=NULL, leaf_na_ok2=NULL; @@ -111,47 +126,120 @@ static void tests() /* Case 0: leaf_na_ok1 (not revoked) */ /* -- OK: cert issued 2017-10-20, before the CA not-after date of 2017-10-21 */ /* test cert has no SCT, but is expected to be OK since we now only apply the CT restriction for SSL. */ - test_valid_trust(leaf_na_ok1, ca_na, anchors, date_20180102, 0, kSecTrustResultUnspecified, "leaf_na_ok1 basic test"); + test_valid_trust(leaf_na_ok1, ca_na, NULL, anchors, date_20180102, + kBasicPolicy, kSecTrustResultUnspecified, + "leaf_na_ok1 basic"); /* Case 1: leaf_na_ok1 (not revoked) */ /* -- BAD: since a not-after date now requires CT (for SSL) and the test cert has no SCT, this is fatal. */ - test_valid_trust(leaf_na_ok1, ca_na, anchors, date_20180102, 1, kSecTrustResultFatalTrustFailure, "leaf_na_ok1 ssl test"); + test_valid_trust(leaf_na_ok1, ca_na, NULL, anchors, date_20180102, + kSSLServerPolicy, kSecTrustResultFatalTrustFailure, + "leaf_na_ok1 ssl"); /* Case 2: leaf_na_ok2 (revoked) */ /* -- BAD: cert issued 2017-10-26, after the CA not-after date of 2017-10-21 */ - test_valid_trust(leaf_na_ok2, ca_na, anchors, date_20180102, 0, kSecTrustResultFatalTrustFailure, "leaf_na_ok2 basic test"); + test_valid_trust(leaf_na_ok2, ca_na, NULL, anchors, date_20180102, + kBasicPolicy, kSecTrustResultFatalTrustFailure, + "leaf_na_ok2 basic"); /* Case 3: leaf_nb_ok1 (revoked) */ /* -- BAD: cert issued 2017-10-20, before the CA not-before date of 2017-10-22 */ - test_valid_trust(leaf_nb_ok1, ca_nb, anchors, date_20180102, 0, kSecTrustResultFatalTrustFailure, "leaf_nb_ok1 basic test"); + test_valid_trust(leaf_nb_ok1, ca_nb, NULL, anchors, date_20180102, + kBasicPolicy, kSecTrustResultFatalTrustFailure, + "leaf_nb_ok1 basic"); /* Case 4: leaf_nb_ok2 (not revoked) */ /* -- OK: cert issued 2017-10-26, after the CA not-before date of 2017-10-22 */ - test_valid_trust(leaf_nb_ok2, ca_nb, anchors, date_20180102, 0, kSecTrustResultUnspecified, "leaf_nb_ok2 basic test"); + test_valid_trust(leaf_nb_ok2, ca_nb, NULL, anchors, date_20180102, + kBasicPolicy, kSecTrustResultUnspecified, + "leaf_nb_ok2 basic"); /* Case 5: leaf_nb_revoked1 (revoked) */ /* -- BAD: cert issued 2017-10-20, before the CA not-before date of 2017-10-22 */ - test_valid_trust(leaf_nb_revoked1, ca_nb, anchors, date_20180102, 0, kSecTrustResultFatalTrustFailure, "leaf_nb_revoked1 basic test"); + test_valid_trust(leaf_nb_revoked1, ca_nb, NULL, anchors, date_20180102, + kBasicPolicy, kSecTrustResultFatalTrustFailure, + "leaf_nb_revoked1 basic"); CFReleaseSafe(ca_na); CFReleaseSafe(ca_nb); - CFReleaseSafe(root); CFReleaseSafe(leaf_na_ok1); CFReleaseSafe(leaf_na_ok2); CFReleaseSafe(leaf_nb_ok1); CFReleaseSafe(leaf_nb_ok2); CFReleaseSafe(leaf_nb_revoked1); + CFReleaseSafe(root); CFReleaseSafe(anchors); CFReleaseSafe(cal); CFReleaseSafe(date_20180102); } +/* number of tests in known_intermediate_tests function, plus calls to test_valid_trust */ +#define KI_COUNT (10+(TVT_COUNT*3)) + +static void known_intermediate_tests() +{ + SecCertificateRef ca_ki=NULL, root=NULL; + SecCertificateRef leaf_ki_ok1=NULL, leaf_ki_revoked1=NULL; + SecCertificateRef leaf_unknown=NULL, ca_unknown=NULL; + + isnt(ca_ki = SecCertificateCreateFromResource(@"ca-ki"), NULL, "create ca-ki cert"); + isnt(root = SecCertificateCreateFromResource(@"root"), NULL, "create root cert"); + isnt(leaf_ki_ok1 = SecCertificateCreateFromResource(@"leaf-ki-ok1"), NULL, "create leaf-ki-ok1 cert"); + isnt(leaf_ki_revoked1 = SecCertificateCreateFromResource(@"leaf-ki-revoked1"), NULL, "create leaf-ki-revoked1 cert"); + isnt(ca_unknown = SecCertificateCreateFromResource(@"ca-unknown"), NULL, "create ca-unknown cert"); + isnt(leaf_unknown = SecCertificateCreateFromResource(@"leaf-unknown"), NULL, "create leaf-unknown cert"); + + CFMutableArrayRef anchors=NULL; + isnt(anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create anchors array"); + if (anchors && root) { + CFArrayAppendValue(anchors, root); + } + CFCalendarRef cal = NULL; + CFAbsoluteTime at; + CFDateRef date_20180310 = NULL; // a date when our test certs would all be valid, in the absence of Valid db info + + isnt(cal = CFCalendarCreateWithIdentifier(kCFAllocatorDefault, kCFGregorianCalendar), NULL, "create calendar"); + ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2018, 3, 10), "create verify absolute time 20180310"); + isnt(date_20180310 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20180310"); + + /* Case 1: leaf_ki_ok1 */ + /* -- OK: cert issued by a known intermediate */ + test_valid_trust(leaf_ki_ok1, ca_ki, NULL, anchors, date_20180310, + kBasicPolicy, kSecTrustResultUnspecified, + "leaf_ki_ok1"); + + /* Case 2: leaf_ki_revoked1 */ + /* -- BAD: CA specifies known-only+complete serial blocklist; this cert is on the blocklist. */ + test_valid_trust(leaf_ki_revoked1, ca_ki, NULL, anchors, date_20180310, + kBasicPolicy, kSecTrustResultFatalTrustFailure, + "leaf_ki_revoked1"); + + /* Case 3: leaf_unknown */ + /* -- BAD: ca_unknown issued from ca_ki, but is not a known intermediate. + * ca_ki has a path len of 0 which would normally result in kSecTrustResultRecoverableTrustFailure; + * however, since known-intermediates is asserted for ca_ki (non-overridable), we expect a fatal failure. */ + test_valid_trust(leaf_unknown, ca_unknown, ca_ki, anchors, date_20180310, + kBasicPolicy, kSecTrustResultFatalTrustFailure, + "leaf_unknown test"); + + CFReleaseSafe(ca_ki); + CFReleaseSafe(leaf_ki_ok1); + CFReleaseSafe(leaf_ki_revoked1); + CFReleaseSafe(ca_unknown); + CFReleaseSafe(leaf_unknown); + CFReleaseSafe(root); + CFReleaseSafe(anchors); + CFReleaseSafe(cal); + CFReleaseSafe(date_20180310); +} + int si_88_sectrust_valid(int argc, char *const *argv) { - plan_tests(12+(6*8)); + plan_tests(DC_COUNT+KI_COUNT); - tests(); + date_constraints_tests(); + known_intermediate_tests(); return 0; } diff --git a/OSX/trustd/iOS/entitlements.plist b/OSX/trustd/iOS/entitlements.plist index dd43167f..125854bc 100644 --- a/OSX/trustd/iOS/entitlements.plist +++ b/OSX/trustd/iOS/entitlements.plist @@ -14,8 +14,6 @@ com.apple.private.keychain.certificates - com.apple.private.read-trustd-downloads - com.apple.private.assets.accessible-asset-types com.apple.MobileAsset.CertificatePinning diff --git a/OSX/trustd/trustd.c b/OSX/trustd/trustd.c index 2fd55127..a4d137fd 100644 --- a/OSX/trustd/trustd.c +++ b/OSX/trustd/trustd.c @@ -348,10 +348,8 @@ static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc secdebug("serverxpc", "entering"); if (type == XPC_TYPE_DICTIONARY) { - // TODO: Find out what we're dispatching. replyMessage = xpc_dictionary_create_reply(event); - uint64_t operation = xpc_dictionary_get_uint64(event, kSecXPCKeyOperation); audit_token_t auditToken = {}; @@ -409,39 +407,7 @@ static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc } else { secdebug("ipc", "%@ %@ responding %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), asyncReply); } -#if TARGET_OS_IPHONE - // Ensure that we remain dirty for two seconds after ending the client's transaction to avoid jetsam loops. - // Refer to rdar://problem/38044831 for more details. - static dispatch_queue_t dirty_timer_queue = NULL; - static dispatch_source_t dirty_timer = NULL; - static bool has_transcation = false; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - dirty_timer_queue = dispatch_queue_create("dirty timer queue", DISPATCH_QUEUE_SERIAL); - dirty_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dirty_timer_queue); - dispatch_source_set_event_handler(dirty_timer, ^{ - /* timer fired, end the transaction */ - os_assumes(has_transcation); - xpc_transaction_end(); - has_transcation = false; - }); - }); - - dispatch_sync(dirty_timer_queue, ^{ - /* reset the timer for 2 seconds from now */ - dispatch_source_set_timer(dirty_timer, dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), - DISPATCH_TIME_FOREVER, 100 * NSEC_PER_MSEC); - if (!has_transcation) { - /* timer is not running/not holding a transaction, start transaction */ - xpc_transaction_begin(); - has_transcation = true; - } - static dispatch_once_t onceToken2; - dispatch_once(&onceToken2, ^{ - dispatch_resume(dirty_timer); - }); - }); -#endif + xpc_connection_send_message(connection, asyncReply); xpc_release(asyncReply); xpc_release(connection); @@ -552,13 +518,7 @@ static void trustd_xpc_init(const char *service_name) if (xpc_get_type(connection) == XPC_TYPE_CONNECTION) { xpc_connection_set_event_handler(connection, ^(xpc_object_t event) { if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) { - xpc_retain(connection); - xpc_retain(event); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - trustd_xpc_dictionary_handler(connection, event); - xpc_release(event); - xpc_release(connection); - }); + trustd_xpc_dictionary_handler(connection, event); } }); xpc_connection_resume(connection); @@ -691,13 +651,6 @@ static void trustd_sandbox(void) { } #endif -static void trustd_cfstream_init() { - CFReadStreamRef rs = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8*) "", 0, kCFAllocatorNull); - CFReadStreamSetDispatchQueue(rs, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); - CFReadStreamSetDispatchQueue(rs, NULL); - CFRelease(rs); -} - int main(int argc, char *argv[]) { char *wait4debugger = getenv("WAIT4DEBUGGER"); @@ -744,9 +697,6 @@ int main(int argc, char *argv[]) /* set up SQLite before some other component has a chance to create a database connection */ _SecDbServerSetup(); - /* Force legacy CFStream run loop initialization before any NSURLSession usage */ - trustd_cfstream_init(); - gTrustd = &trustd_spi; /* Initialize static content */ diff --git a/OSX/utilities/Regressions/su-40-secdb.c b/OSX/utilities/Regressions/su-40-secdb.c index 4202b53b..5c3c4d13 100644 --- a/OSX/utilities/Regressions/su-40-secdb.c +++ b/OSX/utilities/Regressions/su-40-secdb.c @@ -109,7 +109,7 @@ static void tests(void) const char *home_var = getenv("HOME"); CFStringRef dbName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s/Library/Keychains/su-40-sqldb.db"), home_var ? home_var : ""); - SecDbRef db = SecDbCreate(dbName, NULL); + SecDbRef db = SecDbCreate(dbName, 0600, true, true, true, true, kSecDbMaxIdleHandles, NULL); CFReleaseNull(dbName); ok(db, "SecDbCreate"); diff --git a/OSX/utilities/Regressions/su-41-secdb-stress.c b/OSX/utilities/Regressions/su-41-secdb-stress.c index 15d9723a..b7f9c5bf 100644 --- a/OSX/utilities/Regressions/su-41-secdb-stress.c +++ b/OSX/utilities/Regressions/su-41-secdb-stress.c @@ -190,7 +190,9 @@ static void tests(void) CFStringRef dbName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s/Library/Keychains/su-41-sqldb-stress.db"), home_var ? home_var : ""); CFStringPerformWithCString(dbName, ^(const char *path) { unlink(path); }); - SecDbRef db = SecDbCreate(dbName, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool did_create, bool *callMeAgainForNextConnection, CFErrorRef *firstOpenError) { + SecDbRef db = SecDbCreate(dbName, 0600, true, true, true, true, kSecDbMaxIdleHandles, + ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool did_create, bool *callMeAgainForNextConnection, CFErrorRef *firstOpenError) + { // This test will run when the database is first opened. return ts_ok(SecDbExec(dbconn, CFSTR("CREATE TABLE tablea(key TEXT,value BLOB);"), firstOpenError), "create table: %@", *firstOpenError); diff --git a/OSX/utilities/src/SecAKSWrappers.h b/OSX/utilities/src/SecAKSWrappers.h index 86964c3d..4233c69e 100644 --- a/OSX/utilities/src/SecAKSWrappers.h +++ b/OSX/utilities/src/SecAKSWrappers.h @@ -46,7 +46,7 @@ #else #define TARGET_HAS_KEYSTORE 1 #endif -#elif TARGET_OS_EMBEDDED +#elif TARGET_OS_IPHONE #define TARGET_HAS_KEYSTORE 1 #else #error "unknown keystore status for this platform" diff --git a/OSX/utilities/src/SecAutorelease.h b/OSX/utilities/src/SecAutorelease.h new file mode 100644 index 00000000..29de9e95 --- /dev/null +++ b/OSX/utilities/src/SecAutorelease.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 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@ + */ + +#ifndef _UTILITIES_SECAUTORELEASE_H_ +#define _UTILITIES_SECAUTORELEASE_H_ + +/* Wrap a block with @autoreleasepool, suitable for use from C. */ +void SecAutoreleaseInvokeWithPool(os_block_t block); + +#endif /* !_UTILITIES_SECAUTORELEASE_H_ */ diff --git a/OSX/utilities/src/SecAutorelease.m b/OSX/utilities/src/SecAutorelease.m new file mode 100644 index 00000000..29d8f8cf --- /dev/null +++ b/OSX/utilities/src/SecAutorelease.m @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018 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@ + */ + +#include +#include "SecAutorelease.h" + +void +SecAutoreleaseInvokeWithPool(os_block_t block) +{ + @autoreleasepool { + block(); + } +} diff --git a/OSX/utilities/src/SecCFWrappers.c b/OSX/utilities/src/SecCFWrappers.c index d259a8d2..655c4f8a 100644 --- a/OSX/utilities/src/SecCFWrappers.c +++ b/OSX/utilities/src/SecCFWrappers.c @@ -39,7 +39,7 @@ CFGiblisGetSingleton(CFDictionaryRef, SecGetDebugDescriptionFormatOptions, forma }) // -// Smart comparitor for strings that matchies sorting functions +// Smart comparator for strings that matches sorting functions // CFComparisonResult CFStringCompareSafe(const void *val1, const void *val2, void *context) { @@ -51,7 +51,7 @@ CFComparisonResult CFStringCompareSafe(const void *val1, const void *val2, void return CFStringCompare(val1, val2, 0); } -void CFStringArrayPerfromWithDelimeterWithDescription(CFArrayRef strings, CFStringRef start, CFStringRef end, void (^action)(CFStringRef description)) { +void CFStringArrayPerformWithDelimiterWithDescription(CFArrayRef strings, CFStringRef start, CFStringRef end, void (^action)(CFStringRef description)) { if(!strings) { action(CFSTR("null")); } else { @@ -72,19 +72,41 @@ void CFStringArrayPerfromWithDelimeterWithDescription(CFArrayRef strings, CFStri } -void CFStringArrayPerfromWithDescription(CFArrayRef strings, void (^action)(CFStringRef description)) { - CFStringArrayPerfromWithDelimeterWithDescription(strings, CFSTR("["), CFSTR("]"), action); +void CFStringArrayPerformWithDescription(CFArrayRef strings, void (^action)(CFStringRef description)) { + CFStringArrayPerformWithDelimiterWithDescription(strings, CFSTR("["), CFSTR("]"), action); +} + +static void +appendDescriptionToArray(const void *value, void *context) +{ + CFTypeRef obj = (CFTypeRef)value; + CFMutableArrayRef array = (CFMutableArrayRef)context; + CFStringRef desc; + + if (CFGetTypeID(obj) == CFStringGetTypeID()) { + CFArrayAppendValue(array, obj); + } else { + desc = CFCopyDescription(obj); + if (desc != NULL) { + CFArrayAppendValue(array, desc); + CFRelease(desc); + } else { + CFArrayAppendValue(array, CFSTR("null")); + } + } } void CFStringSetPerformWithDescription(CFSetRef set, void (^action)(CFStringRef description)) { if(!set) { action(CFSTR("null")); } else { - CFMutableArrayRef keys = CFSetCopyValues(set); + CFMutableArrayRef keys = CFArrayCreateMutable(NULL, CFSetGetCount(set), &kCFTypeArrayCallBacks); + CFSetApplyFunction(set, appendDescriptionToArray, keys); + CFArraySortValues(keys, CFRangeMake(0, CFArrayGetCount(keys)), (CFComparatorFunction)&CFStringCompare, NULL); - CFStringArrayPerfromWithDelimeterWithDescription(keys, CFSTR("{("), CFSTR(")}"), action); + CFStringArrayPerformWithDelimiterWithDescription(keys, CFSTR("{("), CFSTR(")}"), action); CFReleaseNull(keys); } diff --git a/OSX/utilities/src/SecCFWrappers.h b/OSX/utilities/src/SecCFWrappers.h index b54b4c24..82ad991c 100644 --- a/OSX/utilities/src/SecCFWrappers.h +++ b/OSX/utilities/src/SecCFWrappers.h @@ -614,16 +614,21 @@ static inline CFMutableArrayRef CFArrayCreateDifference(CFAllocatorRef alloc, CF // static inline CFArrayRef CFArrayCreateCountedForVC(CFAllocatorRef allocator, const CFArrayCallBacks *cbs, CFIndex entries, va_list args) { - const void *values[entries ? entries : 1]; - for (CFIndex currentValue = 0; currentValue < entries; ++currentValue) - { - values[currentValue] = va_arg(args, void*); - - if (values[currentValue] == NULL) - values[currentValue] = kCFNull; + CFMutableArrayRef array = CFArrayCreateMutable(allocator, entries, cbs); + if (array == NULL) { + return NULL; + } + for (CFIndex currentValue = 0; currentValue < entries; ++currentValue) { + const void * value = va_arg(args, const void *); + if (value == NULL) { + value = kCFNull; + } + CFArrayAppendValue(array, value); } - return CFArrayCreate(allocator, values, entries, cbs); + CFArrayRef constArray = CFArrayCreateCopy(allocator, array); + CFRelease(array); + return constArray; } static inline CFArrayRef CFArrayCreateForVC(CFAllocatorRef allocator, const CFArrayCallBacks *cbs, va_list args) @@ -637,7 +642,6 @@ static inline CFArrayRef CFArrayCreateForVC(CFAllocatorRef allocator, const CFAr } return CFArrayCreateCountedForVC(allocator, cbs, entries, args); - } @@ -722,20 +726,25 @@ static void CFDictionarySetIfNonNull(CFMutableDictionaryRef dictionary, const vo static inline CFDictionaryRef CFDictionaryCreateCountedForCFTypesV(CFAllocatorRef allocator, CFIndex entries, va_list args) { - const void *keys[entries]; - const void *values[entries]; - - for(CFIndex currentValue = 0; currentValue < entries; ++currentValue) - { - keys[currentValue] = va_arg(args, void*); - values[currentValue] = va_arg(args, void*); - - if (values[currentValue] == NULL) - values[currentValue] = kCFNull; + CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(allocator, entries, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (dictionary == NULL) { + return NULL; + } + + for(CFIndex currentValue = 0; currentValue < entries; ++currentValue) { + CFTypeRef key = va_arg(args, CFTypeRef); + CFTypeRef value = va_arg(args, CFTypeRef); + if (value == NULL) { + value = kCFNull; + } + CFDictionarySetValue(dictionary, key, value); } - return CFDictionaryCreate(allocator, keys, values, entries, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryRef constDictionary = CFDictionaryCreateCopy(allocator, dictionary); + CFRelease(dictionary); + return constDictionary; } static inline CFDictionaryRef SECWRAPPER_SENTINEL CFDictionaryCreateForCFTypes(CFAllocatorRef allocator, ...) @@ -905,8 +914,8 @@ static inline void CFSetTransferObject(CFTypeRef object, CFMutableSetRef from, C // MARK: CFStringXxx Helpers // -void CFStringArrayPerfromWithDelimeterWithDescription(CFArrayRef strings, CFStringRef start, CFStringRef end, void (^action)(CFStringRef description)); -void CFStringArrayPerfromWithDescription(CFArrayRef strings, void (^action)(CFStringRef description)); +void CFStringArrayPerformWithDelimiterWithDescription(CFArrayRef strings, CFStringRef start, CFStringRef end, void (^action)(CFStringRef description)); +void CFStringArrayPerformWithDescription(CFArrayRef strings, void (^action)(CFStringRef description)); void CFStringSetPerformWithDescription(CFSetRef set, void (^action)(CFStringRef description)); // diff --git a/OSX/utilities/src/SecDb.c b/OSX/utilities/src/SecDb.c index 814cb4f1..f19f5413 100644 --- a/OSX/utilities/src/SecDb.c +++ b/OSX/utilities/src/SecDb.c @@ -37,6 +37,7 @@ #include "SecIOFormat.h" #include #include "Security/SecBase.h" +#include "SecAutorelease.h" // @@ -47,8 +48,6 @@ #include #include -#define HAVE_UNLOCK_NOTIFY 0 - struct __OpaqueSecDbStatement { CFRuntimeBase _base; @@ -91,10 +90,12 @@ struct __OpaqueSecDb { bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error); bool callOpenedHandlerForNextConnection; CFMutableArrayRef notifyPhase; /* array of SecDBNotifyBlock */ - mode_t mode; /* database file permissions, default 0600 */ - bool readWrite; /* open database read-write, default true */ - bool allowRepair; /* allow database repair, default true */ - bool useWAL; /* use WAL mode, default true */ + mode_t mode; /* database file permissions */ + bool readWrite; /* open database read-write */ + bool allowRepair; /* allow database repair */ + bool useWAL; /* use WAL mode */ + bool useRobotVacuum; /* use if SecDB should manage vacuum behind your back */ + uint8_t maxIdleHandles; void (^corruptionReset)(void); }; @@ -231,7 +232,7 @@ SecDbDestroy(CFTypeRef value) CFGiblisFor(SecDb) SecDbRef -SecDbCreateWithOptions(CFStringRef dbName, mode_t mode, bool readWrite, bool allowRepair, bool useWAL, +SecDbCreate(CFStringRef dbName, mode_t mode, bool readWrite, bool allowRepair, bool useWAL, bool useRobotVacuum, uint8_t maxIdleHandles, bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error)) { SecDbRef db = NULL; @@ -263,19 +264,14 @@ SecDbCreateWithOptions(CFStringRef dbName, mode_t mode, bool readWrite, bool all db->readWrite = readWrite; db->allowRepair = allowRepair; db->useWAL = useWAL; + db->useRobotVacuum = useRobotVacuum; + db->maxIdleHandles = maxIdleHandles; db->corruptionReset = NULL; done: return db; } -SecDbRef -SecDbCreate(CFStringRef dbName, - bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error)) -{ - return SecDbCreateWithOptions(dbName, 0600, true, true, true, opened); -} - CFIndex SecDbIdleConnectionCount(SecDbRef db) { __block CFIndex count = 0; @@ -312,7 +308,7 @@ static void SecDbNotifyPhase(SecDbConnectionRef dbconn, SecDbTransactionPhase ph } } -static void SecDbOnNotify(SecDbConnectionRef dbconn, void (^perform)()) { +static void SecDbOnNotify(SecDbConnectionRef dbconn, void (^perform)(void)) { perform(); } @@ -486,51 +482,24 @@ static bool SecDbConnectionCheckCode(SecDbConnectionRef dbconn, int code, CFErro return false; } -#if HAVE_UNLOCK_NOTIFY - -static void SecDbUnlockNotify(void **apArg, int nArg) { - int i; - for(i=0; ihandle, SecDbUnlockNotify, dsema); - assert(rc == SQLITE_LOCKED || rc == SQLITE_OK); - if (rc == SQLITE_OK) { - dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER); - } - dispatch_release(dsema); - return (rc == SQLITE_OK - ? true - : (stmt - ? SecDbErrorWithStmt(rc, stmt, error, CFSTR("sqlite3_unlock_notify")) - : SecDbErrorWithDb(rc, dbconn->handle, error, CFSTR("sqlite3_unlock_notify")))); -} - -#endif - #define BUSY_TIMEOUT_MS (5 * 60 * 1000) /* 5 minutes */ -static bool SecDbBusyHandler(SecDbConnectionRef dbconn, CFErrorRef *error) { - return SecDbErrorWithDb(sqlite3_busy_timeout(dbconn->handle, BUSY_TIMEOUT_MS), dbconn->handle, error, CFSTR("busy_handler")); -} - static int sleepBackoff[] = { 10, 20, 50, 100, 250 }; static int sumBackoff[] = { 10, 30, 80, 180, 430 }; static int NumberOfSleepBackoff = sizeof(sleepBackoff)/sizeof(sleepBackoff[0]); +// Use these as silly hacks to encode the SQLite return code in the backtrace, for hang debugging purposes +static void __attribute__((noinline)) SecDbLockSleep(int ms) { + sqlite3_sleep(ms); +} + +static void __attribute__((noinline)) SecDbBusySleep(int ms) { + sqlite3_sleep(ms); +} + // Return true causes the operation to be tried again. +// Note that we set sqlite3_busy_timeout on the connection, so anytime you're in here, it's likely due to SQLITE_LOCKED. static bool SecDbWaitIfNeeded(SecDbConnectionRef dbconn, int s3e, sqlite3_stmt *stmt, CFStringRef desc, int nTries, CFErrorRef *error) { -#if HAVE_UNLOCK_NOTIFY - if (s3e == SQLITE_LOCKED) { // Optionally check for extended code being SQLITE_LOCKED_SHAREDCACHE - return SecDbWaitForUnlockNotify(dbconn, stmt, error)) - } -#endif if (((0xFF & s3e) == SQLITE_BUSY) || ((0xFF & s3e) == SQLITE_LOCKED)) { int totaltimeout, timeout; @@ -546,7 +515,11 @@ static bool SecDbWaitIfNeeded(SecDbConnectionRef dbconn, int s3e, sqlite3_stmt * } if (totaltimeout < BUSY_TIMEOUT_MS) { secinfo("#SecDB", "sqlite busy/locked: %d ntries: %d totaltimeout: %d", s3e, nTries, totaltimeout); - sqlite3_sleep(timeout); + if(((0xFF & s3e) == SQLITE_LOCKED)) { + SecDbLockSleep(timeout); + } else { + SecDbBusySleep(timeout); + } return true; } else { secinfo("#SecDB", "sqlite busy/locked: too long: %d ms, giving up", totaltimeout); @@ -614,6 +587,61 @@ SecDbExec(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error) return ok; } +static int SecDBGetInteger(SecDbConnectionRef dbconn, CFStringRef sql) +{ + __block int number = -1; + __block CFErrorRef error = NULL; + + (void)SecDbWithSQL(dbconn, sql, &error, ^bool(sqlite3_stmt *sqlStmt) { + (void)SecDbStep(dbconn, sqlStmt, &error, ^(bool *stop) { + number = sqlite3_column_int(sqlStmt, 0); + *stop = true; + }); + return true; + }); + CFReleaseNull(error); + return number; +} + + +void SecDBManagementTasks(SecDbConnectionRef dbconn) +{ + int64_t page_count = SecDBGetInteger(dbconn, CFSTR("pragma page_count")); + if (page_count <= 0) { + return; + } + int64_t free_count = SecDBGetInteger(dbconn, CFSTR("pragma freelist_count")); + if (free_count < 0) { + return; + } + + int64_t max_free = 8192; + + int64_t pages_in_use = page_count - free_count; + double loadFactor = ((double)pages_in_use/(double)page_count); + if (0.85 < loadFactor && free_count < max_free) { + /* no work yet */ + } else { + int64_t pages_to_free = (int64_t)(0.2 * free_count); + if (0.4 > loadFactor) { + pages_to_free = free_count; + } + + char *formatString = NULL; + asprintf(&formatString, "pragma incremental_vacuum(%d)", (int)pages_to_free); + if (formatString) { + char *sqlerror = NULL; + int rc = sqlite3_exec(dbconn->handle, formatString, NULL, NULL, &sqlerror); + if (rc) { + secerror("incremental_vacuum failed with: (%d) %{public}s", rc, sqlerror); + } + sqlite3_free(sqlerror); + free(formatString); + } + } +} + + static bool SecDbBeginTransaction(SecDbConnectionRef dbconn, SecDbTransactionType type, CFErrorRef *error) { bool ok = true; @@ -677,6 +705,10 @@ static bool SecDbEndTransaction(SecDbConnectionRef dbconn, bool commit, CFErrorR SecDbNotifyPhase(dbconn, commited ? kSecDbTransactionDidCommit : kSecDbTransactionDidRollback); secdebug("db", "SecDbEndTransaction %s %p", commited ? "kSecDbTransactionDidCommit" : "kSecDbTransactionDidRollback", dbconn); dbconn->source = kSecDbAPITransaction; + + if (commit && dbconn->db->useRobotVacuum) { + SecDBManagementTasks(dbconn); + } }; SecDbPerformOnCommitQueue(dbconn, true, notifyAndExec); @@ -719,8 +751,10 @@ bool SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, case kSecDbRowStep: secdebug("db", "kSecDbRowStep %@", error?*error:NULL); if (row) { - bool stop = false; - row(&stop); + __block bool stop = false; + SecAutoreleaseInvokeWithPool(^{ + row(&stop); + }); if (stop) return true; break; @@ -743,10 +777,11 @@ static bool SecDbFileControl(SecDbConnectionRef dbconn, int op, void *arg, CFErr return SecDbConnectionCheckCode(dbconn, sqlite3_file_control(dbconn->handle, NULL, op, arg), error, CFSTR("file_control")); } -static sqlite3 *_SecDbOpenV2(const char *path, int flags, CFErrorRef *error) { -#if HAVE_UNLOCK_NOTIFY - flags |= SQLITE_OPEN_SHAREDCACHE; -#endif +static sqlite3 *_SecDbOpenV2(const char *path, + int flags, + int useWAL, + int useRobotVacuum, + CFErrorRef *error) { sqlite3 *handle = NULL; int s3e = sqlite3_open_v2(path, &handle, flags, NULL); if (s3e) { @@ -757,12 +792,44 @@ static sqlite3 *_SecDbOpenV2(const char *path, int flags, CFErrorRef *error) { } else { SecDbError(s3e, error, CFSTR("open_v2 \"%s\" 0x%X"), path, flags); } + } else if (SQLITE_OPEN_READWRITE == (flags & SQLITE_OPEN_READWRITE)) { + if (useRobotVacuum) { +#define SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL 2 + sqlite3_stmt *stmt; + int vacuumMode = -1; + + /* + * Setting auto_vacuum = incremental on a database that is not empty requires + * a VACCUUM, so check if the vacuum mode is not INCREMENTAL, and if its not, + * set it to incremental and vacuum. + */ + + int s3e = sqlite3_prepare_v2(handle, "PRAGMA auto_vacuum", -1, &stmt, NULL); + if (s3e == 0) { + s3e = sqlite3_step(stmt); + if (s3e == SQLITE_ROW) { + vacuumMode = sqlite3_column_int(stmt, 0); + } + sqlite3_reset(stmt); + } + + if (vacuumMode != SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL) { + (void)sqlite3_exec(handle, "PRAGMA auto_vacuum = incremental", NULL, NULL, NULL); + (void)sqlite3_exec(handle, "VACUUM", NULL, NULL, NULL); + } + } + if (useWAL) { + (void)sqlite3_exec(handle, "PRAGMA journal_mode = WAL", NULL, NULL, NULL); + } + + // Let SQLite handle timeouts. + sqlite3_busy_timeout(handle, 5*1000); } return handle; } static bool SecDbOpenV2(SecDbConnectionRef dbconn, const char *path, int flags, CFErrorRef *error) { - return (dbconn->handle = _SecDbOpenV2(path, flags, error)) != NULL; + return (dbconn->handle = _SecDbOpenV2(path, flags, dbconn->db->useWAL, dbconn->db->useRobotVacuum, error)) != NULL; } static bool SecDbTruncate(SecDbConnectionRef dbconn, CFErrorRef *error) @@ -806,7 +873,7 @@ static bool SecDbHandleCorrupt(SecDbConnectionRef dbconn, int rc, CFErrorRef *er sqlite3 *corrupt_db = NULL; char buf[PATH_MAX+1]; snprintf(buf, sizeof(buf), "%s-corrupt", db_path); - if (dbconn->handle && (corrupt_db = _SecDbOpenV2(buf, SQLITE_OPEN_READWRITE, error))) { + if (dbconn->handle && (corrupt_db = _SecDbOpenV2(buf, SQLITE_OPEN_READWRITE, dbconn->db->useWAL, dbconn->db->useRobotVacuum, error))) { int on = 1; didRename = SecDbErrorWithDb(sqlite3_file_control(corrupt_db, NULL, SQLITE_FCNTL_PERSIST_WAL, &on), corrupt_db, error, CFSTR("persist wal")); didRename &= SecDbErrorWithDb(sqlite3_file_control(corrupt_db, NULL, SQLITE_REPLACE_DATABASE, (void *)dbconn->handle), corrupt_db, error, CFSTR("replace database")); @@ -994,8 +1061,6 @@ static bool SecDbOpenHandle(SecDbConnectionRef dbconn, bool *created, CFErrorRef dbconn); } } - - ok = ok && SecDbBusyHandler(dbconn, error); }); return ok; @@ -1156,7 +1221,7 @@ void SecDbConnectionRelease(SecDbConnectionRef dbconn) { // Add back possible writable dbconn to the pool. CFArrayInsertValueAtIndex(db->connections, readOnly ? count : 0, dbconn); // Remove the last (probably read-only) dbconn from the pool. - if (count >= kSecDbMaxIdleHandles) { + if (count >= db->maxIdleHandles) { CFArrayRemoveValueAtIndex(db->connections, count); } } @@ -1180,65 +1245,6 @@ void SecDbReleaseAllConnections(SecDbRef db) { }); } -bool SecDbReplace(SecDbRef db, CFStringRef newDbPath, CFErrorRef *error) { - // Replace the given database with the contents of the database - // at newDbPath, as an atomic operation on db->queue. - - __block bool result = false; - if (!db || !newDbPath) { - secerror("called with NULL argument"); - return result; - } - dispatch_sync(db->queue, ^{ - // Explicitly close all database connections - CFIndex idx, count = (db->connections) ? CFArrayGetCount(db->connections) : 0; - for (idx = 0; idx < count; idx++) { - SecDbConnectionRef dbconn = (SecDbConnectionRef) CFArrayGetValueAtIndex(db->connections, idx); - if (dbconn->handle) { - sqlite3_close(dbconn->handle); - dbconn->handle = NULL; - } - } - CFArrayRemoveAllValues(db->connections); - - __block sqlite3 *old_db = NULL; - __block sqlite3 *new_db = NULL; - CFStringPerformWithCString(db->db_path, ^(const char *db_path) { - int s3e = sqlite3_open_v2(db_path, &old_db, SQLITE_OPEN_READWRITE, NULL); - if (SQLITE_OK != s3e) { - secerror("Unable to open db for writing: %s (error %d)", db_path, s3e); - } - }); - CFStringPerformWithCString(newDbPath, ^(const char *new_db_path) { - int s3e = sqlite3_open_v2(new_db_path, &new_db, SQLITE_OPEN_READONLY, NULL); - if (SQLITE_OK != s3e) { - secerror("Unable to open db for reading: %s (error %d)", new_db_path, s3e); - } - }); - if (old_db && new_db) { - // Replace old_db with contents of new_db - int s3e = sqlite3_file_control(old_db, NULL, SQLITE_FCNTL_REPLACE_DATABASE, new_db); - if (SQLITE_OK != s3e) { - secerror("Unable to replace db: %@ (error %d)", db->db_path, s3e); - } else { - result = true; - } - } - if (old_db) { - sqlite3_close(old_db); - } - if (new_db) { - sqlite3_close(new_db); - } - - // Signal that connections are available again. - dispatch_semaphore_signal(db->write_semaphore); - dispatch_semaphore_signal(db->read_semaphore); - }); - - return result; -} - bool SecDbPerformRead(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn)) { SecDbConnectionRef dbconn = SecDbConnectionAcquire(db, true, error); bool success = false; diff --git a/OSX/utilities/src/SecDb.h b/OSX/utilities/src/SecDb.h index 1e86e10d..598374c4 100644 --- a/OSX/utilities/src/SecDb.h +++ b/OSX/utilities/src/SecDb.h @@ -102,9 +102,10 @@ typedef void (^SecDBNotifyBlock)(SecDbConnectionRef dbconn, SecDbTransactionPhas CFTypeID SecDbGetTypeID(void); // Database creation -SecDbRef SecDbCreateWithOptions(CFStringRef dbName, mode_t mode, bool readWrite, bool allowRepair, bool useWAL, bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error)); - -SecDbRef SecDbCreate(CFStringRef dbName, bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error)); +SecDbRef +SecDbCreate(CFStringRef dbName, mode_t mode, + bool readWrite, bool allowRepair, bool useWAL, bool useRobotVacuum, uint8_t maxIdleHandles, + bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error)); void SecDbAddNotifyPhaseBlock(SecDbRef db, SecDBNotifyBlock notifyPhase); void SecDbSetCorruptionReset(SecDbRef db, void (^corruptionReset)(void)); @@ -123,7 +124,6 @@ bool SecDbPerformWrite(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConn // TODO: DEBUG only -> Private header CFIndex SecDbIdleConnectionCount(SecDbRef db); void SecDbReleaseAllConnections(SecDbRef db); -bool SecDbReplace(SecDbRef db, CFStringRef newDbPath, CFErrorRef *error); CFStringRef SecDbGetPath(SecDbRef db); @@ -149,6 +149,7 @@ sqlite3 *SecDbHandle(SecDbConnectionRef dbconn); void SecDbRecordChange(SecDbConnectionRef dbconn, CFTypeRef deleted, CFTypeRef inserted); void SecDbPerformOnCommitQueue(SecDbConnectionRef dbconn, bool barrier, dispatch_block_t perform); +void SecDBManagementTasks(SecDbConnectionRef dbconn); // MARK: - // MARK: Bind helpers diff --git a/OSX/utilities/src/SecPLWrappers.m b/OSX/utilities/src/SecPLWrappers.m index 5bdd94bc..d4e915b4 100644 --- a/OSX/utilities/src/SecPLWrappers.m +++ b/OSX/utilities/src/SecPLWrappers.m @@ -25,7 +25,7 @@ #include #include "SecPLWrappers.h" -#if TARGET_OS_EMBEDDED +#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE #include static typeof(PLShouldLogRegisteredEvent) *soft_PLShouldLogRegisteredEvent = NULL; @@ -68,7 +68,7 @@ setup(void) bool SecPLShouldLogRegisteredEvent(NSString *event) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE if (setup()) return soft_PLShouldLogRegisteredEvent(PLClientIDSecurity, (__bridge CFStringRef)event); #endif @@ -77,7 +77,7 @@ bool SecPLShouldLogRegisteredEvent(NSString *event) void SecPLLogRegisteredEvent(NSString *eventName, NSDictionary *eventDictionary) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE if (setup()) soft_PLLogRegisteredEvent(PLClientIDSecurity, (__bridge CFStringRef)eventName, @@ -88,7 +88,7 @@ void SecPLLogRegisteredEvent(NSString *eventName, NSDictionary *eventDictionary) void SecPLLogTimeSensitiveRegisteredEvent(NSString *eventName, NSDictionary *eventDictionary) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE if (setup()) soft_PLLogTimeSensitiveRegisteredEvent(PLClientIDSecurity, (__bridge CFStringRef)eventName, diff --git a/RegressionTests/Security.plist b/RegressionTests/Security.plist index 4db898f3..c9fde58c 100644 --- a/RegressionTests/Security.plist +++ b/RegressionTests/Security.plist @@ -68,10 +68,38 @@ TestName secitemfunctionality + EnableEasyperf + + EasyperfArgs + + -p + secd + + Command + + /AppleInternal/CoreOS/tests/Security/secitemfunctionality + + EligibleResource + type != 'CAMEmbeddedDeviceResource' + + + TestName + secitemfunctionality + EnableEasyperf + + EasyperfArgs + + -p + securityd + + AsRoot + Command /AppleInternal/CoreOS/tests/Security/secitemfunctionality + EligibleResource + type == 'CAMEmbeddedDeviceResource' TestName @@ -135,17 +163,59 @@ /AppleInternal/CoreOS/tests/Security/authdtest EligibleResource - NOT (cpuArchitecture BEGINSWITH 'arm') - - - TestName - KeychainAnalytics - Command - - BATS_XCTEST_CMD - /AppleInternal/XCTests/com.apple.security/KeychainAnalyticsTests.xctest - - + type != 'CAMEmbeddedDeviceResource' + + + TestName + KeychainAnalyticsTests + Command + + BATS_XCTEST_CMD + /AppleInternal/XCTests/com.apple.security/KeychainAnalyticsTests.xctest + + + + TestName + KeychainMockAKSTests + Command + + BATS_XCTEST_CMD + /AppleInternal/XCTests/com.apple.security/secdmockaks.xctest + + + + TestName + MultiDeviceSimulatorTests + Command + + BATS_XCTEST_CMD + /AppleInternal/XCTests/com.apple.security/MultiDeviceSimulatorTests.xctest + + EligibleResource + type != 'CAMEmbeddedDeviceResource' + + + TestName + KeychainSecd_macOS + Command + + BATS_XCTEST_CMD + /AppleInternal/XCTests/com.apple.security/secdxctests_mac.xctest + + EligibleResource + type != 'CAMEmbeddedDeviceResource' + + + TestName + KeychainSecd_iOS + Command + + BATS_XCTEST_CMD + /AppleInternal/XCTests/com.apple.security/secdxctests_ios.xctest + + EligibleResource + type == 'CAMEmbeddedDeviceResource' + diff --git a/RegressionTests/SecurityInduceLowDisk.plist b/RegressionTests/SecurityInduceLowDisk.plist new file mode 100644 index 00000000..92d28113 --- /dev/null +++ b/RegressionTests/SecurityInduceLowDisk.plist @@ -0,0 +1,44 @@ + + + + + BATSConfigVersion + 0.1.0 + Project + Security + Condition + + ConditionName + LowDiskCondition + ConditionProfile + LowDiskConditionPrevailingExceedingLowThresholdNonCached + + Tests + + + TestName + secitemstresstest + Command + + /AppleInternal/CoreOS/tests/Security/secitemstresstest + + + + TestName + secitemnotifications + Command + + /AppleInternal/CoreOS/tests/Security/secitemnotifications + + + + TestName + secitemfunctionality + Command + + /AppleInternal/CoreOS/tests/Security/secitemfunctionality + + + + + diff --git a/RegressionTests/secitemcanarytest/secitemcanarytest.entitlements b/RegressionTests/secitemcanarytest/secitemcanarytest.entitlements new file mode 100644 index 00000000..011c037d --- /dev/null +++ b/RegressionTests/secitemcanarytest/secitemcanarytest.entitlements @@ -0,0 +1,10 @@ + + + + + keychain-access-groups + + com.apple.security.test.canary + + + diff --git a/RegressionTests/secitemcanarytest/secitemcanarytest.m b/RegressionTests/secitemcanarytest/secitemcanarytest.m new file mode 100644 index 00000000..bc496868 --- /dev/null +++ b/RegressionTests/secitemcanarytest/secitemcanarytest.m @@ -0,0 +1,238 @@ +#include +#include +#include +#include + +static void usage(void) __dead2; +static bool create_item(NSString *acct); +static bool verify_item(NSString *acct, bool deleteit); +static void initial_state(void) __dead2; +static uint64_t update_state(void); +static void reset(void) __dead2; + +static NSString *kCanaryAccessGroup = @"com.apple.security.test.canary"; +static NSString *kCanaryStateAccount = @"com.apple.security.test.canaryState"; + +int +main(int argc, char *argv[]) +{ + int ch; + uint64_t iter; + bool success; + + iter = 0; + while ((ch = getopt(argc, argv, "ir")) != -1) { + switch (ch) { + case 'i': + initial_state(); + /*notreached*/ + case 'r': + reset(); + /*notreached*/ + default: + usage(); + /*notreached*/ + } + } + + iter = update_state(); + fprintf(stderr, "iter = %llu\n\n", iter); + + @autoreleasepool { + if (iter > 0) { + printf("[TEST] Verify and delete previous canary item\n"); + success = verify_item([NSString stringWithFormat:@"canary%llu", iter - 1], true); + printf("[%s]\n", success ? "PASS" : "FAIL"); + fprintf(stderr, "\n"); + } + + printf("[TEST] Create canary item\n"); + success = create_item([NSString stringWithFormat:@"canary%llu", iter]); + printf("[%s]\n", success ? "PASS" : "FAIL"); + } +} + +static void +usage(void) +{ + + fprintf(stderr, "usage: secitemcanarytest -i Generate initial state\n" + " secitemcanarytest Normal operation\n" + " secitemcanarytest -r Reset everything\n"); + exit(1); +} + +static bool +create_item(NSString *acct) +{ + OSStatus status; + NSDictionary *attrs; + int nerrors = 0; + + attrs = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrLabel : @"secitemcanarytest-oneItem", + (id)kSecAttrAccount : acct, + (id)kSecAttrAccessGroup : kCanaryAccessGroup, + (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, + (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecValueData : [NSData dataWithBytes:"password" length: 8], + }; + status = SecItemAdd((__bridge CFDictionaryRef)attrs, NULL); + if (status != 0) { + nerrors++; + fprintf(stderr, "SecItemAdd(%s): %d\n", acct.UTF8String, status); + } else { + printf("created: %s\n", acct.UTF8String); + } + + if (!verify_item(acct, false)) { + nerrors++; + } + + return (nerrors == 0); +} + +static bool +verify_item(NSString *acct, bool deleteit) +{ + OSStatus status; + NSDictionary *query; + CFTypeRef result; + int nerrors = 0; + + query = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccessGroup : kCanaryAccessGroup, + (id)kSecAttrAccount : acct, + (id)kSecReturnAttributes : @YES, + (id)kSecMatchLimit : (id)kSecMatchLimitAll, + (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + }; + result = NULL; + status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + if (status != 0) { + nerrors++; + fprintf(stderr, "SecItemCopyMatching(%s): %d\n", acct.UTF8String, status); + } else { + if (CFGetTypeID(result) != CFArrayGetTypeID()) { + nerrors++; + fprintf(stderr, "SecItemCopyMatching(%s): not array\n", acct.UTF8String); + } else if (CFArrayGetCount(result) != 1) { + nerrors++; + fprintf(stderr, "SecItemCopyMatching(%s): incorrect number of results\n", acct.UTF8String); + } else { + printf("verified: %s\n", acct.UTF8String); + } + CFRelease(result); + } + + if (deleteit) { + status = SecItemDelete((__bridge CFDictionaryRef)query); + if (status != 0) { + nerrors++; + fprintf(stderr, "SecItemDelete(%s): %d\n", acct.UTF8String, status); + } else { + printf("deleted: %s\n", acct.UTF8String); + } + } + + return (nerrors == 0); +} + +static void +initial_state(void) +{ + OSStatus status; + uint64_t state; + NSDictionary *attrs; + + state = 0; + attrs = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrLabel : @"canary test state", + (id)kSecAttrAccount : kCanaryStateAccount, + (id)kSecAttrAccessGroup : kCanaryAccessGroup, + (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, + (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecValueData : [NSData dataWithBytes:&state length:sizeof(state)], + }; + status = SecItemAdd((__bridge CFDictionaryRef)attrs, NULL); + switch (status) { + case 0: + exit(0); + /*notreached*/ + default: + errx(1, "SecItemAdd: %d", status); + /*notreached*/ + } +} + +static uint64_t +update_state(void) +{ + OSStatus status; + NSMutableDictionary *query; + NSDictionary *update; + CFTypeRef result; + uint64_t state = 0, next_state; + + query = [NSMutableDictionary dictionary]; + query[(id)kSecClass] = (id)kSecClassGenericPassword; + query[(id)kSecAttrAccessGroup] = kCanaryAccessGroup; + query[(id)kSecAttrAccount] = kCanaryStateAccount; + query[(id)kSecAttrNoLegacy] = (id)kCFBooleanTrue; + query[(id)kSecReturnData] = @YES; + + status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + switch (status) { + case 0: + if (result != NULL && CFGetTypeID(result) == CFDataGetTypeID() && CFDataGetLength(result) == sizeof(state)) { + memcpy(&state, CFDataGetBytePtr(result), sizeof(state)); + } else { + errx(1, "invalid state"); + /*notreached*/ + } + break; + default: + errx(1, "failed to retrieve state: SecItemCopyMatching(state): %d", status); + /*notreached*/ + } + + next_state = state + 1; + + query[(id)kSecReturnData] = nil; + update = @{ + (id)kSecValueData : [NSData dataWithBytes:&next_state length:sizeof(next_state)], + }; + status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)update); + + if (status != 0) { + errx(1, "SecItemUpdate: %d", status); + } + + return state; +} + +static void +reset(void) +{ + OSStatus status; + NSDictionary *query; + + query = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccessGroup : kCanaryAccessGroup, + (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + }; + status = SecItemDelete((__bridge CFDictionaryRef)query); + switch (status) { + case 0: + case errSecItemNotFound: + exit(0); + /*notreached*/ + default: + errx(1, "SecItemDelete: %d", status); + /*notreached*/ + } +} diff --git a/SOSCCAuthPlugin/SOSCCAuthPlugin.m b/SOSCCAuthPlugin/SOSCCAuthPlugin.m index e6dd747a..744fde2b 100644 --- a/SOSCCAuthPlugin/SOSCCAuthPlugin.m +++ b/SOSCCAuthPlugin/SOSCCAuthPlugin.m @@ -22,11 +22,38 @@ #if !TARGET_OS_SIMULATOR SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wstrict-prototypes" SOFT_LINK_CLASS(AuthKit, AKAccountManager); +#pragma clang diagnostic pop #endif @implementation SOSCCAuthPlugin +static bool accountIsHSA2(ACAccount *account) { + bool hsa2 = false; + +#if !TARGET_OS_SIMULATOR + AKAccountManager *manager = [getAKAccountManagerClass() sharedInstance]; + if(manager != nil) { +#if TARGET_OS_OSX + ACAccount *aka = [manager authKitAccountWithAltDSID:account.icaAltDSID]; +#else + ACAccount *aka = [manager authKitAccountWithAltDSID:account.aa_altDSID]; +#endif + if (aka) { + AKAppleIDSecurityLevel securityLevel = [manager securityLevelForAccount: aka]; + if(securityLevel == AKAppleIDSecurityLevelHSA2) { + hsa2 = true; + } + } + } +#endif + secnotice("accounts", "Account %s HSA2", (hsa2) ? "is": "isn't" ); + return hsa2; +} + - (void) didReceiveAuthenticationResponseParameters: (NSDictionary *) parameters accountStore: (ACDAccountStore *) store account: (ACAccount *) account @@ -47,43 +74,36 @@ SOFT_LINK_CLASS(AuthKit, AKAccountManager); do_auth = [account aa_isPrimaryAccount]; } -#if !TARGET_OS_SIMULATOR - // If this is an HSA2 account let cdpd SetCreds - AKAccountManager *manager = [getAKAccountManagerClass() sharedInstance]; - if(manager != nil) { - AKAppleIDSecurityLevel securityLevel = [manager securityLevelForAccount: account]; - if(securityLevel == AKAppleIDSecurityLevelHSA2) { - secnotice("accounts", "Not performing SOSCCSetUserCredentialsAndDSID in accountsd plugin since we're HSA2" ); - do_auth = NO; - } - } else { - secnotice("accounts", "Couldn't softlink AKAccountManager - proceeding with do_auth = %@", do_auth ? @"YES" : @"NO"); - } -#endif - - secnotice("accounts", "do_auth %@", do_auth ? @"YES" : @"NO" ); - - if (do_auth) { - CFErrorRef authError = NULL; + if(do_auth && !accountIsHSA2(account)) { NSString *rawPassword = [account _aa_rawPassword]; if (rawPassword != NULL) { - const char *password = [rawPassword cStringUsingEncoding:NSUTF8StringEncoding]; - CFDataRef passwordData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *) password, strlen(password)); - if (passwordData) { - secinfo("accounts", "Performing SOS circle credential set for account %@: %@", accountIdentifier, account.username); - NSString *dsid = [account aa_personID]; - if (!SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef) account.username, passwordData, (__bridge CFStringRef) dsid, &authError)) { - secerror("Unable to set SOS circle credentials for account %@: %@", accountIdentifier, authError); - CFReleaseNull(authError); - } + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + CFErrorRef asyncError = NULL; + NSString *dsid = [account aa_personID]; + const char *password = [rawPassword cStringUsingEncoding:NSUTF8StringEncoding]; + CFDataRef passwordData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *) password, strlen(password)); - CFRelease(passwordData); - } + if (passwordData) { + secinfo("accounts", "Performing async SOS circle credential set for account %@: %@", accountIdentifier, account.username); + + if (!SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef) account.username, passwordData, (__bridge CFStringRef) dsid, &asyncError)) { + secerror("Unable to set SOS circle credentials for account %@: %@", accountIdentifier, asyncError); + secinfo("accounts", "Returning from failed async call to SOSCCSetUserCredentialsAndDSID"); + CFReleaseNull(asyncError); + } else { + secinfo("accounts", "Returning from successful async call to SOSCCSetUserCredentialsAndDSID"); + } + CFRelease(passwordData); + } else { + secinfo("accounts", "Failed to create string for call to SOSCCSetUserCredentialsAndDSID"); + } + }); } else { + CFErrorRef authError = NULL; if (!SOSCCCanAuthenticate(&authError)) { secerror("Account %@ did not present a password and we could not authenticate the SOS circle: %@", accountIdentifier, authError); - CFReleaseNull(authError); // CFReleaseSafe? + CFReleaseNull(authError); } } } else { diff --git a/Security.exp-in b/Security.exp-in index 2eb7fe59..80c70e6c 100644 --- a/Security.exp-in +++ b/Security.exp-in @@ -1,5 +1,7 @@ #include +_kSecFrameworkBundleID + #include "Security/SecExports.exp-in" #include "Security/SecAccessControlExports.exp-in" #include "Security/SecureObjectSync/SOSExports.exp-in" @@ -317,7 +319,7 @@ _OBJC_CLASS_$_SecuritydXPCClient #endif #if __OBJC2__ && (TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__)) -_OBJC_CLASS_$_SFTransactionMetric +_OBJC_CLASS_$_SFSignInAnalytics #endif //__OBJC2__ && IPHONE || OSX _OTSetupControlProtocol @@ -337,6 +339,7 @@ _securityd_create_message _securityd_message_with_reply_sync _securityd_message_no_error _securityd_send_sync_and_do +_securityd_send_async_and_do #if TARGET_OS_IOS _SecSecuritySetMusrMode #endif @@ -414,6 +417,7 @@ _CMSEncoderAddSignedAttributes _CMSEncoderSetSigningTime _CMSEncoderSetAppleCodesigningHashAgility _CMSEncoderSetAppleCodesigningHashAgilityV2 +_CMSEncoderSetAppleExpirationTime _CMSEncoderSetCertificateChainMode _CMSEncoderGetCertificateChainMode _CMSEncoderUpdateContent @@ -444,6 +448,7 @@ _CMSEncoderCopySignerTimestamp _CMSEncoderCopySignerTimestampWithPolicy _CMSDecoderCopySignerAppleCodesigningHashAgility _CMSDecoderCopySignerAppleCodesigningHashAgilityV2 +_CMSDecoderCopySignerAppleExpirationTime #endif // TARGET_OS_OSX #if TARGET_OS_OSX @@ -1538,6 +1543,7 @@ _kSecCodeSignerRequireTimestamp _kSecCodeSignerTeamIdentifier _kSecCodeSignerPlatformIdentifier _kSecCodeSignerRuntimeVersion +_kSecCodeSignerPreserveAFSC _kSecCodeSignerTimestampServer _kSecCodeSignerTimestampAuthentication _kSecCodeSignerTimestampOmitCertificates @@ -1575,6 +1581,7 @@ _kSecCodeInfoDiskRepVersionPlatform _kSecCodeInfoDiskRepVersionMin _kSecCodeInfoDiskRepVersionSDK _kSecCodeInfoResourceDirectory +_kSecCodeInfoNotarizationDate _kSecGuestAttributeCanonical _kSecGuestAttributeDynamicCode _kSecGuestAttributeDynamicCodeInfoPlist @@ -1587,6 +1594,8 @@ _kSecGuestAttributeAudit _kSecRequirementKeyInfoPlist _kSecRequirementKeyEntitlements _kSecRequirementKeyIdentifier +_kSecRequirementKeyPackageChecksum +_kSecRequirementKeyChecksumAlgorithm _kSecCFErrorArchitecture _kSecCFErrorPath _kSecCFErrorPattern @@ -1607,6 +1616,8 @@ _SecAssessmentUpdate _SecAssessmentCopyUpdate _SecAssessmentControl _SecAssessmentGetTypeID +_SecAssessmentTicketLookup +_SecAssessmentTicketRegister _kSecAssessmentContextKeyOperation _kSecAssessmentOperationTypeExecute _kSecAssessmentOperationTypeInstall @@ -1642,6 +1653,7 @@ _kSecAssessmentAssessmentSource _kSecAssessmentAssessmentVerdict _kSecAssessmentAssessmentWeakSignature _kSecAssessmentAssessmentCodeSigningError +_kSecAssessmentAssessmentNotarizationDate _kSecAssessmentRuleKeyID _kSecAssessmentRuleKeyPriority _kSecAssessmentRuleKeyAllow @@ -1672,8 +1684,11 @@ _SecCodeGetTypeID _SecCodeMapMemory _SecCodeSetStatus _SecCodeValidateFileResource +#endif // TARGET_OS_IPHONE + _SecCopyLastError +#if TARGET_OS_IPHONE _SecRequirementCopyData _SecRequirementCopyString _SecRequirementCreateWithData @@ -1711,6 +1726,7 @@ _kSecCodeInfoFlags _kSecCodeInfoFormat _kSecCodeInfoImplicitDesignatedRequirement _kSecCodeInfoMainExecutable +_kSecCodeInfoNotarizationDate _kSecCodeInfoPList _kSecCodeInfoPlatformIdentifier _kSecCodeInfoRequirementData @@ -1954,6 +1970,7 @@ _OBJC_CLASS_$_SFAnalyticsActivityTracker _OBJC_CLASS_$_SFAnalyticsMultiSampler _OBJC_CLASS_$_SFAnalyticsSampler _OBJC_CLASS_$_SFAnalyticsSQLiteStore +_OBJC_METACLASS_$_SFSignInAnalytics _SFAnalyticsMaxEventsToReport _SFSQLiteJournalSuffixes _SFAnalyticsSamplerIntervalOncePerReport @@ -1978,6 +1995,7 @@ _SFAnalyticsAttributeErrorDomain _SFAnalyticsAttributeErrorUnderlyingChain _SFAnalyticsTopicKeySync _SFAnaltyicsTopicTrust +_SFAnalyticsErrorDomain _OBJC_CLASS_$_SOSAnalytics _CKDKVSPerformanceCountersSampler @@ -1988,9 +2006,17 @@ _CKDKVSPerfCounterOutgoingMessages _CKDKVSPerfCounterTotalWaitTimeSynchronize _CKDKVSPerfCounterLongestWaitTimeSynchronize _CKDKVSPerfCounterSynchronizeFailures + +_OBJC_CLASS_$_LocalKeychainAnalytics +_LKAEventUpgrade #endif // __OBJC2__ +_LKAReportKeychainUpgradeOutcome +_LKAReportKeychainUpgradeOutcomeWithError + +// // Padding +// _SecPaddingCompute // diff --git a/Security.xcodeproj/project.pbxproj b/Security.xcodeproj/project.pbxproj index 3e7f0bac..cb162682 100644 --- a/Security.xcodeproj/project.pbxproj +++ b/Security.xcodeproj/project.pbxproj @@ -36,6 +36,7 @@ buildPhases = ( ); dependencies = ( + 47C2F1902059CBFC0062DE30 /* PBXTargetDependency */, 0C78CCE51FCC97E7008B4B24 /* PBXTargetDependency */, F621D0831ED6ED5B000EA569 /* PBXTargetDependency */, 6C24EF4A1E415109000DE79F /* PBXTargetDependency */, @@ -60,7 +61,6 @@ DC61096B1D78E60C002223DE /* PBXTargetDependency */, EBD849361B242C8900C5FD1E /* PBXTargetDependency */, E74583BE1BF66489001B54A4 /* PBXTargetDependency */, - E7E7B24B1BFC0CD900B1E66B /* PBXTargetDependency */, EB31EA831D3EF2FB008F952A /* PBXTargetDependency */, DA30D6821DF8C93500EC6B43 /* PBXTargetDependency */, EBC15EA91BE29AC3001C0C5B /* PBXTargetDependency */, @@ -72,6 +72,8 @@ 6CAA8D3F1F8431C9007B6E03 /* PBXTargetDependency */, 6CAA8CE91F82FD13007B6E03 /* PBXTargetDependency */, DC5225001E40295C0021640A /* PBXTargetDependency */, + EB636BD320992DB400C1E21A /* PBXTargetDependency */, + EB11965A20A6300600BFDA1B /* PBXTargetDependency */, 6C7C38811FD88C4700DFFE68 /* PBXTargetDependency */, ); name = Security_executables_osx; @@ -112,12 +114,26 @@ name = Security_frameworks_ios; productName = kernel; }; + 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 4809F7AC2061B697003E72D0 /* Build configuration list for PBXAggregateTarget "MultiPeerSimulatorTests" */; + buildPhases = ( + ); + dependencies = ( + 4809F7AE2061B6AA003E72D0 /* PBXTargetDependency */, + 4809F7B02061B6B0003E72D0 /* PBXTargetDependency */, + ); + name = MultiPeerSimulatorTests; + productName = MultiPeerSimulatorTests; + }; 4C541F840F250BF500E508AE /* Security_executables_ios */ = { isa = PBXAggregateTarget; buildConfigurationList = 4C541FA30F250C8C00E508AE /* Build configuration list for PBXAggregateTarget "Security_executables_ios" */; buildPhases = ( ); dependencies = ( + 4771D982209A76B100BA9772 /* PBXTargetDependency */, + 47C2F18C2059CBEA0062DE30 /* PBXTargetDependency */, 0C78CCE71FCC97F1008B4B24 /* PBXTargetDependency */, D41257F11E941E7D00781F23 /* PBXTargetDependency */, EB27FF281E40717400EC9E3A /* PBXTargetDependency */, @@ -135,7 +151,6 @@ 0C99B740131C984900584CF4 /* PBXTargetDependency */, 0CC827F2138712B100BD99B7 /* PBXTargetDependency */, 52D82BF616A627100078DFE5 /* PBXTargetDependency */, - CD0637811A840C6400C81E74 /* PBXTargetDependency */, 4C52D0EE16EFCD720079966E /* PBXTargetDependency */, BE197F631911742900BA91D1 /* PBXTargetDependency */, BE4AC9B418B8020400B84964 /* PBXTargetDependency */, @@ -150,6 +165,8 @@ 6CAA8D3D1F8431BC007B6E03 /* PBXTargetDependency */, 6CAA8CE51F82FD08007B6E03 /* PBXTargetDependency */, 6C7C38881FD88C5A00DFFE68 /* PBXTargetDependency */, + EB636BCA20992D8900C1E21A /* PBXTargetDependency */, + EB11965C20A6301100BFDA1B /* PBXTargetDependency */, ); name = Security_executables_ios; productName = phase2; @@ -185,6 +202,8 @@ buildPhases = ( ); dependencies = ( + EB8910FE20E06DF500DE533F /* PBXTargetDependency */, + 47C2F1922059CC040062DE30 /* PBXTargetDependency */, BE061EB91EE5EBA000B22118 /* PBXTargetDependency */, EBA62C1C1EAD34CD0096B33A /* PBXTargetDependency */, D41257F51E941E8E00781F23 /* PBXTargetDependency */, @@ -199,6 +218,11 @@ D41AD46C1B978F28008C7270 /* PBXTargetDependency */, D41AD46E1B978F4C008C7270 /* PBXTargetDependency */, EB9FE0B61BFBC499004FEAAF /* PBXTargetDependency */, + EB636BD520992DC000C1E21A /* PBXTargetDependency */, + EB89FAFE20DBDAA800085498 /* PBXTargetDependency */, + EB89FB0020DBDAA800085498 /* PBXTargetDependency */, + EB89FB0220DBDAA800085498 /* PBXTargetDependency */, + EB8910F820E0287E00DE533F /* PBXTargetDependency */, ); name = Security_executables_watchos; productName = Security_executables_watchos; @@ -209,6 +233,7 @@ buildPhases = ( ); dependencies = ( + 47C2F18E2059CBF40062DE30 /* PBXTargetDependency */, BE061EB71EE5EB9000B22118 /* PBXTargetDependency */, EBA62C151EAD34C60096B33A /* PBXTargetDependency */, D41257F31E941E8600781F23 /* PBXTargetDependency */, @@ -226,6 +251,13 @@ D41AD44E1B978791008C7270 /* PBXTargetDependency */, D41AD44A1B9786D8008C7270 /* PBXTargetDependency */, EB9FE08D1BFBC48F004FEAAF /* PBXTargetDependency */, + EB636BD120992DA300C1E21A /* PBXTargetDependency */, + EBC73F52209A705A00AE3350 /* PBXTargetDependency */, + EB11965E20A6302100BFDA1B /* PBXTargetDependency */, + EBC73F5D209A739600AE3350 /* PBXTargetDependency */, + EBC73F64209A73A100AE3350 /* PBXTargetDependency */, + EBC73F66209A73A100AE3350 /* PBXTargetDependency */, + EB8910F120E0287600DE533F /* PBXTargetDependency */, ); name = Security_executables_tvos; productName = Security_executables_tvos; @@ -391,6 +423,7 @@ EB10557F1E14DFBE0003C309 /* PBXTargetDependency */, BE9C38D11EB115F4007E2AE1 /* PBXTargetDependency */, DCDB29761FD8839F00B5D242 /* PBXTargetDependency */, + 47D991D720407F890078CAE2 /* PBXTargetDependency */, ); name = Security_tests_osx; productName = Security_test_macos; @@ -409,6 +442,7 @@ EB10557D1E14DFB60003C309 /* PBXTargetDependency */, BE9C38D31EB11605007E2AE1 /* PBXTargetDependency */, DCDB29781FD883AB00B5D242 /* PBXTargetDependency */, + 47D991D020407F7E0078CAE2 /* PBXTargetDependency */, ); name = Security_tests_ios; productName = Security_test_ios; @@ -468,8 +502,9 @@ buildPhases = ( ); dependencies = ( + 47455B24205B3E2F008FE980 /* PBXTargetDependency */, D41257F71E941E9600781F23 /* PBXTargetDependency */, - EB6A6FB31B90F89F0045DC68 /* PBXTargetDependency */, + DAE40BD520CF3ED5002D5674 /* PBXTargetDependency */, ); name = Security_executables_bridge; productName = Security_executables_Bridge; @@ -517,7 +552,17 @@ /* End PBXAggregateTarget section */ /* 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 */; }; + 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, ); }; }; + 09A3B9E11F82734400C5C324 /* si-44-seckey-proxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A3B9DF1F8271A200C5C324 /* si-44-seckey-proxy.m */; }; + 09A3B9E21F838A3400C5C324 /* SecKeyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */; }; + 09BFE35C20A32E0E008511E9 /* KeychainEntitlementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */; }; 09CB49701F2F64E300C8E4DE /* si-44-seckey-fv.m in Sources */ = {isa = PBXBuildFile; fileRef = 09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */; }; + 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 */; }; 0C0BDB881756A51000BC1A7E /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; 0C0BDB8D1756A66100BC1A7E /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; @@ -555,28 +600,19 @@ 0C48990B1E0E0FF300C6CF70 /* SOSTransportCircleCK.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C48990A1E0E0FF300C6CF70 /* SOSTransportCircleCK.h */; }; 0C4899121E0E105D00C6CF70 /* SOSTransportCircleCK.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C4899111E0E105D00C6CF70 /* SOSTransportCircleCK.m */; }; 0C4899231E0F386900C6CF70 /* SOSAccountTrustClassic.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C4899221E0F386900C6CF70 /* SOSAccountTrustClassic.h */; }; - 0C4899251E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C4899241E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m */; }; - 0C4899271E0F399B00C6CF70 /* SOSAccountTrustOctagon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C4899261E0F399B00C6CF70 /* SOSAccountTrustOctagon.h */; }; 0C52C1FF20003BCA003F0733 /* OTTestsBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C52C1FE20003BCA003F0733 /* OTTestsBase.m */; }; - 0C59605A1FB2D8E50095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; - 0C59605C1FB2D9280095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; - 0C59605D1FB2D95D0095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; - 0C59605E1FB2D9990095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; - 0C59605F1FB2D9F60095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; - 0C5960601FB2DA310095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; - 0C5960621FB2E0EC0095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; - 0C5960631FB2E1A70095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C5663EC20BE2DF30035F362 /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; }; + 0C5663EF20BE2E220035F362 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; 0C5960641FB2E2070095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; settings = {ATTRIBUTES = (Weak, ); }; }; - 0C5960651FB2E2800095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; 0C5960811FB369C50095BA29 /* CKKSHealTLKSharesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */; }; 0C5CFB382019610000913B9C /* OTRamping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5CFB37201960FF00913B9C /* OTRamping.m */; }; 0C5CFB392019610000913B9C /* OTRamping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5CFB37201960FF00913B9C /* OTRamping.m */; }; - 0C5D62F11E81E74800AA4D02 /* SOSInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D8D1D8085F200865A7C /* SOSInternal.m */; }; - 0C5F4FD81F952FEA00AF1616 /* secd-700-sftm.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5F4FD71F952FEA00AF1616 /* secd-700-sftm.m */; }; 0C770EBC1FCF7C9800B5F0E2 /* OTCloudStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */; }; 0C770EC21FCF7C9800B5F0E2 /* OTCloudStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */; }; 0C770EC41FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */; }; 0C770EC51FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */; }; + 0C7756CD209A664800268D2C /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; }; + 0C7756CE209A694100268D2C /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; }; 0C78F1CC16A5E1BF00654E08 /* sectask-10-sectask.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C78F1CA16A5E1BF00654E08 /* sectask-10-sectask.c */; }; 0C78F1CD16A5E1BF00654E08 /* sectask-10-sectask.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C78F1CA16A5E1BF00654E08 /* sectask-10-sectask.c */; }; 0C78F1CE16A5E1BF00654E08 /* sectask_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 0C78F1CB16A5E1BF00654E08 /* sectask_ipc.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; @@ -637,10 +673,12 @@ 0C8BBF231FCB4F1800580909 /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; }; 0C8BBF241FCB4FE700580909 /* OTManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF101FCB486B00580909 /* OTManager.h */; }; 0C8BBF251FCB4FE800580909 /* OTManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF101FCB486B00580909 /* OTManager.h */; }; - 0C8BBF261FCB561C00580909 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; - 0C8BBF2B1FCB575800580909 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; - 0C8BBF2D1FCB5A2900580909 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; - 0C8BBFFD1FCE8F3300580909 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 0C9AEEAF20783FBB00BF6237 /* SFSignInAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF405F42072E2BF003D6A7F /* SFSignInAnalyticsTests.m */; }; + 0C9AEEBB20783FF900BF6237 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 0C9AEEBE207843D000BF6237 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + 0C9FB40720D872A600864612 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C9FB40820D8731800864612 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C9FB40920D8735500864612 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; 0CA4EBF3202B8D9C002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CA4EBF2202B8D1D002B1D96 /* CloudKitKeychainSyncingTestsBase.m */; }; 0CA4EBF4202B8DBE002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CA4EBF2202B8D1D002B1D96 /* CloudKitKeychainSyncingTestsBase.m */; }; 0CA4EC10202BB5AF002B1D96 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; @@ -650,23 +688,25 @@ 0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D891D8085F200865A7C /* SOSCloudCircle.m */; }; 0CAD1E591E1C5CBD00537693 /* secd-52-offering-gencount-reset.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C4F1D8085D800865A7C /* secd-52-offering-gencount-reset.m */; }; 0CAD1E5A1E1C5CD100537693 /* secd-71-engine-save.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C641D8085D800865A7C /* secd-71-engine-save.m */; }; - 0CAD1E5B1E1C5CE100537693 /* secd-76-idstransport.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C681D8085D800865A7C /* secd-76-idstransport.m */; }; - 0CAD1E5C1E1C5CEB00537693 /* secd_77_ids_messaging.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C691D8085D800865A7C /* secd_77_ids_messaging.m */; }; 0CAD1E5D1E1C5CF900537693 /* secd-80-views-alwayson.m in Sources */ = {isa = PBXBuildFile; fileRef = 7281E08B1DFD0A380021E1B7 /* secd-80-views-alwayson.m */; }; 0CAD1E5E1E1C5D0600537693 /* secd-95-escrow-persistence.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C741D8085D800865A7C /* secd-95-escrow-persistence.m */; }; 0CAEC9D81FD740CF00D1F2CA /* OTContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBEAF1FC9DCA400580909 /* OTContextTests.m */; }; + 0CB50A0D20AA486800FE4675 /* SOSAccountTrustClassic+Expansion.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE760471E12F2F200B4381E /* SOSAccountTrustClassic+Expansion.m */; }; + 0CB50A0E20AA4C2F00FE4675 /* SOSAccountTrustClassic+Circle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE760491E12F30200B4381E /* SOSAccountTrustClassic+Circle.m */; }; 0CB9754E2023A8DD008D6B48 /* CloudKitKeychainSyncingMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */; }; 0CB9754F2023A8F5008D6B48 /* CloudKitMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC222CA71E08A7D900B09171 /* CloudKitMockXCTest.m */; }; 0CB975512023B199008D6B48 /* OTRampingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB975502023B199008D6B48 /* OTRampingTests.m */; }; 0CBD55B31FE883F200A8CE21 /* SFBehavior.m in Sources */ = {isa = PBXBuildFile; fileRef = EB82A2A51FAFF26900CA64A9 /* SFBehavior.m */; }; 0CBD55B91FE883F300A8CE21 /* SFBehavior.m in Sources */ = {isa = PBXBuildFile; fileRef = EB82A2A51FAFF26900CA64A9 /* SFBehavior.m */; }; 0CBDF64D1FFC951200433E0D /* OTBottledPeerTLK.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CBDF64C1FFC951200433E0D /* OTBottledPeerTLK.m */; }; - 0CBFEACA200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */; }; - 0CBFEACB200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */; }; - 0CBFEACC200FCD33009A60E9 /* SFTransactionMetric.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 0CBFEACD200FCD33009A60E9 /* SFTransactionMetric.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0CBFEACA200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; }; + 0CBFEACB200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; }; + 0CBFEACC200FCD33009A60E9 /* SFSignInAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF0E2E71F8EE40700BD18E4 /* SFSignInAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0CBFEACD200FCD33009A60E9 /* SFSignInAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF0E2E71F8EE40700BD18E4 /* SFSignInAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0CC0445B1FFC4150004A5B63 /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; 0CC319241DA46FBF005D42EA /* ProtectedCloudStorage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43DB542E1BB1F85B0083C3F1 /* ProtectedCloudStorage.framework */; }; + 0CC3771320A222BC00B58D2D /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; }; + 0CC3775020ACA0DF00B58D2D /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; }; 0CCCC7C920261D310024405E /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; }; 0CCCC7CA20261D310024405E /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; }; 0CCDE7171EEB08220021A946 /* secd-156-timers.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCDE7161EEB08220021A946 /* secd-156-timers.m */; }; @@ -678,14 +718,13 @@ 0CE1BCCF1FCE11690017230E /* OTBottledPeerSigned.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */; }; 0CE407AC1FD4769B00F59B31 /* OTCloudStoreState.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */; }; 0CE407AD1FD4769B00F59B31 /* OTCloudStoreState.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */; }; - 0CE760481E12F2F300B4381E /* SOSAccountTrustClassic+Expansion.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE760471E12F2F200B4381E /* SOSAccountTrustClassic+Expansion.m */; }; - 0CE7604A1E12F30200B4381E /* SOSAccountTrustClassic+Circle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE760491E12F30200B4381E /* SOSAccountTrustClassic+Circle.m */; }; 0CE7604C1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE7604B1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m */; }; 0CE7604E1E12F5BA00B4381E /* SOSAccountTrustClassic+Retirement.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE7604D1E12F5BA00B4381E /* SOSAccountTrustClassic+Retirement.m */; }; 0CE760501E1301DC00B4381E /* SOSAccountTrustClassic+Expansion.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CE7604F1E1301DC00B4381E /* SOSAccountTrustClassic+Expansion.h */; }; 0CE760521E1314F700B4381E /* SOSAccountTrustClassic+Identity.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CE760511E1314F700B4381E /* SOSAccountTrustClassic+Identity.h */; }; 0CE760541E13155100B4381E /* SOSAccountTrustClassic+Circle.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CE760531E13155100B4381E /* SOSAccountTrustClassic+Circle.h */; }; 0CE760561E1316E900B4381E /* SOSAccountTrustClassic+Retirement.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CE760551E1316E900B4381E /* SOSAccountTrustClassic+Retirement.h */; }; + 0CF406522072E422003D6A7F /* SFSignInAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF405F42072E2BF003D6A7F /* SFSignInAnalyticsTests.m */; }; 0CFC029C1D41650700E6283B /* libcoretls.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CFC029B1D41650700E6283B /* libcoretls.dylib */; }; 0CFC02C21D41651E00E6283B /* libcoretls.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CFC029B1D41650700E6283B /* libcoretls.dylib */; }; 107226D30D91DB32003CF14F /* SecTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 107226D10D91DB32003CF14F /* SecTask.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -739,6 +778,53 @@ 22A23B3E1E3AAC9800C41830 /* SecRequirement.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067931D8CDF7E007602F1 /* SecRequirement.h */; settings = {ATTRIBUTES = (Private, ); }; }; 22E337DA1E37FD66001D5637 /* libsecurity_codesigning_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 225394B41E3080A600D3CD9B /* libsecurity_codesigning_ios.a */; }; 24CBF8751E9D4E6100F09F0E /* kc-44-secrecoverypassword.c in Sources */ = {isa = PBXBuildFile; fileRef = 24CBF8731E9D4E4500F09F0E /* kc-44-secrecoverypassword.c */; }; + 3DD1FF92201FC4EA0086D049 /* SecureTransportTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7E201AA50F0086D049 /* SecureTransportTests.m */; }; + 3DD1FF93201FC4EF0086D049 /* STLegacyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE8C201AA5150086D049 /* STLegacyTests.m */; }; + 3DD1FF94201FC4F40086D049 /* STLegacyTests+ciphers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE89201AA5140086D049 /* STLegacyTests+ciphers.m */; }; + 3DD1FF95201FC4F70086D049 /* STLegacyTests+clientauth.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE87201AA5130086D049 /* STLegacyTests+clientauth.m */; }; + 3DD1FF96201FC4FE0086D049 /* STLegacyTests+crashes.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE83201AA5110086D049 /* STLegacyTests+crashes.m */; }; + 3DD1FF97201FC5030086D049 /* STLegacyTests+dhe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE82201AA5110086D049 /* STLegacyTests+dhe.m */; }; + 3DD1FF98201FC5080086D049 /* STLegacyTests+falsestart.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE84201AA5120086D049 /* STLegacyTests+falsestart.m */; }; + 3DD1FF99201FC50E0086D049 /* STLegacyTests+noconn.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7B201AA50D0086D049 /* STLegacyTests+noconn.m */; }; + 3DD1FF9A201FC5130086D049 /* STLegacyTests+renegotiate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE85201AA5120086D049 /* STLegacyTests+renegotiate.m */; }; + 3DD1FF9B201FC5170086D049 /* STLegacyTests+sessioncache.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE8B201AA5150086D049 /* STLegacyTests+sessioncache.m */; }; + 3DD1FF9C201FC51B0086D049 /* STLegacyTests+sessionstate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE80201AA5100086D049 /* STLegacyTests+sessionstate.m */; }; + 3DD1FF9E201FC53A0086D049 /* STLegacyTests+split.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE88201AA5130086D049 /* STLegacyTests+split.m */; }; + 3DD1FF9F201FC5410086D049 /* STLegacyTests+sslciphers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE81201AA5100086D049 /* STLegacyTests+sslciphers.m */; }; + 3DD1FFA0201FC5450086D049 /* STLegacyTests+tls12.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7D201AA50E0086D049 /* STLegacyTests+tls12.m */; }; + 3DD1FFA1201FC5660086D049 /* ssl-utils.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCA451D8B82CD00070CB0 /* ssl-utils.c */; }; + 3DD1FFA2201FC5800086D049 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; + 3DD1FFA3201FC5870086D049 /* libDiagnosticMessagesClient.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41D36701EB14D87007FA978 /* libDiagnosticMessagesClient.tbd */; }; + 3DD1FFA4201FC58F0086D049 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 3DD1FFA5201FC59D0086D049 /* libsecurity_ssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC9CF1D8B824700070CB0 /* libsecurity_ssl.a */; }; + 3DD1FFA7201FC5B90086D049 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + 3DD1FFAA201FC5C30086D049 /* libcoretls.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DD1FFA8201FC5C20086D049 /* libcoretls.tbd */; }; + 3DD1FFAB201FC5C30086D049 /* libcoretls_cfhelpers.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */; }; + 3DD1FFB4201FDB1D0086D049 /* STLegacyTests+noconn.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7B201AA50D0086D049 /* STLegacyTests+noconn.m */; }; + 3DD1FFB5201FDB1D0086D049 /* STLegacyTests+falsestart.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE84201AA5120086D049 /* STLegacyTests+falsestart.m */; }; + 3DD1FFB6201FDB1D0086D049 /* STLegacyTests+crashes.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE83201AA5110086D049 /* STLegacyTests+crashes.m */; }; + 3DD1FFB7201FDB1D0086D049 /* STLegacyTests+clientauth.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE87201AA5130086D049 /* STLegacyTests+clientauth.m */; }; + 3DD1FFB8201FDB1D0086D049 /* SecureTransportTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7E201AA50F0086D049 /* SecureTransportTests.m */; }; + 3DD1FFB9201FDB1D0086D049 /* STLegacyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE8C201AA5150086D049 /* STLegacyTests.m */; }; + 3DD1FFBA201FDB1D0086D049 /* STLegacyTests+ciphers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE89201AA5140086D049 /* STLegacyTests+ciphers.m */; }; + 3DD1FFBB201FDB1D0086D049 /* STLegacyTests+dhe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE82201AA5110086D049 /* STLegacyTests+dhe.m */; }; + 3DD1FFBC201FDB1D0086D049 /* STLegacyTests+renegotiate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE85201AA5120086D049 /* STLegacyTests+renegotiate.m */; }; + 3DD1FFBD201FDB1D0086D049 /* STLegacyTests+sessioncache.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE8B201AA5150086D049 /* STLegacyTests+sessioncache.m */; }; + 3DD1FFBE201FDB1D0086D049 /* STLegacyTests+sessionstate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE80201AA5100086D049 /* STLegacyTests+sessionstate.m */; }; + 3DD1FFBF201FDB1D0086D049 /* STLegacyTests+split.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE88201AA5130086D049 /* STLegacyTests+split.m */; }; + 3DD1FFC0201FDB1D0086D049 /* STLegacyTests+sslciphers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE81201AA5100086D049 /* STLegacyTests+sslciphers.m */; }; + 3DD1FFC1201FDB1D0086D049 /* STLegacyTests+tls12.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7D201AA50E0086D049 /* STLegacyTests+tls12.m */; }; + 3DD1FFC2201FDB1D0086D049 /* ssl-utils.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCA451D8B82CD00070CB0 /* ssl-utils.c */; }; + 3DD1FFC4201FDB1D0086D049 /* libcoretls.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DD1FFA8201FC5C20086D049 /* libcoretls.tbd */; }; + 3DD1FFC5201FDB1D0086D049 /* libcoretls_cfhelpers.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */; }; + 3DD1FFC6201FDB1D0086D049 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + 3DD1FFC8201FDB1D0086D049 /* libsecurity_ssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC9CF1D8B824700070CB0 /* libsecurity_ssl.a */; }; + 3DD1FFC9201FDB1D0086D049 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 3DD1FFCB201FDB1D0086D049 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; + 3DD1FFD1201FDC460086D049 /* STLegacyTests+clientauth41.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE78201AA50C0086D049 /* STLegacyTests+clientauth41.m */; }; + 3DD1FFD2201FDCA80086D049 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; + 3DD1FFD5201FF7860086D049 /* SecureTransport_iosTests.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DD1FE86201AA5120086D049 /* SecureTransport_iosTests.plist */; }; + 3DD1FFD7201FF7B10086D049 /* SecureTransport_macosTests.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DD1FE79201AA50D0086D049 /* SecureTransport_macosTests.plist */; }; 433E519E1B66D5F600482618 /* AppSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 433E519D1B66D5F600482618 /* AppSupport.framework */; }; 4381603A1B4DCE8F00C54D58 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; 4381603B1B4DCEFF00C54D58 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; }; @@ -777,11 +863,203 @@ 44A655A51AA4B4C70059D185 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; }; 44A655A61AA4B4C80059D185 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.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 */; }; + 470D96731FCDE55B0065FE90 /* SecCDKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */; }; + 470D96741FCDE55B0065FE90 /* SecCDKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */; }; 4710A6D91F34F21700745267 /* CrashReporterSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */; }; + 4718AE10205B39620068EC3F /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + 4718AE11205B39620068EC3F /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + 4718AE12205B39620068EC3F /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 790850840CA87CF00083CC4D /* server.c */; }; + 4718AE13205B39620068EC3F /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + 4718AE14205B39620068EC3F /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + 4718AE15205B39620068EC3F /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + 4718AE16205B39620068EC3F /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + 4718AE19205B39620068EC3F /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D47CA65C1EB036450038E2BB /* libMobileGestalt.dylib */; }; + 4718AE1A205B39620068EC3F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + 4718AE1B205B39620068EC3F /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 4718AE1C205B39620068EC3F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; + 4718AE1E205B39620068EC3F /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + 4718AE1F205B39620068EC3F /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; + 4718AE20205B39620068EC3F /* libSWCAgent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC4D1D80D00800B0A59C /* libSWCAgent.a */; }; + 4718AE21205B39620068EC3F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + 4718AE22205B39620068EC3F /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; + 4718AE23205B39620068EC3F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + 4718AE24205B39620068EC3F /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; + 4718AE25205B39620068EC3F /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; + 4718AE27205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCEE1E851D93424D00DC0EB7 /* com.apple.securityd.plist */; }; + 4718AE29205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCE4E80D1D7A4E3A00AFB96E /* com.apple.securityd.plist */; }; + 4718AE30205B39C40068EC3F /* OTAuthenticatedCiphertext.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */; }; + 4718AE31205B39C40068EC3F /* OTPrivateKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */; }; + 4718AE32205B39C40068EC3F /* OTBottle.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A11FD71CC800933DAC /* OTBottle.proto */; }; + 4718AE33205B39C40068EC3F /* OTBottleContents.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A51FD720C900933DAC /* OTBottleContents.proto */; }; + 4718AE34205B39C40068EC3F /* CKKSSerializedKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = DC4D49D81F857728007AF2B8 /* CKKSSerializedKey.proto */; }; + 4718AE35205B39C40068EC3F /* CKKSSQLDatabaseObject.m in Sources */ = {isa = PBXBuildFile; fileRef = DC797E131DD3F88300CC9E42 /* CKKSSQLDatabaseObject.m */; }; + 4718AE36205B39C40068EC3F /* CKKSRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC185981E24E87D009657D8 /* CKKSRateLimiter.m */; }; + 4718AE37205B39C40068EC3F /* CKKSCKAccountStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFB12C41E95A4C000510F5F /* CKKSCKAccountStateTracker.m */; }; + 4718AE38205B39C40068EC3F /* SecCDKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */; }; + 4718AE39205B39C40068EC3F /* CKKSPowerCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */; }; + 4718AE3A205B39C40068EC3F /* CKKSGroupOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCCD88E71E42622200F5AA71 /* CKKSGroupOperation.m */; }; + 4718AE3B205B39C40068EC3F /* OTContextRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */; }; + 4718AE3C205B39C40068EC3F /* OTPrivateKey+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */; }; + 4718AE3D205B39C40068EC3F /* CKKSManifestLeafRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 476D873A1E6750E200190352 /* CKKSManifestLeafRecord.m */; }; + 4718AE3E205B39C40068EC3F /* CKKSItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCDCCB8E1DF7B8D4006E840E /* CKKSItem.m */; }; + 4718AE3F205B39C40068EC3F /* CKKSItemEncrypter.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1ED8BA1DD51883002BDCFA /* CKKSItemEncrypter.m */; }; + 4718AE40205B39C40068EC3F /* CKKSOutgoingQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9B7AE41DCBF604004E9385 /* CKKSOutgoingQueueEntry.m */; }; + 4718AE42205B39C40068EC3F /* CKKSIncomingQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B3B1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m */; }; + 4718AE43205B39C40068EC3F /* OTLocalStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */; }; + 4718AE44205B39C40068EC3F /* SFKeychainControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */; }; + 4718AE45205B39C40068EC3F /* OTBottledPeerSigned.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */; }; + 4718AE46205B39C40068EC3F /* CKKSIncomingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4F11E0C86800010F836 /* CKKSIncomingQueueOperation.m */; }; + 4718AE47205B39C40068EC3F /* CKKSOutgoingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4FD1E0C98320010F836 /* CKKSOutgoingQueueOperation.m */; }; + 4718AE48205B39C40068EC3F /* CKKSZoneStateEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B371DEFADB500A3DAFA /* CKKSZoneStateEntry.m */; }; + 4718AE49205B39C40068EC3F /* AsymKeybagBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 526965CC1E6E283100627F9D /* AsymKeybagBackup.m */; }; + 4718AE4A205B39C40068EC3F /* RateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC7F5B31E9F99EE0014AE63 /* RateLimiter.m */; }; + 4718AE4B205B39C40068EC3F /* CKKSHealKeyHierarchyOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC15F7651E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m */; }; + 4718AE4C205B39C40068EC3F /* CKKSCurrentItemPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE278DC1ED789EF0083B485 /* CKKSCurrentItemPointer.m */; }; + 4718AE4D205B39C40068EC3F /* CKKSLocalSynchronizeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3D748B1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m */; }; + 4718AE4E205B39C40068EC3F /* OTManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0F1FCB481800580909 /* OTManager.m */; }; + 4718AE4F205B39C40068EC3F /* OTEscrowKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */; }; + 4718AE50205B39C40068EC3F /* CKKSCurrentKeyPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA4D1F41E5520550056214F /* CKKSCurrentKeyPointer.m */; }; + 4718AE51205B39C40068EC3F /* CKKSControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */; }; + 4718AE52205B39C40068EC3F /* CKKSUpdateDeviceStateOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C501F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m */; }; + 4718AE53205B39C40068EC3F /* SecDbKeychainSerializedMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */; }; + 4718AE54205B39C40068EC3F /* CKKSNearFutureScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD6C4B11EC5302500414FEE /* CKKSNearFutureScheduler.m */; }; + 4718AE55205B39C40068EC3F /* CKKSMirrorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B2E1DEF9E0E00A3DAFA /* CKKSMirrorEntry.m */; }; + 4718AE56205B39C40068EC3F /* CloudKitCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC94BCC91F10448600E07CEB /* CloudKitCategories.m */; }; + 4718AE57205B39C40068EC3F /* CKKSPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3291F8598F300C8AAC8 /* CKKSPeer.m */; }; + 4718AE58205B39C40068EC3F /* CKKS.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1ED8C51DD55476002BDCFA /* CKKS.m */; }; + 4718AE59205B39C40068EC3F /* CKKSSynchronizeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB5D93A1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m */; }; + 4718AE5A205B39C40068EC3F /* CKKSRecordHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = DC762A9D1E57A86A00B03A2C /* CKKSRecordHolder.m */; }; + 4718AE5B205B39C40068EC3F /* SOSChangeTracker.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D4F1D8085F200865A7C /* SOSChangeTracker.c */; }; + 4718AE5C205B39C40068EC3F /* CKKSScanLocalItemsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1DA6671E4555D80094CE7F /* CKKSScanLocalItemsOperation.m */; }; + 4718AE5D205B39C40068EC3F /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC18F76E1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m */; }; + 4718AE5E205B39C40068EC3F /* CKKSNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = DC2C5F5B1F0EB97E00FEBDA7 /* CKKSNotifier.m */; }; + 4718AE5F205B39C40068EC3F /* SOSEngine.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D561D8085F200865A7C /* SOSEngine.c */; }; + 4718AE60205B39C40068EC3F /* CKKSKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4DB14F1E24692100CD6769 /* CKKSKey.m */; }; + 4718AE61205B39C40068EC3F /* CKKSViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBDB3BA1E57CA7A00B61300 /* CKKSViewManager.m */; }; + 4718AE62205B39C40068EC3F /* SecDbKeychainItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */; }; + 4718AE63205B39C40068EC3F /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 4718AE64205B39C40068EC3F /* CKKSReachabilityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = EB4E0CD51FF36A1900CDCACC /* CKKSReachabilityTracker.m */; }; + 4718AE65205B39C40068EC3F /* SecDbItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C8E1D8085D800865A7C /* SecDbItem.c */; }; + 4718AE66205B39C40068EC3F /* SecDbKeychainItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */; }; + 4718AE67205B39C40068EC3F /* SecDbQuery.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C921D8085D800865A7C /* SecDbQuery.c */; }; + 4718AE68205B39C40068EC3F /* CKKSResultOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447891F5764C600236DB4 /* CKKSResultOperation.m */; }; + 4718AE69205B39C40068EC3F /* CKKSManifest.m in Sources */ = {isa = PBXBuildFile; fileRef = 47CEED1F1E60DE900044EAB4 /* CKKSManifest.m */; }; + 4718AE6A205B39C40068EC3F /* SecItemBackupServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9C1D8085D800865A7C /* SecItemBackupServer.c */; }; + 4718AE6B205B39C40068EC3F /* SecItemDataSource.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C941D8085D800865A7C /* SecItemDataSource.c */; }; + 4718AE6C205B39C40068EC3F /* OctagonControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC124DC220059B8700BE8DAC /* OctagonControlServer.m */; }; + 4718AE6D205B39C40068EC3F /* SecItemDb.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C961D8085D800865A7C /* SecItemDb.c */; }; + 4718AE6E205B39C40068EC3F /* SecItemSchema.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C981D8085D800865A7C /* SecItemSchema.c */; }; + 4718AE6F205B39C40068EC3F /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; }; + 4718AE70205B39C40068EC3F /* OTRamping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5CFB37201960FF00913B9C /* OTRamping.m */; }; + 4718AE71205B39C40068EC3F /* SecItemServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9A1D8085D800865A7C /* SecItemServer.c */; }; + 4718AE72205B39C40068EC3F /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */; }; + 4718AE74205B39C40068EC3F /* OTContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE981FC9DA5A00580909 /* OTContext.m */; }; + 4718AE75205B39C40068EC3F /* NSOperationCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447951F5766D200236DB4 /* NSOperationCategories.m */; }; + 4718AE76205B39C40068EC3F /* SecKeybagSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9E1D8085D800865A7C /* SecKeybagSupport.c */; }; + 4718AE77205B39C40068EC3F /* SecLogSettingsServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CAE1D8085D800865A7C /* SecLogSettingsServer.m */; }; + 4718AE78205B39C40068EC3F /* CKKSDeviceStateEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C261F17E455007640C8 /* CKKSDeviceStateEntry.m */; }; + 4718AE79205B39C40068EC3F /* CKKSFixups.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAD9B431F8D939C00C5E2AE /* CKKSFixups.m */; }; + 4718AE7A205B39C40068EC3F /* OTIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */; }; + 4718AE7C205B39C40068EC3F /* SecOTRRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB41D8085D800865A7C /* SecOTRRemote.m */; }; + 4718AE7D205B39C40068EC3F /* CKKSUpdateCurrentItemPointerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE278E71ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m */; }; + 4718AE7E205B39C40068EC3F /* CKKSNewTLKOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD662F41E329B6800188186 /* CKKSNewTLKOperation.m */; }; + 4718AE7F205B39C40068EC3F /* CKKSLockStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DC207EB71ED4EAB600D46873 /* CKKSLockStateTracker.m */; }; + 4718AE80205B39C40068EC3F /* OTCloudStoreState.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */; }; + 4718AE81205B39C40068EC3F /* SecDbKeychainSerializedSecretData.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */; }; + 4718AE82205B39C40068EC3F /* CKKSKeychainView.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBDB3B11E57C67500B61300 /* CKKSKeychainView.m */; }; + 4718AE83205B39C40068EC3F /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; + 4718AE84205B39C40068EC3F /* SecDbKeychainSerializedItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */; }; + 4718AE85205B39C40068EC3F /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; }; + 4718AE86205B39C40068EC3F /* CKKSProcessReceivedKeysOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7A17EC1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m */; }; + 4718AE87205B39C40068EC3F /* CKKSTLKShare.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7341F21F8447AB00AB9BDF /* CKKSTLKShare.m */; }; + 4718AE88205B39C40068EC3F /* CKKSHealTLKSharesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */; }; + 4718AE89205B39C40068EC3F /* CKKSReencryptOutgoingItemsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA4D2141E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m */; }; + 4718AE8A205B39C40068EC3F /* SecBackupKeybagEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 52AA92881E662A4A004301A6 /* SecBackupKeybagEntry.m */; }; + 4718AE8B205B39C40068EC3F /* iCloudTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB31D8085D800865A7C /* iCloudTrace.c */; }; + 4718AE8C205B39C40068EC3F /* CKKSAPSReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D841E2F14810089CF55 /* CKKSAPSReceiver.m */; }; + 4718AE8D205B39C40068EC3F /* OTBottledPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */; }; + 4718AE8F205B39C40068EC3F /* SOSEnsureBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C860C7A1F4F63DB004100A1 /* SOSEnsureBackup.m */; }; + 4718AE90205B39C40068EC3F /* OTBottledPeerRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */; }; + 4718AE91205B39C40068EC3F /* OTCloudStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */; }; + 4718AE92205B39C40068EC3F /* CKKSSIV.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D541E2826DB0089CF55 /* CKKSSIV.m */; }; + 4718AE93205B39C40068EC3F /* OTPreflightInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */; }; + 4718AE95205B39C40068EC3F /* OTAuthenticatedCiphertext+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */; }; + 4718AE96205B39C40068EC3F /* CKKSZoneChangeFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */; }; + 4718AE97205B39C40068EC3F /* CKKSCondition.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C331F17ECE5007640C8 /* CKKSCondition.m */; }; + 4718AE98205B39C40068EC3F /* CKKSZone.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D961E3014250089CF55 /* CKKSZone.m */; }; + 4718AE99205B39C40068EC3F /* SFKeychainServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 47FF17251FD60ACA00875565 /* SFKeychainServer.m */; }; + 4718AE9A205B39C40068EC3F /* SFECPublicKey+SPKI.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */; }; + 4718AE9B205B39C40068EC3F /* swcagent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78EA01D80860C00865A7C /* swcagent_client.c */; }; + 4718AE9E205B39C40068EC3F /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */; }; + 4718AE9F205B39C40068EC3F /* CKKSCondition.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C321F17ECE5007640C8 /* CKKSCondition.h */; }; + 4718AEA0205B39C40068EC3F /* CKKSScanLocalItemsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1DA65C1E4554620094CE7F /* CKKSScanLocalItemsOperation.h */; }; + 4718AEA1205B39C40068EC3F /* CKKSNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = DC2C5F5A1F0EB97E00FEBDA7 /* CKKSNotifier.h */; }; + 4718AEA2205B39C40068EC3F /* CKKSGroupOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCCD88E61E42622200F5AA71 /* CKKSGroupOperation.h */; }; + 4718AEA3205B39C40068EC3F /* CKKSRateLimiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC185971E24E87D009657D8 /* CKKSRateLimiter.h */; }; + 4718AEA4205B39C40068EC3F /* SecDbKeychainSerializedItemV7.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */; }; + 4718AEA5205B39C40068EC3F /* OTCloudStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */; }; + 4718AEA6205B39C40068EC3F /* CKKSResultOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447881F5764C600236DB4 /* CKKSResultOperation.h */; }; + 4718AEA7205B39C40068EC3F /* CKKSUpdateDeviceStateOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C4F1F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h */; }; + 4718AEA8205B39C40068EC3F /* CKKSViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBDB3B91E57CA7A00B61300 /* CKKSViewManager.h */; }; + 4718AEA9205B39C40068EC3F /* CKKSRecordHolder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC762A9C1E57A86A00B03A2C /* CKKSRecordHolder.h */; }; + 4718AEAA205B39C40068EC3F /* CKKSOutgoingQueueOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5BB4FC1E0C98320010F836 /* CKKSOutgoingQueueOperation.h */; }; + 4718AEAB205B39C40068EC3F /* CKKSSynchronizeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB5D9391E4A9A3400BE22AB /* CKKSSynchronizeOperation.h */; }; + 4718AEAC205B39C40068EC3F /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; }; + 4718AEAD205B39C40068EC3F /* SOSChangeTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D501D8085F200865A7C /* SOSChangeTracker.h */; }; + 4718AEAE205B39C40068EC3F /* CKKSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */; }; + 4718AEAF205B39C40068EC3F /* SOSEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D571D8085F200865A7C /* SOSEngine.h */; }; + 4718AEB0205B39C40068EC3F /* SecDbKeychainItem.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C911D8085D800865A7C /* SecDbKeychainItem.h */; }; + 4718AEB1205B39C40068EC3F /* CKKSProcessReceivedKeysOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7A17EB1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h */; }; + 4718AEB2205B39C40068EC3F /* SecDbQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C931D8085D800865A7C /* SecDbQuery.h */; }; + 4718AEB3205B39C40068EC3F /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; }; + 4718AEB4205B39C40068EC3F /* CKKSMirrorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B2C1DEF9DF000A3DAFA /* CKKSMirrorEntry.h */; }; + 4718AEB5205B39C40068EC3F /* CloudKitCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC94BCC81F10448600E07CEB /* CloudKitCategories.h */; }; + 4718AEB6205B39C40068EC3F /* CKKSDeviceStateEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C251F17E455007640C8 /* CKKSDeviceStateEntry.h */; }; + 4718AEB7205B39C40068EC3F /* OTAuthenticatedCiphertext+SF.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */; }; + 4718AEB8205B39C40068EC3F /* CKKSCKAccountStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFB12C31E95A4C000510F5F /* CKKSCKAccountStateTracker.h */; }; + 4718AEB9205B39C40068EC3F /* CKKSZoneStateEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B361DEFADB500A3DAFA /* CKKSZoneStateEntry.h */; }; + 4718AEBA205B39C40068EC3F /* CKKSTLKShare.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7341F11F8447AB00AB9BDF /* CKKSTLKShare.h */; }; + 4718AEBB205B39C40068EC3F /* SecItemDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C951D8085D800865A7C /* SecItemDataSource.h */; }; + 4718AEBC205B39C40068EC3F /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC18F76D1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h */; }; + 4718AEBD205B39C40068EC3F /* SecDbKeychainSerializedMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */; }; + 4718AEBE205B39C40068EC3F /* CKKSZoneChangeFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9082C21EA0276000D0C1C5 /* CKKSZoneChangeFetcher.h */; }; + 4718AEBF205B39C40068EC3F /* CKKSReencryptOutgoingItemsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCA4D2131E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h */; }; + 4718AEC0205B39C40068EC3F /* SFPublicKey+SPKI.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */; }; + 4718AEC1205B39C40068EC3F /* CKKSIncomingQueueEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B3A1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.h */; }; + 4718AEC2205B39C40068EC3F /* SecItemDb.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C971D8085D800865A7C /* SecItemDb.h */; }; + 4718AEC3205B39C40068EC3F /* CKKSFixups.h in Headers */ = {isa = PBXBuildFile; fileRef = DCAD9B421F8D939C00C5E2AE /* CKKSFixups.h */; }; + 4718AEC4205B39C40068EC3F /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; }; + 4718AEC5205B39C40068EC3F /* SecItemSchema.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C991D8085D800865A7C /* SecItemSchema.h */; }; + 4718AEC6205B39C40068EC3F /* CKKSLocalSynchronizeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3D748A1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h */; }; + 4718AEC7205B39C40068EC3F /* SecKeybagSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C9F1D8085D800865A7C /* SecKeybagSupport.h */; }; + 4718AEC8205B39C40068EC3F /* CKKSNewTLKOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD662F31E329B6800188186 /* CKKSNewTLKOperation.h */; }; + 4718AEC9205B39C40068EC3F /* iCloudTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78CB21D8085D800865A7C /* iCloudTrace.h */; }; + 4718AECA205B39C40068EC3F /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; }; + 4718AECB205B39C40068EC3F /* SFKeychainServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 47FF17241FD60ACA00875565 /* SFKeychainServer.h */; }; + 4718AECC205B39C40068EC3F /* CKKSOutgoingQueueEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9B7AE61DCBF651004E9385 /* CKKSOutgoingQueueEntry.h */; }; + 4718AECD205B39C40068EC3F /* CKKSHealKeyHierarchyOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC15F7641E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h */; }; + 4718AECE205B39C40068EC3F /* CKKSNearFutureScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD6C4B01EC5302400414FEE /* CKKSNearFutureScheduler.h */; }; + 4718AECF205B39C40068EC3F /* OTManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF101FCB486B00580909 /* OTManager.h */; }; + 4718AED0205B39C40068EC3F /* CKKSHealTLKSharesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBF2F831F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h */; }; + 4718AED1205B39C40068EC3F /* CKKSUpdateCurrentItemPointerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278E61ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h */; }; + 4718AED2205B39C40068EC3F /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; }; + 4718AED3205B39C40068EC3F /* CKKSAPSReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D831E2F14810089CF55 /* CKKSAPSReceiver.h */; }; + 4718AED4205B39C40068EC3F /* NSOperationCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447941F5766D200236DB4 /* NSOperationCategories.h */; }; + 4718AED5205B39C40068EC3F /* CKKSKey.h in Headers */ = {isa = PBXBuildFile; fileRef = DC4DB14E1E24692100CD6769 /* CKKSKey.h */; }; + 4718AED6205B39C40068EC3F /* CKKSCurrentItemPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */; }; + 4718AED7205B39C40068EC3F /* CKKSControlServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */; }; + 4718AED8205B39C40068EC3F /* CKKSSIV.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D531E2826DB0089CF55 /* CKKSSIV.h */; }; + 4718AED9205B39C40068EC3F /* SFKeychainControlManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */; }; + 4718AEDA205B39C40068EC3F /* SecDbKeychainSerializedSecretData.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */; }; + 4718AEDB205B39C40068EC3F /* CKKSItem.h in Headers */ = {isa = PBXBuildFile; fileRef = DCDCCB8D1DF7B8D4006E840E /* CKKSItem.h */; }; + 4718AEE3205B3A050068EC3F /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; }; + 4718AEE4205B3A060068EC3F /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; }; + 4718AEE7205B3A420068EC3F /* libsecurityd_bridge.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4718AEE2205B39C40068EC3F /* libsecurityd_bridge.a */; }; 471A03EC1F72E35B000A8904 /* SecDbKeychainItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */; }; 471A03F21F72E35C000A8904 /* SecDbKeychainItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */; }; 472339671FD7155E00CB6A72 /* libprequelite.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 472339611FD7155C00CB6A72 /* libprequelite.dylib */; }; - 472339691FD7156800CB6A72 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 472339681FD7156700CB6A72 /* CoreCDP.framework */; }; 4723C9C21F152EB50082882F /* SFObjCType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9C01F152EB10082882F /* SFObjCType.h */; }; 4723C9C31F152EB60082882F /* SFObjCType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9C01F152EB10082882F /* SFObjCType.h */; }; 4723C9C61F152EC00082882F /* SFSQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9BD1F152EB10082882F /* SFSQLite.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -794,10 +1072,7 @@ 4727FBBA1F9918590003AE36 /* KeychainCryptoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */; }; 4727FBC51F991C470003AE36 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBC41F991C460003AE36 /* Foundation.framework */; }; 4727FBC61F991DE90003AE36 /* libsecdRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EDB11D80D58400B0A59C /* libsecdRegressions.a */; }; - 4727FBC71F991E3A0003AE36 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; - 4727FBC81F991E460003AE36 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; 4727FBC91F991E5A0003AE36 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; - 4727FBCB1F991F510003AE36 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCA1F991F510003AE36 /* Security.framework */; }; 4727FBCD1F991F660003AE36 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCC1F991F660003AE36 /* libsqlite3.dylib */; }; 4727FBCE1F991F820003AE36 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCF1F991F820003AE36 /* SecurityFoundation.framework */; }; 4727FBD11F991F990003AE36 /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD01F991F990003AE36 /* libMobileGestalt.dylib */; }; @@ -807,10 +1082,7 @@ 4727FBD71F99209C0003AE36 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; 4727FBD91F9920BC0003AE36 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD81F9920BB0003AE36 /* SystemConfiguration.framework */; }; 4727FBDB1F9920CC0003AE36 /* WirelessDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDA1F9920CB0003AE36 /* WirelessDiagnostics.framework */; }; - 4727FBDD1F9920F20003AE36 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDC1F9920F10003AE36 /* libaks_acl.a */; }; - 4727FBDF1F99211D0003AE36 /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDE1F99211D0003AE36 /* libaks.a */; }; 4727FBE11F9921300003AE36 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE01F99212F0003AE36 /* IOKit.framework */; }; - 4727FBE31F9921660003AE36 /* MobileKeyBag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE21F9921660003AE36 /* MobileKeyBag.framework */; }; 4727FBE51F99217B0003AE36 /* SharedWebCredentials.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE41F99217A0003AE36 /* SharedWebCredentials.framework */; }; 4727FBE71F99218A0003AE36 /* ApplePushService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE61F9921890003AE36 /* ApplePushService.framework */; }; 4727FBE91F9921D10003AE36 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE81F9921D00003AE36 /* libACM.a */; }; @@ -830,6 +1102,8 @@ 474B5FC81E662E79007546F8 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; 475F37201EE8F23900248FB5 /* SFAnalytics.plist in Resources */ = {isa = PBXBuildFile; fileRef = 475F371F1EE8F23900248FB5 /* SFAnalytics.plist */; }; 475F37211EE8F23900248FB5 /* SFAnalytics.plist in Resources */ = {isa = PBXBuildFile; fileRef = 475F371F1EE8F23900248FB5 /* SFAnalytics.plist */; }; + 4764E9272059D866005497C9 /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; }; + 4764E92D2059D8BF005497C9 /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; }; 476541651F339F6300413F65 /* SecdWatchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = 476541631F339F6300413F65 /* SecdWatchdog.h */; }; 476541701F33B59300413F65 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; 476541711F33B59500413F65 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; @@ -847,6 +1121,13 @@ 47702B291E5F463400B29577 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; 47702B371E5F495C00B29577 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 47702B351E5F495C00B29577 /* main.m */; }; 47702B391E5F4B2200B29577 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; + 4771D973209A755800BA9772 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBC41F991C460003AE36 /* Foundation.framework */; }; + 4771D980209A75FE00BA9772 /* KeychainDataclassOwner.m in Sources */ = {isa = PBXBuildFile; fileRef = 4771D97F209A75FE00BA9772 /* KeychainDataclassOwner.m */; }; + 4771D9A0209B7C2700BA9772 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4771D99F209B7C2600BA9772 /* Security.framework */; }; + 4771D9A2209B7C3900BA9772 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4771D9A1209B7C3900BA9772 /* Accounts.framework */; }; + 4771DA2520A4C33A00BA9772 /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; }; + 4771DA2620A4C34800BA9772 /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; }; + 4771DA2720A4C37D00BA9772 /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; }; 4771ECCD1F17CD0E00840998 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; 477A1F5220320E4A00ACD81D /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 477A1F4C20320E4900ACD81D /* Accounts.framework */; }; 477A1F5320320E5100ACD81D /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; @@ -861,7 +1142,6 @@ 478D427A1FD72A8100CAB645 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; 478D427B1FD72A8100CAB645 /* KeychainCryptoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */; }; 478D427C1FD72A8100CAB645 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; - 478D427E1FD72A8100CAB645 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 472339681FD7156700CB6A72 /* CoreCDP.framework */; }; 478D427F1FD72A8100CAB645 /* libprequelite.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 472339611FD7155C00CB6A72 /* libprequelite.dylib */; }; 478D42801FD72A8100CAB645 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; 478D42811FD72A8100CAB645 /* libregressionBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCBFD1D8C648C00070CB0 /* libregressionBase.a */; }; @@ -880,9 +1160,7 @@ 478D428E1FD72A8100CAB645 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD21F9920290003AE36 /* CloudKit.framework */; }; 478D42901FD72A8100CAB645 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCF1F991F820003AE36 /* SecurityFoundation.framework */; }; 478D42911FD72A8100CAB645 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCC1F991F660003AE36 /* libsqlite3.dylib */; }; - 478D42921FD72A8100CAB645 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCA1F991F510003AE36 /* Security.framework */; }; 478D42931FD72A8100CAB645 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; - 478D42941FD72A8100CAB645 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; 478D42951FD72A8100CAB645 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; 478D42961FD72A8100CAB645 /* libsecdRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EDB11D80D58400B0A59C /* libsecdRegressions.a */; }; 478D42971FD72A8100CAB645 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBC41F991C460003AE36 /* Foundation.framework */; }; @@ -890,8 +1168,6 @@ 478D429F1FD72C8400CAB645 /* AppleSystemInfo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3F1D78F2FF002223DE /* AppleSystemInfo.framework */; }; 479108B71EE879F9008CEFA0 /* CKKSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */; }; 479108B81EE879F9008CEFA0 /* CKKSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */; }; - 479108B91EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; }; - 479108BA1EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; }; 47922D211FAA76000008F7E0 /* SecDbKeychainSerializedMetadata.proto in Resources */ = {isa = PBXBuildFile; fileRef = 47922D201FAA75FF0008F7E0 /* SecDbKeychainSerializedMetadata.proto */; }; 47922D2D1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto in Resources */ = {isa = PBXBuildFile; fileRef = 47922D2C1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto */; }; 47922D421FAA7C240008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */; }; @@ -911,25 +1187,41 @@ 47922D551FAA7E070008F7E0 /* SecDbKeychainSerializedItemV7.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */; }; 47922D561FAA7E0D0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */; }; 47922D571FAA7E0E0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */; }; + 479231E82065B31300B2718C /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + 479231EE2065B32200B2718C /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + 479231EF2065C52200B2718C /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; + 479231F02065C52D00B2718C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; 479DA1721EBBA8D10065C98F /* CKKSManifest.m in Sources */ = {isa = PBXBuildFile; fileRef = 47CEED1F1E60DE900044EAB4 /* CKKSManifest.m */; }; 479DA1781EBBA8D30065C98F /* CKKSManifest.m in Sources */ = {isa = PBXBuildFile; fileRef = 47CEED1F1E60DE900044EAB4 /* CKKSManifest.m */; }; 47A05B161FDB5D9E00D0816E /* SFKeychainControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */; }; 47A05B171FDB5D9F00D0816E /* SFKeychainControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */; }; 47A05B181FDB5DBC00D0816E /* SFKeychainControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */; }; 47A0ABA81E6F7B24001B388C /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */; }; + 47A91562201A43BA00FF8F46 /* SecSharedCredential.h in Headers */ = {isa = PBXBuildFile; fileRef = BE061FE01899ECEE00C739F6 /* SecSharedCredential.h */; settings = {ATTRIBUTES = (Public, ); }; }; 47B011991F17D78D0030B49F /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; 47B90C901F350966006500BC /* CrashReporterSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */; }; + 47C2F1762059A2300062DE30 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 47C2F1842059CB680062DE30 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBC41F991C460003AE36 /* Foundation.framework */; }; + 47C2F18A2059CB820062DE30 /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; }; 47C51B871EEA657D0032D9E5 /* SecurityUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 47C51B861EEA657D0032D9E5 /* SecurityUnitTests.m */; }; 47C51B891EEA657D0032D9E5 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; + 47D13759209CD1A200CAD493 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; }; 47D13F631E8447FB0063B6E2 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; 47D183911FB3827800CFCD89 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; 47DE88DA1FA7B07400DD3254 /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; 47E553741EDF674700749715 /* CKKSManifestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 476E918D1E7343B200B4E4D3 /* CKKSManifestTests.m */; }; + 47FF17261FD60ACA00875565 /* SFKeychainServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 47FF17241FD60ACA00875565 /* SFKeychainServer.h */; }; + 47FF17271FD60ACA00875565 /* SFKeychainServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 47FF17241FD60ACA00875565 /* SFKeychainServer.h */; }; + 47FF17281FD60ACA00875565 /* SFKeychainServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 47FF17251FD60ACA00875565 /* SFKeychainServer.m */; }; + 47FF17291FD60ACA00875565 /* SFKeychainServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 47FF17251FD60ACA00875565 /* SFKeychainServer.m */; }; 483E798F1DC87605005C0008 /* secd-67-prefixedKeyIDs.m in Sources */ = {isa = PBXBuildFile; fileRef = 483E79891DC875F2005C0008 /* secd-67-prefixedKeyIDs.m */; }; 48776C811DA5BC0E00CC09B9 /* SOSAccountRecovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 48776C801DA5BC0E00CC09B9 /* SOSAccountRecovery.m */; }; + 4885DCAD207FF0780071FB7B /* ClientInfoByNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 4885DCAB207FF0780071FB7B /* ClientInfoByNotification.m */; }; 48CC589F1DA5FF2700EBD9DB /* secd-66-account-recovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 48CC58971DA5FF0B00EBD9DB /* secd-66-account-recovery.m */; }; 48E617211DBEC6BA0098EAAD /* SOSBackupInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 48E6171A1DBEC40D0098EAAD /* SOSBackupInformation.m */; }; 48E617221DBEC6C60098EAAD /* SOSBackupInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 48E6171B1DBEC40D0098EAAD /* SOSBackupInformation.h */; }; + 48FE669620E6E69D00FAEF17 /* SOSAuthKitHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 48FE668F20E6E69B00FAEF17 /* SOSAuthKitHelpers.m */; }; + 48FE669720E6E69D00FAEF17 /* SOSAuthKitHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 48FE669520E6E69C00FAEF17 /* SOSAuthKitHelpers.h */; }; 4AF7000115AFB73800B9D400 /* SecOTRMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF715AFB73800B9D400 /* SecOTRMath.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4AF7000315AFB73800B9D400 /* SecOTRPacketData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF915AFB73800B9D400 /* SecOTRPacketData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4AF7000415AFB73800B9D400 /* SecOTRPackets.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFFA15AFB73800B9D400 /* SecOTRPackets.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -971,6 +1263,8 @@ 4C3DD6B0179755560093F9D8 /* NSDate+TimeIntervalDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3DD6AF179755560093F9D8 /* NSDate+TimeIntervalDescription.m */; }; 4C3DD6BD179760280093F9D8 /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; }; 4C4296320BB0A68200491999 /* SecTrustSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C4296300BB0A68200491999 /* SecTrustSettings.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4C47FA9320A51DC900384CB6 /* AppleFSCompression.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C47FA8D20A51DC700384CB6 /* AppleFSCompression.framework */; }; + 4C47FA9420A51DD800384CB6 /* AppleFSCompression.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C47FA8D20A51DC700384CB6 /* AppleFSCompression.framework */; }; 4C50AD0C1410679000EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar Resources */ = {isa = PBXBuildFile; fileRef = 4C50ACFD1410671D00EE92DE /* Invalid-asterisk.google.com.crt */; }; 4C50AD0D1410679000EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar Resources */ = {isa = PBXBuildFile; fileRef = 4C50ACFE1410671D00EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt */; }; 4C50AD0E1410679000EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar Resources */ = {isa = PBXBuildFile; fileRef = 4C50ACFF1410671D00EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt */; }; @@ -1132,6 +1426,20 @@ 5346481E173322BD00FE9172 /* KeychainSyncAccountNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 5346481D173322BD00FE9172 /* KeychainSyncAccountNotification.m */; }; 5346481F17332F9C00FE9172 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; 53C0E1FF177FB48A00F8A018 /* CloudKeychain.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53C0E1F1177FAC2C00F8A018 /* CloudKeychain.strings */; }; + 5A4E381B207529670047F40F /* SecProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A4E381A207529480047F40F /* SecProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5A4E381C207529680047F40F /* SecProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A4E381A207529480047F40F /* SecProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5A4E52792051D7FA009D5826 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 5A4E527B2051D857009D5826 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 5AC6BFAB2077CD310051737D /* SecProtocolTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AC6BFA52077CD130051737D /* SecProtocolTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5AC6BFAC2077CD310051737D /* SecProtocolTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AC6BFA52077CD130051737D /* SecProtocolTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5AF762FF2051F990001557AE /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A94C6D4203CC2590066E391 /* AuthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 5AF7630920520870001557AE /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A94C6D4203CC2590066E391 /* AuthKit.framework */; }; + 5AFCF32920746BC20010D4B5 /* SecProtocolOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32220746AD80010D4B5 /* SecProtocolOptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5AFCF32A20746BC30010D4B5 /* SecProtocolOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32220746AD80010D4B5 /* SecProtocolOptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5AFCF32B20746BC80010D4B5 /* SecProtocolMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32820746AE90010D4B5 /* SecProtocolMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5AFCF32C20746BC90010D4B5 /* SecProtocolMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32820746AE90010D4B5 /* SecProtocolMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5AFCF32E20746DA70010D4B5 /* SecProtocolObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32D20746D9A0010D4B5 /* SecProtocolObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5AFCF32F20746DA70010D4B5 /* SecProtocolObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32D20746D9A0010D4B5 /* SecProtocolObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5E10992619A5E55800A60E2B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; 5E10995119A5E5CE00A60E2B /* ISProtectedItems.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5E10994E19A5E5CE00A60E2B /* ISProtectedItems.plist */; }; 5E10995219A5E5CE00A60E2B /* ISProtectedItemsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E10995019A5E5CE00A60E2B /* ISProtectedItemsController.m */; }; @@ -1148,18 +1456,22 @@ 5E8B53A51AA0B8A600345E7B /* libcoreauthd_test_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E8B53A41AA0B8A600345E7B /* libcoreauthd_test_client.a */; }; 5EAFA4D31EF1605A002DC188 /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EAFA4CD1EF16059002DC188 /* LocalAuthentication.framework */; }; 5EBE247D1B00CCAE0007DB0E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 5EBE247C1B00CCAE0007DB0E /* main.c */; }; - 6C0B0C4B1E253848007F95E5 /* AwdMetadata-0x60-Keychain.bin in CopyFiles */ = {isa = PBXBuildFile; fileRef = 6C3446551E2534E800F9522B /* AwdMetadata-0x60-Keychain.bin */; }; 6C1260FD1F7DA42D001B2EEC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; 6C13AE471F8E9F5F00F047E3 /* supd.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69517E1F758E1000F68F91 /* supd.m */; }; 6C13AE481F8E9FC800F047E3 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; 6C1520D41DCCF71400C85C6D /* secd.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = 6C1520CD1DCCF57A00C85C6D /* secd.8 */; }; 6C1F93111DD5E41A00585608 /* libDiagnosticMessagesClient.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3C1D78F25C002223DE /* libDiagnosticMessagesClient.dylib */; }; + 6C32BB9920EAE6B00042DF59 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; }; + 6C32BB9A20EAE6B80042DF59 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; }; 6C3446301E24F6BE00F9522B /* CKKSRateLimiterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C34462F1E24F6BE00F9522B /* CKKSRateLimiterTests.m */; }; 6C3446461E25346C00F9522B /* CKKSRateLimiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC185971E24E87D009657D8 /* CKKSRateLimiter.h */; }; 6C3446471E25346C00F9522B /* CKKSRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC185981E24E87D009657D8 /* CKKSRateLimiter.m */; }; 6C4605A51F882B9B001421B6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; 6C4605BC1F882DB6001421B6 /* SFAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C1A29FC1F882788002312D8 /* SFAnalyticsTests.m */; }; 6C4605BD1F882DC3001421B6 /* SupdTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C758CB01F8826100075BD78 /* SupdTests.m */; }; + 6C4F98252075833E00A3C5AB /* OCMock.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 6C53A447206AB1A6000FA611 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; }; + 6C53A44D206AB1EF000FA611 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; }; 6C588D7F1EAA14AA00D7E322 /* RateLimiterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C588D791EAA149F00D7E322 /* RateLimiterTests.m */; }; 6C588D801EAA20AB00D7E322 /* RateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC7F5B31E9F99EE0014AE63 /* RateLimiter.m */; }; 6C588D811EAA20AC00D7E322 /* RateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC7F5B31E9F99EE0014AE63 /* RateLimiter.m */; }; @@ -1172,16 +1484,10 @@ 6C73F48F2006B910003D5D63 /* SOSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C7BB0042006B4EF004D1B6B /* SOSAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6C73F4902006B911003D5D63 /* SOSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C7BB0042006B4EF004D1B6B /* SOSAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6C7FD5DF1F87FA42002C2285 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + 6C814A4C2050B4B600CB391B /* LocalKeychainAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C814A4A2050B4B600CB391B /* LocalKeychainAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6C814A4D2050B4B600CB391B /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; }; 6C869A751F50CAF400957298 /* SOSEnsureBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C860C7A1F4F63DB004100A1 /* SOSEnsureBackup.m */; }; 6C869A761F50CAF500957298 /* SOSEnsureBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C860C7A1F4F63DB004100A1 /* SOSEnsureBackup.m */; }; - 6C869A791F54C37900957298 /* AWDKeychainSOSKeychainBackupFailed.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C869A771F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.m */; }; - 6C869A7A1F54C37A00957298 /* AWDKeychainSOSKeychainBackupFailed.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C869A771F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.m */; }; - 6C8CC3AB1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterAggregatedScores.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446501E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.m */; }; - 6C8CC3AC1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterOverload.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446521E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.m */; }; - 6C8CC3AD1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterTopWriters.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446541E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.m */; }; - 6C8CC3B31E2F913D009025C5 /* AWDKeychainCKKSRateLimiterAggregatedScores.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446501E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.m */; }; - 6C8CC3B41E2F913D009025C5 /* AWDKeychainCKKSRateLimiterOverload.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446521E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.m */; }; - 6C8CC3B51E2F913D009025C5 /* AWDKeychainCKKSRateLimiterTopWriters.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446541E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.m */; }; 6C8CC3B61E2F98C2009025C5 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 6C8CE6C11FA248DA0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C8CE6BB1FA248B50032ADF0 /* SFAnalyticsActivityTracker+Internal.h */; }; 6C8CE6C21FA248DB0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C8CE6BB1FA248B50032ADF0 /* SFAnalyticsActivityTracker+Internal.h */; }; @@ -1251,6 +1557,8 @@ 6CAA8D3A1F8431A7007B6E03 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; 6CAA8D3B1F8431AE007B6E03 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40B6A881E2B5F9900CD6EE5 /* Foundation.framework */; }; 6CAB39C71E521BEA00566A79 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + 6CB420A52051FDD500FF2D44 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; }; + 6CB420AB2051FDE000FF2D44 /* LocalKeychainAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C814A4A2050B4B600CB391B /* LocalKeychainAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6CB5F47B1E402E6700DBF3F0 /* KeychainEntitledTestRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CB5F47A1E402E5700DBF3F0 /* KeychainEntitledTestRunner.m */; }; 6CB96BAC1F966D6500E11457 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C6951801F758E1000F68F91 /* main.m */; }; 6CB96BB21F966DA400E11457 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; @@ -1306,14 +1614,9 @@ 6CF4A0B81E45488B00ECD7B5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0B71E45488B00ECD7B5 /* AppDelegate.m */; }; 6CF4A0BB1E45488B00ECD7B5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0BA1E45488B00ECD7B5 /* main.m */; }; 6CF4A0BE1E45488B00ECD7B5 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0BD1E45488B00ECD7B5 /* ViewController.m */; }; - 6CF4A0C01E45488B00ECD7B5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0BF1E45488B00ECD7B5 /* Assets.xcassets */; }; - 6CF4A0C31E45488B00ECD7B5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0C11E45488B00ECD7B5 /* Main.storyboard */; }; 6CF4A0E41E4549F200ECD7B5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0E31E4549F200ECD7B5 /* main.m */; }; 6CF4A0E71E4549F300ECD7B5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0E61E4549F300ECD7B5 /* AppDelegate.m */; }; 6CF4A0EA1E4549F300ECD7B5 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0E91E4549F300ECD7B5 /* ViewController.m */; }; - 6CF4A0ED1E4549F300ECD7B5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0EB1E4549F300ECD7B5 /* Main.storyboard */; }; - 6CF4A0EF1E4549F300ECD7B5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0EE1E4549F300ECD7B5 /* Assets.xcassets */; }; - 6CF4A0F21E4549F300ECD7B5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0F01E4549F300ECD7B5 /* LaunchScreen.storyboard */; }; 6CFDC4551F907D2600646DBB /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; 7200D76F177B9999009BB396 /* ManagedConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72C3EC2D1705F24E0040C87C /* ManagedConfiguration.framework */; }; 724340BA1ED3FEC800F8F566 /* SecSMIME.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870D1D778FA900B50D50 /* SecSMIME.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -1360,6 +1663,15 @@ 79EF5B730D3D6AFE009F5270 /* p12import.h in Headers */ = {isa = PBXBuildFile; fileRef = 79EF5B720D3D6AFE009F5270 /* p12import.h */; }; 8E02FA6B1107BE460043545E /* pbkdf2.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E02FA691107BE460043545E /* pbkdf2.h */; settings = {ATTRIBUTES = (Private, ); }; }; 8ED6F6CA110904E300D2B368 /* SecPBKDF.h in Headers */ = {isa = PBXBuildFile; fileRef = 8ED6F6C8110904E300D2B368 /* SecPBKDF.h */; settings = {ATTRIBUTES = (Private, ); }; }; + A690B033208A75D1002FB775 /* notarization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6B1BA78207BD9D400F1E099 /* notarization.cpp */; }; + A6B1BA81207BD9EC00F1E099 /* notarization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6B1BA78207BD9D400F1E099 /* notarization.cpp */; }; + A6B1BA82207BDCB200F1E099 /* notarization.h in Headers */ = {isa = PBXBuildFile; fileRef = A6B1BA79207BD9D400F1E099 /* notarization.h */; }; + AA44E0D520325150001EA371 /* SecProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0D02032513F001EA371 /* SecProtocol.c */; }; + AA44E0D620325150001EA371 /* SecProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0D02032513F001EA371 /* SecProtocol.c */; }; + AA44E0D72032515C001EA371 /* SecProtocolTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0D120325140001EA371 /* SecProtocolTypes.m */; }; + AA44E0D82032515C001EA371 /* SecProtocolTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0D120325140001EA371 /* SecProtocolTypes.m */; }; + AA44E0DE2032519E001EA371 /* SecProtocolPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = AA44E0D920325177001EA371 /* SecProtocolPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + AA44E0DF2032519F001EA371 /* SecProtocolPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = AA44E0D920325177001EA371 /* SecProtocolPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; ACBAF6EE1E941AE00007BA2F /* transform_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = ACBAF6E31E941AE00007BA2F /* transform_regressions.h */; }; ACBAF6EF1E941AE00007BA2F /* transform_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = ACBAF6E31E941AE00007BA2F /* transform_regressions.h */; }; ACBAF6F91E941B020007BA2F /* transform-01-sigverify.m in Sources */ = {isa = PBXBuildFile; fileRef = ACBAF6E51E941AE00007BA2F /* transform-01-sigverify.m */; }; @@ -1379,7 +1691,6 @@ BE197F5C1911724900BA91D1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE411314471B000DE34E /* UIKit.framework */; }; BE197F5E191173A800BA91D1 /* SWCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE197F5D191173A800BA91D1 /* SWCViewController.m */; }; BE197F61191173F200BA91D1 /* entitlements.plist in Resources */ = {isa = PBXBuildFile; fileRef = BE197F60191173F200BA91D1 /* entitlements.plist */; }; - BE1F74D31F609D460068FA64 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; BE22FBC61EE0E8AB00893431 /* Monkey.m in Sources */ = {isa = PBXBuildFile; fileRef = BE22FBC51EE0E8AB00893431 /* Monkey.m */; }; BE22FBCE1EE1E26600893431 /* Keychain.m in Sources */ = {isa = PBXBuildFile; fileRef = BE22FBCD1EE1E26600893431 /* Keychain.m */; }; BE22FBD11EE2084100893431 /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = BE22FBD01EE2084100893431 /* Config.m */; }; @@ -1416,7 +1727,6 @@ BEB0B0DD1FFC45D7007E6A83 /* OTPrivateKey+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */; }; BEB0B0DE1FFC45D8007E6A83 /* OTPrivateKey+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */; }; BEB9E9EC1FFF195C00676593 /* si-88-sectrust-valid.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB9E9E51FFF193D00676593 /* si-88-sectrust-valid.m */; }; - BEB9EA2F1FFF1AF700676593 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */; }; BEB9EA301FFF1B0800676593 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */; }; BED208D81EDF950E00753952 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; BED208D91EDF950E00753952 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; @@ -1478,18 +1788,8 @@ BEF88C9C1EB000FD00357577 /* TPPolicyDocumentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C741EB0008E00357577 /* TPPolicyDocumentTests.m */; }; BEF88C9D1EB000FD00357577 /* TPUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C751EB0008E00357577 /* TPUtilsTests.m */; }; BEF88C9E1EB000FD00357577 /* TPVoucherTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C761EB0008E00357577 /* TPVoucherTests.m */; }; - CD0637551A84060600C81E74 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; - CD0637561A84065F00C81E74 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; - CD0637571A84068F00C81E74 /* IDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD744683195A00BB00FB01C0 /* IDS.framework */; }; CD112FC51DDA31AD00C77A07 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; CD198F971DE27B9E00F6FB83 /* SOSAccountPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = CD9021471DE27A9E00F81DC4 /* SOSAccountPriv.h */; }; - CD23B49E1DA06EB40047EDE9 /* IDSPersistentState.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B4931DA06EB30047EDE9 /* IDSPersistentState.m */; }; - CD23B4A01DA06EB40047EDE9 /* IDSProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B4951DA06EB30047EDE9 /* IDSProxy.m */; }; - CD23B4A11DA06EB40047EDE9 /* keychainsyncingoveridsproxy.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B4961DA06EB30047EDE9 /* keychainsyncingoveridsproxy.m */; }; - CD23B4A31DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B4981DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m */; }; - CD23B4A51DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B49A1DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m */; }; - CD276C281A83F60C003226BC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; - CD51245E1DA1C67000962524 /* com.apple.private.alloy.keychainsync.plist in Install alloy plist */ = {isa = PBXBuildFile; fileRef = CD23B4A81DA06ED10047EDE9 /* com.apple.private.alloy.keychainsync.plist */; }; CD791B3C1DFC9A7600F0E5DC /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CD2F99D91DFC995B00769430 /* libsqlite3.0.dylib */; }; CD791B3D1DFC9AB200F0E5DC /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; CD9F2AF81DF23CA600AD3577 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; @@ -1536,13 +1836,14 @@ D43761661EB2996C00954447 /* SecRevocationNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = D43761641EB2996C00954447 /* SecRevocationNetworking.h */; }; D43761671EB2996C00954447 /* SecRevocationNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = D43761651EB2996C00954447 /* SecRevocationNetworking.m */; }; D43B88721E72298500F86F19 /* MobileAsset.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7273402816CAFB3C0096622A /* MobileAsset.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - D43DBEFB1E99D1CA00C04AEA /* asynchttp.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBED51E99D17100C04AEA /* asynchttp.c */; }; + D43D8B2C20AB8A48005BEEC4 /* Security.apinotes in Headers */ = {isa = PBXBuildFile; fileRef = D44D08B420AB890E0023C439 /* Security.apinotes */; settings = {ATTRIBUTES = (Public, ); }; }; + D43D8B2D20AB8A54005BEEC4 /* Security.apinotes in Headers */ = {isa = PBXBuildFile; fileRef = D44D08B420AB890E0023C439 /* Security.apinotes */; settings = {ATTRIBUTES = (Public, ); }; }; D43DBEFC1E99D1CA00C04AEA /* nameconstraints.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBED71E99D17100C04AEA /* nameconstraints.c */; }; D43DBEFD1E99D1CA00C04AEA /* OTATrustUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D43DBED91E99D17100C04AEA /* OTATrustUtilities.m */; }; D43DBEFE1E99D1CA00C04AEA /* personalization.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEDB1E99D17100C04AEA /* personalization.c */; }; D43DBEFF1E99D1CA00C04AEA /* policytree.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEDD1E99D17100C04AEA /* policytree.c */; }; D43DBF001E99D1CA00C04AEA /* SecCAIssuerCache.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEDF1E99D17200C04AEA /* SecCAIssuerCache.c */; }; - D43DBF011E99D1CA00C04AEA /* SecCAIssuerRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.c */; }; + D43DBF011E99D1CA00C04AEA /* SecCAIssuerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.m */; }; D43DBF021E99D1CA00C04AEA /* SecCertificateServer.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE31E99D17200C04AEA /* SecCertificateServer.c */; }; D43DBF031E99D1CA00C04AEA /* SecCertificateSource.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE51E99D17200C04AEA /* SecCertificateSource.c */; }; D43DBF041E99D1CA00C04AEA /* SecOCSPCache.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE71E99D17200C04AEA /* SecOCSPCache.c */; }; @@ -1558,12 +1859,7 @@ D447C4101D3094740082FC1D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; D450686A1E948D2200FA7675 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; D453C3901FEC66AE00DE349B /* trust_update.m in Sources */ = {isa = PBXBuildFile; fileRef = D453C38A1FEC669300DE349B /* trust_update.m */; }; - D4574AA0203E618B006D9B82 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - D4574AA1203E6893006D9B82 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - D4574AA2203E68C8006D9B82 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A94C6D4203CC2590066E391 /* AuthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - D4574AA3203E68E0006D9B82 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A94C6D4203CC2590066E391 /* AuthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; D45917E41DC13E6700752D25 /* SecCertificateRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E3E1D8085FC00865A7C /* SecCertificateRequest.c */; }; - D459A1781E9FFE60009ED74B /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; D46246971F9AE2E400D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246911F9AE2E400D63882 /* libDER.a */; }; D46246A31F9AE59E00D63882 /* oids.h in Headers */ = {isa = PBXBuildFile; fileRef = D46246A21F9AE49E00D63882 /* oids.h */; settings = {ATTRIBUTES = (Private, ); }; }; D46246A61F9AE61000D63882 /* oids.c in Sources */ = {isa = PBXBuildFile; fileRef = D462469C1F9AE45900D63882 /* oids.c */; }; @@ -1583,6 +1879,9 @@ D46246C91F9AEA5300D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246C31F9AEA5200D63882 /* libDER.a */; }; D46246D41F9AEAE300D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246CE1F9AEAE300D63882 /* libDER.a */; }; D46246D91F9AED5D00D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246CE1F9AEAE300D63882 /* libDER.a */; }; + D465131A2097FF2E005D93FE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0EB1E4549F300ECD7B5 /* Main.storyboard */; }; + D465131B2097FF2E005D93FE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0EE1E4549F300ECD7B5 /* Assets.xcassets */; }; + D465131C2097FF2E005D93FE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0F01E4549F300ECD7B5 /* LaunchScreen.storyboard */; }; D479F6E21F980FAB00388D28 /* Trust.strings in Resources */ = {isa = PBXBuildFile; fileRef = D479F6DF1F980F8F00388D28 /* Trust.strings */; }; D479F6E31F981FD600388D28 /* OID.strings in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C198F1F0ACDB4BF00AAB142 /* OID.strings */; }; D479F6E41F981FD600388D28 /* Certificate.strings in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C198F1D0ACDB4BF00AAB142 /* Certificate.strings */; }; @@ -1594,7 +1893,28 @@ D487B9881DFA2902000410A1 /* SecInternalReleasePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC771D8C68CF00070CB0 /* SecInternalReleasePriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; D487FBB81DB8357300D4BB0B /* si-29-sectrust-sha1-deprecation.m in Sources */ = {isa = PBXBuildFile; fileRef = D487FBB71DB8357300D4BB0B /* si-29-sectrust-sha1-deprecation.m */; }; D487FBBA1DB835B500D4BB0B /* si-29-sectrust-sha1-deprecation.h in Headers */ = {isa = PBXBuildFile; fileRef = D487FBB91DB835B500D4BB0B /* si-29-sectrust-sha1-deprecation.h */; }; + D48BD18D206C45F00075DDC9 /* si-89-cms-hash-agility.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */; }; + D48BD194206C47530075DDC9 /* si-35-cms-expiration-time.m in Sources */ = {isa = PBXBuildFile; fileRef = D48BD193206C47530075DDC9 /* si-35-cms-expiration-time.m */; }; D48E4E241E42F0620011B4BA /* si-62-csr.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DDA1D8085FC00865A7C /* si-62-csr.m */; }; + D491112C209515400066A1E4 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; }; + D491112D209515400066A1E4 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; }; + D491112E209515400066A1E4 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; }; + D491112F2095154B0066A1E4 /* MainMenu.xib in Sources */ = {isa = PBXBuildFile; fileRef = DC0B622D1D909C4600D43BCB /* MainMenu.xib */; }; + D49111302095154B0066A1E4 /* MainMenu.xib in Sources */ = {isa = PBXBuildFile; fileRef = DC0B622D1D909C4600D43BCB /* MainMenu.xib */; }; + D49111312095154B0066A1E4 /* Main.storyboard in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0C11E45488B00ECD7B5 /* Main.storyboard */; }; + D49111322095154B0066A1E4 /* Assets.xcassets in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0BF1E45488B00ECD7B5 /* Assets.xcassets */; }; + D49111692095593D0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D491116A2095593E0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D491116B2095593E0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D491116C2095594A0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D491116D2095594B0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D491116E209559510066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D491116F209559510066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D49111702095595B0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D4911171209559620066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; }; + D4911172209559630066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D4911173209559630066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D4961BC42079424200F16DA7 /* TrustURLSessionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D4961BBD2079423300F16DA7 /* TrustURLSessionDelegate.m */; }; D4AA64361E95D92600D317ED /* com.apple.trustd.sb in Copy Sandbox */ = {isa = PBXBuildFile; fileRef = D41257EB1E941CF200781F23 /* com.apple.trustd.sb */; }; D4AA643C1E95D93100D317ED /* com.apple.trustd.plist in Copy LaunchDaemon Files */ = {isa = PBXBuildFile; fileRef = D41257EA1E941CF200781F23 /* com.apple.trustd.plist */; }; D4AA643D1E95D93900D317ED /* com.apple.trustd.agent.plist in Copy LaunchAgent */ = {isa = PBXBuildFile; fileRef = D41257E91E941CF200781F23 /* com.apple.trustd.agent.plist */; }; @@ -1609,6 +1929,7 @@ D4ADA32F1E2B43220031CEA3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; D4ADA3301E2B433B0031CEA3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; D4ADA3311E2B43450031CEA3 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; + D4B6D57C2069D8450099FBEF /* si-34-cms-timestamp.m in Sources */ = {isa = PBXBuildFile; fileRef = D4B6D57B2069D8450099FBEF /* si-34-cms-timestamp.m */; }; D4B858671D370D9A003B2D95 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4B858661D370D9A003B2D95 /* MobileCoreServices.framework */; }; D4BEECE81E93094500F76D1A /* trustd.c in Sources */ = {isa = PBXBuildFile; fileRef = D4BEECE61E93093A00F76D1A /* trustd.c */; }; D4C263CE1F95300F001317EA /* SecErrorMessages.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4C263CC1F952F6C001317EA /* SecErrorMessages.strings */; }; @@ -1633,11 +1954,16 @@ DA19DAEF1FCFA420008E82EE /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; DA19DAF01FCFA425008E82EE /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; DA30D6851DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30D6841DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m */; }; + DA5B871C2065A8440093F083 /* SecAutorelease.h in Headers */ = {isa = PBXBuildFile; fileRef = DA5B871A2065A8410093F083 /* SecAutorelease.h */; }; + DA5B871D2065A8440093F083 /* SecAutorelease.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5B871B2065A8430093F083 /* SecAutorelease.m */; }; DA6AA1651FE88AFB004565B0 /* CKKSControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */; }; DA6AA1661FE88AFB004565B0 /* CKKSControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */; }; DA6AA1671FE88AFB004565B0 /* CKKSControlServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */; }; DA6AA1681FE88AFB004565B0 /* CKKSControlServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */; }; DAB27AE11FA29EE300DEBBDE /* SOSControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAB27AE01FA29EB800DEBBDE /* SOSControlServer.m */; }; + DAE40BC920CF3E46002D5674 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; + DAE40BCA20CF3E46002D5674 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + DAE40BD920CF3F0F002D5674 /* secitemcanarytest.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE40BD820CF3F04002D5674 /* secitemcanarytest.m */; }; DAEE055C1FAD3FC700DF27F3 /* AutoreleaseTest.c in Sources */ = {isa = PBXBuildFile; fileRef = DAEE05551FAD3FC500DF27F3 /* AutoreleaseTest.c */; }; DC0067C11D87879D005AF8DB /* ucspServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82811D87734600418608 /* ucspServer.cpp */; }; DC0067C21D8787A4005AF8DB /* ucspNotifyReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82831D87734600418608 /* ucspNotifyReceiver.cpp */; }; @@ -1690,6 +2016,7 @@ DC00ABF11D821FC400513D74 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; DC00ABF21D821FC800513D74 /* libSOSRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC681D80D0C400B0A59C /* libSOSRegressions.a */; }; DC00ABF31D821FCD00513D74 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + DC066DF02102563300694EAF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; DC08D1C41E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */; }; DC08D1CC1E64FCC5006237DA /* CKKSSOSTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC08D1CB1E64FCC5006237DA /* CKKSSOSTests.m */; }; DC0950411E38271300B2C8AC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; @@ -1699,8 +2026,6 @@ DC0B62291D90974600D43BCB /* si-25-cms-skid.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0B62271D90973900D43BCB /* si-25-cms-skid.m */; }; DC0B622A1D9097C600D43BCB /* libsecurity_cms_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1002CB1D8E19D70025549C /* libsecurity_cms_regressions.a */; }; DC0B622C1D90982C00D43BCB /* secd-201-coders.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0B622B1D90982100D43BCB /* secd-201-coders.m */; }; - DC0B622F1D909C4600D43BCB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DC0B622D1D909C4600D43BCB /* MainMenu.xib */; }; - DC0B62301D909C4600D43BCB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DC0B622D1D909C4600D43BCB /* MainMenu.xib */; }; DC0BC5611D8B6D6000070CB0 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC5461D8B6AFE00070CB0 /* main.c */; }; DC0BC5621D8B6D7000070CB0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; }; DC0BC5671D8B6E3D00070CB0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; }; @@ -2608,7 +2933,6 @@ DC52E8CB1D80C2FD00B0A59C /* SOSTransportCircleKVS.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D7A1D8085F200865A7C /* SOSTransportCircleKVS.m */; }; DC52E8CC1D80C2FD00B0A59C /* SOSTransportKeyParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D7C1D8085F200865A7C /* SOSTransportKeyParameter.m */; }; DC52E8CE1D80C2FD00B0A59C /* SOSTransportMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D801D8085F200865A7C /* SOSTransportMessage.m */; }; - DC52E8CF1D80C2FD00B0A59C /* SOSTransportMessageIDS.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D821D8085F200865A7C /* SOSTransportMessageIDS.m */; }; DC52E8D01D80C2FD00B0A59C /* SOSTransportMessageKVS.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D841D8085F200865A7C /* SOSTransportMessageKVS.m */; }; DC52E8DD1D80C31F00B0A59C /* SOSCoder.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D511D8085F200865A7C /* SOSCoder.c */; }; DC52E8DE1D80C31F00B0A59C /* SOSDigestVector.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D541D8085F200865A7C /* SOSDigestVector.c */; }; @@ -2637,7 +2961,6 @@ DC52E90C1D80C3D900B0A59C /* SOSBackupEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D281D8085F200865A7C /* SOSBackupEvent.h */; }; DC52E9101D80C3EF00B0A59C /* SOSAccountLog.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D211D8085F200865A7C /* SOSAccountLog.h */; }; DC52E9161D80C41A00B0A59C /* SOSPeerInfoInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D6C1D8085F200865A7C /* SOSPeerInfoInternal.h */; }; - DC52E9191D80C42F00B0A59C /* SOSTransportMessageIDS.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D831D8085F200865A7C /* SOSTransportMessageIDS.h */; }; DC52E91A1D80C43500B0A59C /* SOSRing.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D391D8085F200865A7C /* SOSRing.h */; }; DC52E91C1D80C43F00B0A59C /* SOSPeerCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D5F1D8085F200865A7C /* SOSPeerCoder.h */; }; DC52E91D1D80C44400B0A59C /* SOSCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D521D8085F200865A7C /* SOSCoder.h */; }; @@ -2729,7 +3052,6 @@ DC52ECD51D80D22600B0A59C /* si-78-query-attrs.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E011D8085FC00865A7C /* si-78-query-attrs.c */; }; DC52ECD61D80D22600B0A59C /* si-80-empty-data.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E021D8085FC00865A7C /* si-80-empty-data.c */; }; DC52ECD91D80D22600B0A59C /* si-82-token-ag.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E051D8085FC00865A7C /* si-82-token-ag.c */; }; - DC52ECDD1D80D22600B0A59C /* si-89-cms-hash-agility.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */; }; DC52ECDE1D80D22600B0A59C /* si-90-emcs.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E0D1D8085FC00865A7C /* si-90-emcs.m */; }; DC52ECDF1D80D22600B0A59C /* si-95-cms-basic.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E0E1D8085FC00865A7C /* si-95-cms-basic.c */; }; DC52ECE11D80D2F000B0A59C /* otr-00-identity.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DA71D8085FC00865A7C /* otr-00-identity.c */; }; @@ -2789,7 +3111,6 @@ DC52EDE21D80D5C500B0A59C /* secd-74-engine-beer-servers.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C661D8085D800865A7C /* secd-74-engine-beer-servers.m */; }; DC52EDE31D80D5C500B0A59C /* secd-75-engine-views.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C671D8085D800865A7C /* secd-75-engine-views.m */; }; DC52EDE61D80D5C500B0A59C /* secd-80-views-basic.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6A1D8085D800865A7C /* secd-80-views-basic.m */; }; - DC52EDE71D80D5C500B0A59C /* secd-82-secproperties-basic.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6B1D8085D800865A7C /* secd-82-secproperties-basic.m */; }; DC52EDE81D80D5C500B0A59C /* secd-81-item-acl-stress.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6C1D8085D800865A7C /* secd-81-item-acl-stress.m */; }; DC52EDE91D80D5C500B0A59C /* secd-81-item-acl.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6D1D8085D800865A7C /* secd-81-item-acl.m */; }; DC52EDEA1D80D5C500B0A59C /* secd-82-persistent-ref.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6E1D8085D800865A7C /* secd-82-persistent-ref.m */; }; @@ -2836,16 +3157,16 @@ DC52EE611D80D79E00B0A59C /* si-71-mobile-store-policy.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DFB1D8085FC00865A7C /* si-71-mobile-store-policy.c */; }; DC52EE6F1D80D83F00B0A59C /* SecPasswordGenerate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7A1D8085FC00865A7C /* SecPasswordGenerate.c */; }; DC52EE701D80D84700B0A59C /* SecItemConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5C1D8085FC00865A7C /* SecItemConstants.c */; }; - DC52EE711D80D85F00B0A59C /* SecECKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.c */; }; + DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.m */; }; DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; DC52EE731D80D86800B0A59C /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; }; DC52EE741D80D86F00B0A59C /* SecAccessControl.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E301D8085FC00865A7C /* SecAccessControl.c */; }; - DC52EE761D80D87F00B0A59C /* SecCTKKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.c */; }; + DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.m */; }; DC52EE771D80D88300B0A59C /* SecDH.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E461D8085FC00865A7C /* SecDH.c */; }; DC52EE781D80D88800B0A59C /* SecRSAKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E851D8085FC00865A7C /* SecRSAKey.c */; }; DC52EE791D80D88D00B0A59C /* SecItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E581D8085FC00865A7C /* SecItem.c */; }; DC52EE7A1D80D89400B0A59C /* SecCFAllocator.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E401D8085FC00865A7C /* SecCFAllocator.c */; }; - DC52EE7B1D80D89900B0A59C /* SecKeyAdaptors.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */; }; + DC52EE7B1D80D89900B0A59C /* SecKeyAdaptors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */; }; DC52EE7C1D80D89E00B0A59C /* SecItemBackup.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5A1D8085FC00865A7C /* SecItemBackup.c */; }; DC54DD0F1EA7D9E700108E92 /* CKKSManifestLeafRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 476D873A1E6750E200190352 /* CKKSManifestLeafRecord.m */; }; DC54DD101EA7D9E800108E92 /* CKKSManifestLeafRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 476D873A1E6750E200190352 /* CKKSManifestLeafRecord.m */; }; @@ -3017,6 +3338,11 @@ DC5AC12A1D83555A00CF422C /* SharedMemoryServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFD21D83511A00CF422C /* SharedMemoryServer.h */; }; DC5AC12B1D83555A00CF422C /* self.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5AC0FF1D83550300CF422C /* self.h */; }; DC5AC12D1D83560100CF422C /* securityd_dtrace.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFD91D83512A00CF422C /* securityd_dtrace.h */; }; + DC5B391720C08B38005B09F6 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + DC5B391820C08B39005B09F6 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + DC5B391A20C08B70005B09F6 /* SecBase.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC5860220BF8A98005C7269 /* SecBase.c */; }; + DC5B391B20C08BDC005B09F6 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + DC5B391C20C08BF1005B09F6 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; DC5BB4FA1E0C90DE0010F836 /* CKKSIncomingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4F11E0C86800010F836 /* CKKSIncomingQueueOperation.m */; }; DC5BB4FB1E0C90DF0010F836 /* CKKSIncomingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4F11E0C86800010F836 /* CKKSIncomingQueueOperation.m */; }; DC5BB4FE1E0C98320010F836 /* CKKSOutgoingQueueOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5BB4FC1E0C98320010F836 /* CKKSOutgoingQueueOperation.h */; }; @@ -3062,13 +3388,13 @@ DC610AB11D7910C3002223DE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; }; DC610ABA1D7910F8002223DE /* gk_reset_check.c in Sources */ = {isa = PBXBuildFile; fileRef = DC610AB91D7910F8002223DE /* gk_reset_check.c */; }; DC63CAF81D91A15F00C03317 /* libsecurity_cms_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1002CB1D8E19D70025549C /* libsecurity_cms_regressions.a */; }; + DC63D70820B3931100D088AD /* libxar.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DC63D70220B3930700D088AD /* libxar.tbd */; }; DC6593D11ED8DAB900C19462 /* CKKSTests+CurrentPointerAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6593C91ED8DA9200C19462 /* CKKSTests+CurrentPointerAPI.m */; }; DC65E7231D8CB28900152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC65E7241D8CB29E00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC65E7271D8CB2EC00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC65E72A1D8CB2FC00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC65E7301D8CB32D00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; - DC65E7311D8CB33800152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC65E7361D8CB35E00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC65E7371D8CB37500152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC65E73C1D8CB39B00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; @@ -3186,6 +3512,7 @@ DC71D9D81D95BA6C0065FB93 /* secasn1d.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88343A1D8A21AA00CE0ACA /* secasn1d.c */; }; DC71D9D91D95BA6C0065FB93 /* SecAsn1Coder.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88340A1D8A21AA00CE0ACA /* SecAsn1Coder.c */; }; DC71D9DA1D95BA6C0065FB93 /* secasn1u.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88343D1D8A21AA00CE0ACA /* secasn1u.c */; }; + DC72BCD720B3A7DF00B26495 /* libOpenScriptingUtil.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DC63D70920B3933000D088AD /* libOpenScriptingUtil.tbd */; settings = {ATTRIBUTES = (Weak, ); }; }; DC7341F31F8447AB00AB9BDF /* CKKSTLKShare.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7341F11F8447AB00AB9BDF /* CKKSTLKShare.h */; }; DC7341F41F8447AB00AB9BDF /* CKKSTLKShare.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7341F11F8447AB00AB9BDF /* CKKSTLKShare.h */; }; DC7341F51F8447AB00AB9BDF /* CKKSTLKShare.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7341F21F8447AB00AB9BDF /* CKKSTLKShare.m */; }; @@ -3223,6 +3550,7 @@ DC8834911D8A21AB00CE0ACA /* oidsalg.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834491D8A21AA00CE0ACA /* oidsalg.c */; }; DC8834931D8A21AB00CE0ACA /* oidsattr.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88344B1D8A21AA00CE0ACA /* oidsattr.c */; }; DC8834961D8A21AB00CE0ACA /* oidsocsp.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88344E1D8A21AA00CE0ACA /* oidsocsp.c */; }; + DC8D238D2064649400E163C8 /* CKKSAPSHandlingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC8D238C2064649400E163C8 /* CKKSAPSHandlingTests.m */; }; DC8EB58D1F70743100080CF2 /* SOSPeerInfoV2.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D681D8085F200865A7C /* SOSPeerInfoV2.h */; }; DC9036B31D9DFED600B6C234 /* ss_types.defs in Headers */ = {isa = PBXBuildFile; fileRef = DC6A82771D87733C00418608 /* ss_types.defs */; settings = {ATTRIBUTES = (Public, ); }; }; DC9082C41EA0277600D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */; }; @@ -3277,6 +3605,8 @@ DCAD9B461F8D939C00C5E2AE /* CKKSFixups.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAD9B431F8D939C00C5E2AE /* CKKSFixups.m */; }; DCAD9B471F8D939C00C5E2AE /* CKKSFixups.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAD9B431F8D939C00C5E2AE /* CKKSFixups.m */; }; DCAD9B491F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAD9B481F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m */; }; + DCAE1DDD2073FDCC00B4F687 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; }; + DCAE1DDE2073FDCD00B4F687 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; }; DCB221501E8B08A5001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; DCB221511E8B08A6001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; DCB221531E8B08BC001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; @@ -3666,6 +3996,9 @@ DCC0937F1D80B0B100F984E4 /* SecOTRMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF715AFB73800B9D400 /* SecOTRMath.h */; }; DCC093801D80B0B700F984E4 /* SecCFAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */; }; DCC19F711EB9151B00B7D70F /* KeychainCKKS.plist in Copy BATS Test Discovery Plist */ = {isa = PBXBuildFile; fileRef = 6CB5F4781E402E5700DBF3F0 /* KeychainCKKS.plist */; }; + DCC585FF20BF8A7E005C7269 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + DCC5860020BF8A7E005C7269 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + DCC5860320BF8A98005C7269 /* SecBase.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC5860120BF8A98005C7269 /* SecBase.h */; }; DCC5BF1B1D93723A008D1E84 /* libsecurity_apple_csp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCF783141D88B4DE00E694BB /* libsecurity_apple_csp.a */; }; DCC5BF1C1D937242008D1E84 /* libsecurity_apple_cspdl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCF785E51D88B95500E694BB /* libsecurity_apple_cspdl.a */; }; DCC5BF1D1D937249008D1E84 /* libsecurity_apple_file_dl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCF7883B1D88C8C400E694BB /* libsecurity_apple_file_dl.a */; }; @@ -3710,21 +4043,20 @@ DCC78ED01D808A8800865A7C /* SecOTRMath.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E6E1D8085FC00865A7C /* SecOTRMath.c */; }; DCC78ED11D808A8E00865A7C /* SecOTRFullIdentity.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E6C1D8085FC00865A7C /* SecOTRFullIdentity.c */; }; DCC78ED21D808A9500865A7C /* SecOTRDHKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E691D8085FC00865A7C /* SecOTRDHKey.c */; }; - DCC78ED31D808AA000865A7C /* SecKeyAdaptors.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */; }; + DCC78ED31D808AA000865A7C /* SecKeyAdaptors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */; }; DCC78ED41D808AA800865A7C /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; }; DCC78ED51D808AAE00865A7C /* SecItemConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5C1D8085FC00865A7C /* SecItemConstants.c */; }; DCC78ED61D808ABA00865A7C /* SecItemBackup.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5A1D8085FC00865A7C /* SecItemBackup.c */; }; DCC78ED71D808AC000865A7C /* SecItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E581D8085FC00865A7C /* SecItem.c */; }; DCC78ED81D808AC600865A7C /* SecImportExport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E551D8085FC00865A7C /* SecImportExport.c */; }; DCC78ED91D808ACB00865A7C /* SecIdentity.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E521D8085FC00865A7C /* SecIdentity.c */; }; - DCC78EDA1D808AD100865A7C /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; DCC78EDB1D808ADF00865A7C /* SecEMCS.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4C1D8085FC00865A7C /* SecEMCS.m */; }; - DCC78EDC1D808AE500865A7C /* SecECKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.c */; }; + DCC78EDC1D808AE500865A7C /* SecECKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.m */; }; DCC78EDD1D808AEC00865A7C /* SecDigest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E481D8085FC00865A7C /* SecDigest.c */; }; DCC78EDE1D808AF100865A7C /* SecDH.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E461D8085FC00865A7C /* SecDH.c */; }; DCC78EDF1D808AF800865A7C /* SecCertificateRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E3E1D8085FC00865A7C /* SecCertificateRequest.c */; }; DCC78EE11D808B0900865A7C /* SecCertificate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E381D8085FC00865A7C /* SecCertificate.c */; }; - DCC78EE21D808B0E00865A7C /* SecCTKKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.c */; }; + DCC78EE21D808B0E00865A7C /* SecCTKKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.m */; }; 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 */; }; @@ -4122,6 +4454,12 @@ DCD22D9B1D8CCFCB001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; DCD22D9C1D8CCFD6001C9B81 /* libutilitiesRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCD481D8C694700070CB0 /* libutilitiesRegressions.a */; }; DCD3EABA1DB599B800DF59BE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + DCD45355209A5B260086CBFC /* si-cms-signing-identity-p12.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD45353209A5B260086CBFC /* si-cms-signing-identity-p12.h */; }; + DCD45357209A5BA10086CBFC /* si-cms-signing-identity-p12.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD45354209A5B260086CBFC /* si-cms-signing-identity-p12.c */; }; + DCD4535A209A60DD0086CBFC /* kc-keychain-file-helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD45358209A5C2D0086CBFC /* kc-keychain-file-helpers.c */; }; + DCD504BC20CB28BE00F37D26 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + DCD504C220CB28BF00F37D26 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + DCD504C320CB293700F37D26 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; DCD662F51E329B6800188186 /* CKKSNewTLKOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD662F31E329B6800188186 /* CKKSNewTLKOperation.h */; }; DCD662F61E329B6800188186 /* CKKSNewTLKOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD662F31E329B6800188186 /* CKKSNewTLKOperation.h */; }; DCD662F71E329B6800188186 /* CKKSNewTLKOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD662F41E329B6800188186 /* CKKSNewTLKOperation.m */; }; @@ -4129,13 +4467,13 @@ DCD66DB21D8204F500DB1393 /* SecSignatureVerificationSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E8E1D8085FC00865A7C /* SecSignatureVerificationSupport.c */; }; DCD66DB31D8204FB00DB1393 /* SecServerEncryptionSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E8A1D8085FC00865A7C /* SecServerEncryptionSupport.c */; }; DCD66DB41D82050000DB1393 /* SecRSAKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E851D8085FC00865A7C /* SecRSAKey.c */; }; - DCD66DB51D82050500DB1393 /* SecECKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.c */; }; + DCD66DB51D82050500DB1393 /* SecECKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.m */; }; DCD66DB61D82050900DB1393 /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; }; DCD66DB71D82050E00DB1393 /* SecTrustStore.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E971D8085FC00865A7C /* SecTrustStore.c */; }; DCD66DB91D82051900DB1393 /* SecTrust.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E901D8085FC00865A7C /* SecTrust.c */; }; DCD66DBA1D82052000DB1393 /* SecPolicyLeafCallbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7F1D8085FC00865A7C /* SecPolicyLeafCallbacks.c */; }; DCD66DBB1D82052700DB1393 /* SecPolicy.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7E1D8085FC00865A7C /* SecPolicy.c */; }; - DCD66DBC1D82052B00DB1393 /* SecKeyAdaptors.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */; }; + DCD66DBC1D82052B00DB1393 /* SecKeyAdaptors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */; }; DCD66DBE1D82053700DB1393 /* SecBase64.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E351D8085FC00865A7C /* SecBase64.c */; }; DCD66DBF1D82053E00DB1393 /* SecDigest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E481D8085FC00865A7C /* SecDigest.c */; }; DCD66DC01D82054500DB1393 /* SecCertificate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E381D8085FC00865A7C /* SecCertificate.c */; }; @@ -4205,7 +4543,6 @@ DCD8A1A41E09EF9000E4FA0A /* SOSPeerInfoCollections.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D6A1D8085F200865A7C /* SOSPeerInfoCollections.c */; }; DCD8A1A51E09EFAE00E4FA0A /* SOSPeerInfoV2.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D671D8085F200865A7C /* SOSPeerInfoV2.m */; }; DCD8A1A61E09EFD700E4FA0A /* SOSKVSKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D721D8085F200865A7C /* SOSKVSKeys.m */; }; - DCD8A1A71E09F01300E4FA0A /* SOSPeerInfoSecurityProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D6F1D8085F200865A7C /* SOSPeerInfoSecurityProperties.m */; }; DCD8A1A91E09F04700E4FA0A /* SOSECWrapUnwrap.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D881D8085F200865A7C /* SOSECWrapUnwrap.c */; }; DCD8A1AE1E09F0C500E4FA0A /* SOSRingDER.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D401D8085F200865A7C /* SOSRingDER.c */; }; DCD8A1AF1E09F0DC00E4FA0A /* SOSRingUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D461D8085F200865A7C /* SOSRingUtils.c */; }; @@ -4231,7 +4568,6 @@ DCD8A1DE1E09F74700E4FA0A /* SOSPeerInfoV2.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D681D8085F200865A7C /* SOSPeerInfoV2.h */; }; DCD8A1DF1E09F76000E4FA0A /* SOSPeerInfoCollections.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D6B1D8085F200865A7C /* SOSPeerInfoCollections.h */; }; DCD8A1E01E09F76800E4FA0A /* SOSPeerInfoRingState.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D6E1D8085F200865A7C /* SOSPeerInfoRingState.h */; }; - DCD8A1E11E09F76D00E4FA0A /* SOSPeerInfoSecurityProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D701D8085F200865A7C /* SOSPeerInfoSecurityProperties.h */; }; DCD8A1E21E09F78A00E4FA0A /* SOSTransportCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D791D8085F200865A7C /* SOSTransportCircle.h */; }; DCD8A1E41E09F80B00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1E71E09F85400E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; @@ -4279,6 +4615,8 @@ DCDD59D01F69ACF70060641E /* SOSCloudCircle.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8A1D8085F200865A7C /* SOSCloudCircle.h */; }; DCDD59D21F69ACF70060641E /* SOSBackupSliceKeyBag.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2A1D8085F200865A7C /* SOSBackupSliceKeyBag.h */; }; DCDF0A4F1D81D76F007AF174 /* Security.exp-in in Sources */ = {isa = PBXBuildFile; fileRef = 4CB7405F0A47498100D641BB /* Security.exp-in */; }; + DCE2341720A3D4B8009766A3 /* si-cms-hash-agility-data.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE2341520A3D4B8009766A3 /* si-cms-hash-agility-data.h */; }; + DCE2341820A3D4B8009766A3 /* si-cms-hash-agility-data.c in Sources */ = {isa = PBXBuildFile; fileRef = DCE2341620A3D4B8009766A3 /* si-cms-hash-agility-data.c */; }; DCE278DD1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */; }; DCE278DE1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */; }; DCE278DF1ED789EF0083B485 /* CKKSCurrentItemPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE278DC1ED789EF0083B485 /* CKKSCurrentItemPointer.m */; }; @@ -4381,7 +4719,6 @@ DCE4E8071D7A4DE200AFB96E /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 790850840CA87CF00083CC4D /* server.c */; }; DCE4E80A1D7A4E1D00AFB96E /* com.apple.secd.plist in Copy LaunchAgents files */ = {isa = PBXBuildFile; fileRef = DCE4E8091D7A4E1C00AFB96E /* com.apple.secd.plist */; }; DCE4E80E1D7A4E3B00AFB96E /* com.apple.securityd.plist in Copy Logging Files */ = {isa = PBXBuildFile; fileRef = DCE4E80D1D7A4E3A00AFB96E /* com.apple.securityd.plist */; }; - DCE4E80F1D7A4E4600AFB96E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; 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 */; }; @@ -4447,7 +4784,6 @@ DCE4E93D1D7F3E1600AFB96E /* AppleSystemInfo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3F1D78F2FF002223DE /* AppleSystemInfo.framework */; }; DCE4E93F1D7F3E4000AFB96E /* AOSAccounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E93E1D7F3E4000AFB96E /* AOSAccounts.framework */; }; DCE4E9401D7F3E4D00AFB96E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; - DCE4E9421D7F3E6E00AFB96E /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; DCE4E9491D7F3E8E00AFB96E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DCE4E9441D7F3E8700AFB96E /* Localizable.strings */; }; DCE4E94A1D7F3E8E00AFB96E /* com.apple.security.keychain-circle-notification.plist in Resources */ = {isa = PBXBuildFile; fileRef = DCE4E9461D7F3E8700AFB96E /* com.apple.security.keychain-circle-notification.plist */; }; DCE4E94B1D7F3E8E00AFB96E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DCE4E9471D7F3E8700AFB96E /* InfoPlist.strings */; }; @@ -4811,6 +5147,8 @@ DCFE1C521F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C4F1F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h */; }; DCFE1C531F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C501F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m */; }; DCFE1C541F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C501F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m */; }; + DCFE9C8920EC1F3B00EB6BAC /* SOSControlHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = EBEEEE351EA31A8300E15F5C /* SOSControlHelper.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCFE9C8F20EC1F3C00EB6BAC /* SOSControlHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = EBEEEE351EA31A8300E15F5C /* SOSControlHelper.h */; settings = {ATTRIBUTES = (Private, ); }; }; E7104A0C169E171900DB0045 /* security_tool_commands.c in Sources */ = {isa = PBXBuildFile; fileRef = E7104A0B169E171900DB0045 /* security_tool_commands.c */; }; E71454EF1C741E0800B5B20B /* KCError.h in Headers */ = {isa = PBXBuildFile; fileRef = E71454ED1C741E0800B5B20B /* KCError.h */; settings = {ATTRIBUTES = (Private, ); }; }; E71454F01C741E0800B5B20B /* KCError.m in Sources */ = {isa = PBXBuildFile; fileRef = E71454EE1C741E0800B5B20B /* KCError.m */; }; @@ -4842,7 +5180,6 @@ E7A5F4D21C0CFF7900F3BEBB /* CKDKVSProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4C71C0CFF3200F3BEBB /* CKDKVSProxy.m */; }; E7A5F4D51C0CFF7900F3BEBB /* cloudkeychainproxy.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4CE1C0CFF3300F3BEBB /* cloudkeychainproxy.m */; }; E7A5F4D81C0D01B000F3BEBB /* SOSCloudKeychainConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4D71C0D01B000F3BEBB /* SOSCloudKeychainConstants.c */; }; - E7A5F5591C0D052600F3BEBB /* SOSCloudKeychainConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4D71C0D01B000F3BEBB /* SOSCloudKeychainConstants.c */; }; E7B00700170B581D00B27966 /* Security.exp-in in Sources */ = {isa = PBXBuildFile; fileRef = 4CB7405F0A47498100D641BB /* Security.exp-in */; }; E7B01BD2166594AB000485F1 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; E7B01BD3166594AB000485F1 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; @@ -4883,6 +5220,9 @@ E7FEEEF81332B7F70025EB06 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; E7FEEEFA1332B8210025EB06 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; E7FEEEFB1332B8300025EB06 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + EB056E431FE5E390000A771E /* DeviceSimulator.m in Sources */ = {isa = PBXBuildFile; fileRef = EB056E421FE5E390000A771E /* DeviceSimulator.m */; }; + EB056E451FE5E390000A771E /* DeviceSimulatorMain.m in Sources */ = {isa = PBXBuildFile; fileRef = EB056E441FE5E390000A771E /* DeviceSimulatorMain.m */; }; + EB05C4F41FE5E48B00D68712 /* MultiDeviceSimulatorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EB05C4F31FE5E48B00D68712 /* MultiDeviceSimulatorTests.m */; }; EB0BC93A1C3C791500785842 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; EB0BC9671C3C798600785842 /* secedumodetest.m in Sources */ = {isa = PBXBuildFile; fileRef = EB0BC9661C3C794700785842 /* secedumodetest.m */; }; EB0DB37D1DCBC99100EAB6AE /* Keychain Circle Notification.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = EB76B75A1DCB0CDA00C43FBC /* Keychain Circle Notification.8 */; }; @@ -4929,6 +5269,7 @@ EB2D54AB1F02A47200E46890 /* SecAtomicFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB2D54A01F02A28200E46890 /* SecAtomicFile.cpp */; }; EB3409B01C1D627400D77661 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; EB3A8DFF1BEEC66F001A89AA /* Security_edumode.plist in Install BATS plist */ = {isa = PBXBuildFile; fileRef = EB3A8DD71BEEC4D6001A89AA /* Security_edumode.plist */; }; + EB3D1FBA2092CB030049EF95 /* SecurityInduceLowDisk.plist in Install BATS plist */ = {isa = PBXBuildFile; fileRef = EBE202752092913500B48020 /* SecurityInduceLowDisk.plist */; }; EB413B801E663AEB00592085 /* PairingChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = EB413B761E6624A500592085 /* PairingChannel.m */; }; EB413B821E663AFA00592085 /* PairingChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = EB413B751E6624A400592085 /* PairingChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; EB425CA21C65846D000ECE53 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; @@ -4963,10 +5304,8 @@ EB49B2DB202DF20F003F34A0 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; EB49B2DD202DF259003F34A0 /* libbsm.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EB49B2DC202DF251003F34A0 /* libbsm.tbd */; }; EB49B2E0202DF5D7003F34A0 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; - EB49B2E2202DFDA3003F34A0 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; EB49B2E5202DFEB3003F34A0 /* mockaks.m in Sources */ = {isa = PBXBuildFile; fileRef = EB49B2E4202DFE7F003F34A0 /* mockaks.m */; }; EB49B308202FF421003F34A0 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; - EB49B310202FF4AC003F34A0 /* OCMock.framework in Embedded OCMock */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; EB4B6E201DC0682A00AFC494 /* SecADWrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = EBF3749A1DC064200065D840 /* SecADWrapper.c */; }; EB4B6E261DC0683600AFC494 /* SecADWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = EBF3749B1DC064200065D840 /* SecADWrapper.h */; }; EB4E0CDB1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = EB4E0CD51FF36A1900CDCACC /* CKKSReachabilityTracker.m */; }; @@ -4993,7 +5332,6 @@ EB75B4911E7540BF00E469CC /* libcoreauthd_test_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E8B53A41AA0B8A600345E7B /* libcoreauthd_test_client.a */; }; EB75B4951E75A44100E469CC /* SOSPiggyback.h in Headers */ = {isa = PBXBuildFile; fileRef = EB75B4931E75A44100E469CC /* SOSPiggyback.h */; }; EB75B4961E75A44100E469CC /* SOSPiggyback.m in Sources */ = {isa = PBXBuildFile; fileRef = EB75B4941E75A44100E469CC /* SOSPiggyback.m */; }; - EB76B7571DCB0C8300C43FBC /* KeychainSyncingOverIDSProxy.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = DC24B5841DA432C600330B48 /* KeychainSyncingOverIDSProxy.8 */; }; EB76B7591DCB0CA200C43FBC /* CloudKeychainProxy.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = DC24B5851DA432E900330B48 /* CloudKeychainProxy.8 */; }; EB78D3F91E600E93009AFE05 /* SOSCloudCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D891D8085F200865A7C /* SOSCloudCircle.m */; }; EB7AE6F81E86DACC00B80B15 /* SecPLWrappers.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7AE6F61E86D55400B80B15 /* SecPLWrappers.m */; }; @@ -5011,9 +5349,65 @@ EBB839B01E2968AB00853BAC /* secfuzzer.m in Sources */ = {isa = PBXBuildFile; fileRef = EBB8399B1E295B8F00853BAC /* secfuzzer.m */; }; EBB839B11E2968B400853BAC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; EBC15B1D1DB432F800126882 /* com.apple.secd.sb in Copy Sandbox profile */ = {isa = PBXBuildFile; fileRef = EBC15B1B1DB4306C00126882 /* com.apple.secd.sb */; }; + EBC73F2020993F8600AE3350 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; + EBC73F2620993FA800AE3350 /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; }; + EBC73F2720993FC900AE3350 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; + EBC73F2820993FDA00AE3350 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; + EBC73F29209966AF00AE3350 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + EBC73F2A20996AD400AE3350 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; + EBC73F2B2099785900AE3350 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; + EBCE150E1FE6389A002E7CCC /* DeviceSimulator.xpc in Embedded XPC service */ = {isa = PBXBuildFile; fileRef = EB056E3E1FE5E390000A771E /* DeviceSimulator.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + EBCE16171FE6DE5A002E7CCC /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + EBCE16181FE6DE5A002E7CCC /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + EBCE16191FE6DE5A002E7CCC /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; + EBCE16201FE6DE5A002E7CCC /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; + EBCE16221FE6DE5A002E7CCC /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; + EBCE16231FE6DE5A002E7CCC /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; }; + EBCE162C1FE6DE5A002E7CCC /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; }; + EBCE162D1FE6DE5A002E7CCC /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; + EBCE162F1FE6DE5A002E7CCC /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; }; + EBCE16311FE6DE5A002E7CCC /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; + EBCE16321FE6DE5A002E7CCC /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; + EBCE16351FE6DE5A002E7CCC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + EBCE16361FE6DE5A002E7CCC /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + EBCE16371FE6DE5A002E7CCC /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + EBCE16391FE6DE5A002E7CCC /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + EBCE163A1FE6DE5A002E7CCC /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; + EBCE163D1FE6DE5A002E7CCC /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + EBCE163E1FE6DE5A002E7CCC /* AutoreleaseTest.c in Sources */ = {isa = PBXBuildFile; fileRef = DAEE05551FAD3FC500DF27F3 /* AutoreleaseTest.c */; }; + EBCE163F1FE6DE5A002E7CCC /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; + EBCE16401FE6DE5A002E7CCC /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; + EBCE16411FE6DE5A002E7CCC /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + EBCE16421FE6DE5A002E7CCC /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */; }; + EBCE16431FE6DE5A002E7CCC /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + EBCE16451FE6DE5A002E7CCC /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; + EBCE16461FE6DE5A002E7CCC /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + EBCE16471FE6DE5A002E7CCC /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; + EBCE16481FE6DE5A002E7CCC /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + EBCE16491FE6DE5A002E7CCC /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; + EBCE164B1FE6DE5A002E7CCC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + EBCE164C1FE6DE5A002E7CCC /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + EBCE164E1FE6DE5A002E7CCC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; + EBCE164F1FE6DE5A002E7CCC /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.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 */; }; + 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 */; }; + EBCE165D1FE71821002E7CCC /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + EBCE16601FE732AA002E7CCC /* MultiDeviceNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = EBCE165F1FE7313C002E7CCC /* MultiDeviceNetworking.m */; }; + EBCE16641FE73679002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = EBCE16611FE73327002E7CCC /* MultiDeviceNetworkingProtocol.h */; }; + EBCE16661FE736A1002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = EBCE16611FE73327002E7CCC /* MultiDeviceNetworkingProtocol.h */; }; + EBCE16671FE736A5002E7CCC /* DeviceSimulatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = EB056E401FE5E390000A771E /* DeviceSimulatorProtocol.h */; }; + EBCE16681FE736AD002E7CCC /* DeviceSimulatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = EB056E401FE5E390000A771E /* DeviceSimulatorProtocol.h */; }; + EBCE166B1FE74688002E7CCC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + EBCE166C1FE746A5002E7CCC /* SecItemConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5C1D8085FC00865A7C /* SecItemConstants.c */; }; EBCF73F71CE45F9C00BED7CA /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; EBCF73F81CE45F9C00BED7CA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; EBCF73FD1CE45FAC00BED7CA /* secitemfunctionality.m in Sources */ = {isa = PBXBuildFile; fileRef = EBCF73F21CE45F8600BED7CA /* secitemfunctionality.m */; }; + EBDD732C20A6A61E003A103A /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; EBE901721C2283F7007308C6 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; }; EBE9019A1C22852C007308C6 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; }; EBE9019B1C2285D4007308C6 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; }; @@ -5045,6 +5439,18 @@ /* End PBXBuildFile section */ /* Begin PBXBuildRule section */ + 4718AEDE205B39C40068EC3F /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.proxy.script; + filePatterns = "*.proto"; + fileType = pattern.proxy; + isEditable = 1; + outputFiles = ( + "$(INPUT_FILE_DIR)/source/${INPUT_FILE_BASE}.h", + "$(INPUT_FILE_DIR)/source/${INPUT_FILE_BASE}.m", + ); + script = "set -x\n\nmkdir -p ${INPUT_FILE_DIR}/source\nprotocompiler --arc --strict --emitDeprecated=NO --generics=YES --outputDir ${INPUT_FILE_DIR}/source --proto ${INPUT_FILE_DIR}/${INPUT_FILE_NAME}\n"; + }; DC58C36E1D77B4AD003C25A4 /* PBXBuildRule */ = { isa = PBXBuildRule; compilerSpec = com.apple.compilers.proxy.script; @@ -5122,6 +5528,20 @@ remoteGlobalIDString = 0C2BCBBD1D0648D100ED7A2F; remoteInfo = dtlsEchoServer; }; + 0C3E2EA82073F5C400F5B95B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C32C0AE0A4975F6002891BD; + remoteInfo = Security_ios; + }; + 0C5663ED20BE2E1A0035F362 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; 0C664AB31759270C0092D3D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5192,6 +5612,13 @@ remoteGlobalIDString = 0C6799F912F7C37C00712919; remoteInfo = dtlsTests; }; + 0C9AEEB920783FE000BF6237 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC1789031D77980500B50D50; + remoteInfo = Security_osx; + }; 0CC827F1138712B100BD99B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5220,6 +5647,34 @@ remoteGlobalIDString = DCD06AA91D8E0D53007602F1; remoteInfo = security_utilities; }; + 3DD1FEF9201C07F30086D049 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; + 3DD1FF4F201C09CD0086D049 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BC9C81D8B824700070CB0; + remoteInfo = security_ssl; + }; + 3DD1FFB0201FDB1D0086D049 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BC9C81D8B824700070CB0; + remoteInfo = security_ssl; + }; + 3DD1FFB2201FDB1D0086D049 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; 438169E61B4EE4B300C54D58 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5227,6 +5682,62 @@ remoteGlobalIDString = 4381690B1B4EDCBD00C54D58; remoteInfo = SOSCCAuthPlugin; }; + 4718AE04205B39620068EC3F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; + }; + 4718AE06205B39620068EC3F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D4ADA3181E2B41670031CEA3; + remoteInfo = libtrustd; + }; + 4718AE0A205B39620068EC3F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = libSecureObjectSync; + }; + 4718AE0C205B39620068EC3F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + 4718AE0E205B39620068EC3F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EC3E1D80D00800B0A59C; + remoteInfo = libSWCAgent; + }; + 4718AEE5205B3A350068EC3F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4718AE2E205B39C40068EC3F; + remoteInfo = libsecurityd_bridge; + }; + 47455B23205B3E2F008FE980 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4718AE02205B39620068EC3F; + remoteInfo = securityd_bridge; + }; + 4771D981209A76B100BA9772 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4771D971209A755800BA9772; + remoteInfo = KeychainDataclassOwner; + }; 478D426E1FD72A8100CAB645 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5241,19 +5752,54 @@ remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; remoteInfo = regressionBase; }; - 478D42721FD72A8100CAB645 /* PBXContainerItemProxy */ = { + 478D42741FD72A8100CAB645 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; + }; + 47A6FC69206B461700BD6C54 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; remoteGlobalIDString = DC52E7731D80BC8000B0A59C; remoteInfo = libsecurityd_ios; }; - 478D42741FD72A8100CAB645 /* PBXContainerItemProxy */ = { + 47A6FC6B206B462400BD6C54 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCC78EA81D8088E200865A7C; - remoteInfo = security; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; + }; + 47C2F18B2059CBEA0062DE30 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47C2F1822059CB680062DE30; + remoteInfo = KeychainResources; + }; + 47C2F18D2059CBF40062DE30 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47C2F1822059CB680062DE30; + remoteInfo = KeychainResources; + }; + 47C2F18F2059CBFC0062DE30 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47C2F1822059CB680062DE30; + remoteInfo = KeychainResources; + }; + 47C2F1912059CC040062DE30 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47C2F1822059CB680062DE30; + remoteInfo = KeychainResources; }; 47C51B8A1EEA657D0032D9E5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -5262,19 +5808,26 @@ remoteGlobalIDString = DC1789031D77980500B50D50; remoteInfo = Security_osx; }; - 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */ = { + 47D991CF20407F7E0078CAE2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCC78EA81D8088E200865A7C; - remoteInfo = security; + remoteGlobalIDString = 4727FBB61F9918580003AE36; + remoteInfo = secdxctests_ios; }; - 47DE88D41FA7AD7000DD3254 /* PBXContainerItemProxy */ = { + 47D991D620407F890078CAE2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd_ios; + remoteGlobalIDString = 478D426C1FD72A8100CAB645; + remoteInfo = secdxctests_mac; + }; + 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; }; 47DE88D61FA7ADAC00DD3254 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -5290,6 +5843,20 @@ remoteGlobalIDString = DC52EDA61D80D58400B0A59C; remoteInfo = secdRegressions; }; + 4809F7AD2061B6AA003E72D0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB056E3D1FE5E390000A771E; + remoteInfo = DeviceSimulator; + }; + 4809F7AF2061B6B0003E72D0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB05C4F01FE5E48A00D68712; + remoteInfo = MultiDeviceSimulatorTests; + }; 4C52D0ED16EFCD720079966E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5612,20 +6179,6 @@ remoteGlobalIDString = BEF88C271EAFFC3F00357577; remoteInfo = TrustedPeers; }; - CD6130EC1DA1C0CC00E1E42F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = CD276C261A83F60C003226BC; - remoteInfo = KeychainSyncingOverIDSProxy; - }; - CD6130ED1DA1C0CC00E1E42F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = CD276C261A83F60C003226BC; - remoteInfo = KeychainSyncingOverIDSProxy; - }; D40B6A7E1E2B5F3D00CD6EE5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5864,6 +6417,13 @@ remoteGlobalIDString = DA30D6751DF8C8FB00EC6B43; remoteInfo = KeychainSyncAccountUpdater; }; + DAE40BD420CF3ED5002D5674 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DAE40BC520CF3E46002D5674; + remoteInfo = secitemcanarytest; + }; DC00678F1D878132005AF8DB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -6340,6 +6900,13 @@ remoteGlobalIDString = DC1789031D77980500B50D50; remoteInfo = Security_osx; }; + DC193C5F20CB4C9D009C1A0F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D4C3345B1BE2A2B100D8C1EF; + remoteInfo = libsecurity_cms_regressions; + }; DC222C781E034EE700B09171 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -6704,13 +7271,6 @@ remoteGlobalIDString = DC0BCC211D8C684F00070CB0; remoteInfo = iOSutilities; }; - DC65E7321D8CB34000152EF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = iOSutilities; - }; DC65E7381D8CB38300152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -7614,6 +8174,27 @@ remoteGlobalIDString = DC0BCC211D8C684F00070CB0; remoteInfo = utilities; }; + EB11965920A6300600BFDA1B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4809F7A42061B697003E72D0; + remoteInfo = MultiPeerSimulatorTests; + }; + EB11965B20A6301100BFDA1B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4809F7A42061B697003E72D0; + remoteInfo = MultiPeerSimulatorTests; + }; + EB11965D20A6302100BFDA1B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4809F7A42061B697003E72D0; + remoteInfo = MultiPeerSimulatorTests; + }; EB1C4CA61E85883900404981 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -7726,6 +8307,34 @@ remoteGlobalIDString = EBB839A41E29665D00853BAC; remoteInfo = secfuzzer; }; + EB636BC920992D8900C1E21A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB49B2AD202D877F003F34A0; + remoteInfo = secdmockaks; + }; + EB636BD020992DA300C1E21A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB49B2AD202D877F003F34A0; + remoteInfo = secdmockaks; + }; + EB636BD220992DB400C1E21A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB49B2AD202D877F003F34A0; + remoteInfo = secdmockaks; + }; + EB636BD420992DC000C1E21A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB49B2AD202D877F003F34A0; + remoteInfo = secdmockaks; + }; EB63ADE01C3E74F900C45A69 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -7740,13 +8349,6 @@ remoteGlobalIDString = 0C7CFA2E14E1BA4800DF9D95; remoteInfo = Security_frameworks_ios; }; - EB6A6FB21B90F89F0045DC68 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 790851B50CA9859F0083CC4D; - remoteInfo = securityd; - }; EB6A6FB81B90F8D70045DC68 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -7768,6 +8370,48 @@ remoteGlobalIDString = 4C32C0AE0A4975F6002891BD; remoteInfo = Security; }; + EB8910F020E0287600DE533F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4727FBB61F9918580003AE36; + remoteInfo = secdxctests_ios; + }; + EB8910F720E0287E00DE533F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4727FBB61F9918580003AE36; + remoteInfo = secdxctests_ios; + }; + EB8910FD20E06DF500DE533F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6C46056B1F882B9B001421B6; + remoteInfo = KeychainAnalyticsTests; + }; + EB89FAFD20DBDAA800085498 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 470415CE1E5E14B5001F3D95; + remoteInfo = seckeychainnetworkextensionstest; + }; + EB89FAFF20DBDAA800085498 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47702B1D1E5F409700B29577; + remoteInfo = seckeychainnetworkextensionsystemdaemontest; + }; + EB89FB0120DBDAA800085498 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47702B2D1E5F492C00B29577; + remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; + }; EB9C1DB61BDFD51800F89272 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -7824,6 +8468,41 @@ remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; remoteInfo = SecurityBatsTests; }; + EBC73F51209A705A00AE3350 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6C46056B1F882B9B001421B6; + remoteInfo = KeychainAnalyticsTests; + }; + EBC73F5C209A739600AE3350 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 470415CE1E5E14B5001F3D95; + remoteInfo = seckeychainnetworkextensionstest; + }; + EBC73F63209A73A100AE3350 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47702B1D1E5F409700B29577; + remoteInfo = seckeychainnetworkextensionsystemdaemontest; + }; + EBC73F65209A73A100AE3350 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47702B2D1E5F492C00B29577; + remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; + }; + EBCE150F1FE638A2002E7CCC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB056E3D1FE5E390000A771E; + remoteInfo = DeviceSimulator; + }; EBCF743E1CE593A700BED7CA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -7989,6 +8668,46 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 0C9AEEB320783FBB00BF6237 /* Embed OCMock */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed OCMock"; + runOnlyForDeploymentPostprocessing = 0; + }; + 0CF4064A2072E3E3003D6A7F /* Embed OCMock */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed OCMock"; + runOnlyForDeploymentPostprocessing = 0; + }; + 3DD1FFD3201FF72C0086D049 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /AppleInternal/CoreOS/BATS/unit_tests; + dstSubfolderSpec = 0; + files = ( + 3DD1FFD5201FF7860086D049 /* SecureTransport_iosTests.plist in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 3DD1FFD6201FF7930086D049 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /AppleInternal/CoreOS/BATS/unit_tests; + dstSubfolderSpec = 0; + files = ( + 3DD1FFD7201FF7B10086D049 /* SecureTransport_macosTests.plist in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; 470415CD1E5E14B5001F3D95 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -7998,6 +8717,26 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 4718AE26205B39620068EC3F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/LaunchDaemons; + dstSubfolderSpec = 0; + files = ( + 4718AE27205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 4718AE28205B39620068EC3F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/Preferences/Logging/Subsystems; + dstSubfolderSpec = 0; + files = ( + 4718AE29205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; 47702B1C1E5F409700B29577 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -8210,16 +8949,6 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - 6C0B0C4A1E253840007F95E5 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /System/Library/AWD/Metadata; - dstSubfolderSpec = 0; - files = ( - 6C0B0C4B1E253848007F95E5 /* AwdMetadata-0x60-Keychain.bin in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; - }; 6C1520D31DCCF6F000C85C6D /* Install man8 page */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -8231,6 +8960,16 @@ name = "Install man8 page"; runOnlyForDeploymentPostprocessing = 1; }; + 6C4F981E2075831300A3C5AB /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 6C4F98252075833E00A3C5AB /* OCMock.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6C9AA79C1F7C1D8F00D08296 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -8331,17 +9070,6 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - CDF91EA61AAE019800E88CF7 /* Install alloy plist */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /System/Library/IdentityServices/ServiceDefinitions; - dstSubfolderSpec = 0; - files = ( - CD51245E1DA1C67000962524 /* com.apple.private.alloy.keychainsync.plist in Install alloy plist */, - ); - name = "Install alloy plist"; - runOnlyForDeploymentPostprocessing = 1; - }; D41257CD1E9410A300781F23 /* Copy LaunchDaemon */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -8864,28 +9592,6 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - EB49B30E202FF484003F34A0 /* Embedded OCMock */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - EB49B310202FF4AC003F34A0 /* OCMock.framework in Embedded OCMock */, - ); - name = "Embedded OCMock"; - runOnlyForDeploymentPostprocessing = 0; - }; - EB76B7561DCB0C6900C43FBC /* Install man8 page */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/share/man/man8; - dstSubfolderSpec = 0; - files = ( - EB76B7571DCB0C8300C43FBC /* KeychainSyncingOverIDSProxy.8 in Install man8 page */, - ); - name = "Install man8 page"; - runOnlyForDeploymentPostprocessing = 1; - }; EB76B7581DCB0C8B00C43FBC /* Install man8 page */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -8916,6 +9622,7 @@ files = ( EB9C1DB51BDFD50100F89272 /* Security.plist in Install BATS plist */, EB3A8DFF1BEEC66F001A89AA /* Security_edumode.plist in Install BATS plist */, + EB3D1FBA2092CB030049EF95 /* SecurityInduceLowDisk.plist in Install BATS plist */, ); name = "Install BATS plist"; runOnlyForDeploymentPostprocessing = 1; @@ -8940,6 +9647,17 @@ name = "Copy Sandbox profile"; runOnlyForDeploymentPostprocessing = 1; }; + EBCE150D1FE63880002E7CCC /* Embedded XPC service */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; + dstSubfolderSpec = 16; + files = ( + EBCE150E1FE6389A002E7CCC /* DeviceSimulator.xpc in Embedded XPC service */, + ); + name = "Embedded XPC service"; + runOnlyForDeploymentPostprocessing = 0; + }; EBF374701DC055580065D840 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -8972,13 +9690,19 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 091B396D2063B64A00ECAB6F /* RemoteServiceDiscovery.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RemoteServiceDiscovery.framework; path = System/Library/PrivateFrameworks/RemoteServiceDiscovery.framework; sourceTree = SDKROOT; }; + 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecKeyProxy.h; path = keychain/SecKeyProxy.h; sourceTree = ""; }; + 09A3B9DF1F8271A200C5C324 /* si-44-seckey-proxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "si-44-seckey-proxy.m"; path = "OSX/shared_regressions/si-44-seckey-proxy.m"; sourceTree = SOURCE_ROOT; }; + 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainEntitlementsTest.m; sourceTree = ""; }; 09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "si-44-seckey-fv.m"; path = "OSX/shared_regressions/si-44-seckey-fv.m"; sourceTree = SOURCE_ROOT; }; + 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecKeyProxy.m; sourceTree = ""; }; 0C0BDB2F175685B000BC1A7E /* secdtests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secdtests; sourceTree = BUILT_PRODUCTS_DIR; }; 0C0BDB31175685B000BC1A7E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 0C0BDB441756868B00BC1A7E /* testlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testlist.h; sourceTree = ""; }; 0C0C88771CCEC5BD00617D1B /* si-82-sectrust-ct-data */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "si-82-sectrust-ct-data"; path = "../OSX/shared_regressions/si-82-sectrust-ct-data"; sourceTree = ""; }; 0C0CEC9D1DA45EA200C22FBC /* recovery_key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = recovery_key.h; sourceTree = ""; }; 0C0CEC9E1DA45EA200C22FBC /* recovery_key.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = recovery_key.m; sourceTree = ""; }; + 0C108C4B208A677100E8CF70 /* SFSignInAnalytics+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFSignInAnalytics+Internal.h"; sourceTree = ""; }; 0C16371F1FD12F1500210823 /* OTCloudStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTCloudStoreTests.m; path = ot/tests/OTCloudStoreTests.m; sourceTree = ""; }; 0C2BCBA51D063F7D00ED7A2F /* dtlsEchoClient.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dtlsEchoClient.c; sourceTree = ""; }; 0C2BCBA61D063F7D00ED7A2F /* dtlsEchoServer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dtlsEchoServer.c; sourceTree = ""; }; @@ -8993,20 +9717,16 @@ 0C4899111E0E105D00C6CF70 /* SOSTransportCircleCK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransportCircleCK.m; sourceTree = ""; }; 0C48991B1E0F384700C6CF70 /* SOSAccountTrustClassic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAccountTrustClassic.m; path = SecureObjectSync/SOSAccountTrustClassic.m; sourceTree = ""; }; 0C4899221E0F386900C6CF70 /* SOSAccountTrustClassic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAccountTrustClassic.h; path = SecureObjectSync/SOSAccountTrustClassic.h; sourceTree = ""; }; - 0C4899241E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAccountTrustOctagon.m; path = SecureObjectSync/SOSAccountTrustOctagon.m; sourceTree = ""; }; - 0C4899261E0F399B00C6CF70 /* SOSAccountTrustOctagon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAccountTrustOctagon.h; path = SecureObjectSync/SOSAccountTrustOctagon.h; sourceTree = ""; }; 0C52C1FE20003BCA003F0733 /* OTTestsBase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTTestsBase.m; path = ot/tests/OTTestsBase.m; sourceTree = ""; }; 0C52C20520004248003F0733 /* OTTestsBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTTestsBase.h; path = ot/tests/OTTestsBase.h; sourceTree = ""; }; 0C5CFB37201960FF00913B9C /* OTRamping.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTRamping.m; path = ot/OTRamping.m; sourceTree = ""; }; 0C5CFB3F201962FF00913B9C /* OTRamping.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTRamping.h; path = ot/OTRamping.h; sourceTree = ""; }; - 0C5F4FD71F952FEA00AF1616 /* secd-700-sftm.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-700-sftm.m"; sourceTree = ""; }; 0C664AB2175926B20092D3D9 /* secdtests-entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "secdtests-entitlements.plist"; sourceTree = ""; }; 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTCloudStore.m; path = ot/OTCloudStore.m; sourceTree = ""; }; 0C78F1C916A5E13400654E08 /* sectask_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sectask_regressions.h; sourceTree = ""; }; 0C78F1CA16A5E1BF00654E08 /* sectask-10-sectask.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sectask-10-sectask.c"; sourceTree = ""; }; 0C78F1CB16A5E1BF00654E08 /* sectask_ipc.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = sectask_ipc.defs; sourceTree = ""; }; 0C85E0031FB38BB6000343A7 /* OTTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OTTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 0C85E0041FB38BB7000343A7 /* OTTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = "OTTests-Info.plist"; path = "/Users/ma/git/security/OTTests-Info.plist"; sourceTree = ""; }; 0C8A03451FDF42BA0042E8BE /* OTEscrowKeyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTEscrowKeyTests.m; path = ot/tests/OTEscrowKeyTests.m; sourceTree = ""; }; 0C8A034C1FDF4CCE0042E8BE /* OTLocalStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTLocalStoreTests.m; path = ot/tests/OTLocalStoreTests.m; sourceTree = ""; }; 0C8A034E1FDF60070042E8BE /* OTBottledPeerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerTests.m; path = ot/tests/OTBottledPeerTests.m; sourceTree = ""; }; @@ -9032,6 +9752,8 @@ 0C8BBF0E1FCB452400580909 /* OTControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTControl.m; path = ot/OTControl.m; sourceTree = ""; }; 0C8BBF0F1FCB481800580909 /* OTManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTManager.m; path = ot/OTManager.m; sourceTree = ""; }; 0C8BBF101FCB486B00580909 /* OTManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTManager.h; path = ot/OTManager.h; sourceTree = ""; }; + 0C9AEEB720783FBB00BF6237 /* SignInAnalyticsTests_osx.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SignInAnalyticsTests_osx.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 0C9FB40120D8729A00864612 /* CoreCDP.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreCDP.framework; path = System/Library/PrivateFrameworks/CoreCDP.framework; sourceTree = SDKROOT; }; 0CA4EBF1202B8D1C002B1D96 /* CloudKitKeychainSyncingTestsBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CloudKitKeychainSyncingTestsBase.h; sourceTree = ""; }; 0CA4EBF2202B8D1D002B1D96 /* CloudKitKeychainSyncingTestsBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CloudKitKeychainSyncingTestsBase.m; sourceTree = ""; }; 0CAC5DBE1EB3DA4C00AD884B /* SOSPeerRateLimiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSPeerRateLimiter.m; sourceTree = ""; }; @@ -9045,6 +9767,7 @@ 0CCDE7161EEB08220021A946 /* secd-156-timers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-156-timers.m"; sourceTree = ""; }; 0CD8CB041ECA50780076F37F /* SOSPeerOTRTimer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSPeerOTRTimer.m; sourceTree = ""; }; 0CD8CB0C1ECA50D10076F37F /* SOSPeerOTRTimer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSPeerOTRTimer.h; sourceTree = ""; }; + 0CD8D654207D6E65005CDBE8 /* SFAnalytics+Signin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFAnalytics+Signin.h"; sourceTree = ""; }; 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTContextRecord.m; path = ot/OTContextRecord.m; sourceTree = ""; }; 0CD9E8071FE05B8700F66C38 /* OTContextRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTContextRecord.h; path = ot/OTContextRecord.h; sourceTree = ""; }; 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerSigned.m; path = ot/OTBottledPeerSigned.m; sourceTree = ""; }; @@ -9060,9 +9783,11 @@ 0CE760531E13155100B4381E /* SOSAccountTrustClassic+Circle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SOSAccountTrustClassic+Circle.h"; path = "SecureObjectSync/SOSAccountTrustClassic+Circle.h"; sourceTree = ""; }; 0CE760551E1316E900B4381E /* SOSAccountTrustClassic+Retirement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SOSAccountTrustClassic+Retirement.h"; path = "SecureObjectSync/SOSAccountTrustClassic+Retirement.h"; sourceTree = ""; }; 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libprequelite.tbd; path = usr/lib/libprequelite.tbd; sourceTree = SDKROOT; }; - 0CE98BAD1FA93AA900CF1D54 /* CKKSTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = "CKKSTests-Info.plist"; path = "/Volumes/Data/ma/git/security/CKKSTests-Info.plist"; sourceTree = ""; }; - 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFTransactionMetric.m; sourceTree = ""; }; - 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFTransactionMetric.h; sourceTree = ""; }; + 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFSignInAnalytics.m; sourceTree = ""; }; + 0CF0E2E71F8EE40700BD18E4 /* SFSignInAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFSignInAnalytics.h; sourceTree = ""; }; + 0CF405F42072E2BF003D6A7F /* SFSignInAnalyticsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFSignInAnalyticsTests.m; sourceTree = ""; }; + 0CF405FC2072E352003D6A7F /* SFTMTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SFTMTests-Info.plist"; sourceTree = ""; }; + 0CF406502072E3E3003D6A7F /* SignInAnalyticsTests_ios.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SignInAnalyticsTests_ios.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 0CFC029B1D41650700E6283B /* libcoretls.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcoretls.dylib; path = usr/lib/libcoretls.dylib; sourceTree = SDKROOT; }; 107226D00D91DB32003CF14F /* SecTask.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecTask.c; sourceTree = ""; }; 107226D10D91DB32003CF14F /* SecTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTask.h; path = sectask/SecTask.h; sourceTree = ""; }; @@ -9071,6 +9796,31 @@ 225394B41E3080A600D3CD9B /* libsecurity_codesigning_ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_codesigning_ios.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2281820D17B4686C0067C9C9 /* BackgroundTaskAgent.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BackgroundTaskAgent.framework; path = System/Library/PrivateFrameworks/BackgroundTaskAgent.framework; sourceTree = SDKROOT; }; 24CBF8731E9D4E4500F09F0E /* kc-44-secrecoverypassword.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "kc-44-secrecoverypassword.c"; path = "regressions/kc-44-secrecoverypassword.c"; sourceTree = ""; }; + 3DD1FE78201AA50C0086D049 /* STLegacyTests+clientauth41.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+clientauth41.m"; sourceTree = ""; }; + 3DD1FE79201AA50D0086D049 /* SecureTransport_macosTests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SecureTransport_macosTests.plist; sourceTree = ""; }; + 3DD1FE7A201AA50D0086D049 /* STLegacyTests-Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "STLegacyTests-Entitlements.plist"; sourceTree = ""; }; + 3DD1FE7B201AA50D0086D049 /* STLegacyTests+noconn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+noconn.m"; sourceTree = ""; }; + 3DD1FE7C201AA50E0086D049 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3DD1FE7D201AA50E0086D049 /* STLegacyTests+tls12.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+tls12.m"; sourceTree = ""; }; + 3DD1FE7E201AA50F0086D049 /* SecureTransportTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecureTransportTests.m; sourceTree = ""; }; + 3DD1FE7F201AA50F0086D049 /* STLegacyTests+sni.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+sni.m"; sourceTree = ""; }; + 3DD1FE80201AA5100086D049 /* STLegacyTests+sessionstate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+sessionstate.m"; sourceTree = ""; }; + 3DD1FE81201AA5100086D049 /* STLegacyTests+sslciphers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+sslciphers.m"; sourceTree = ""; }; + 3DD1FE82201AA5110086D049 /* STLegacyTests+dhe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+dhe.m"; sourceTree = ""; }; + 3DD1FE83201AA5110086D049 /* STLegacyTests+crashes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+crashes.m"; sourceTree = ""; }; + 3DD1FE84201AA5120086D049 /* STLegacyTests+falsestart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+falsestart.m"; sourceTree = ""; }; + 3DD1FE85201AA5120086D049 /* STLegacyTests+renegotiate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+renegotiate.m"; sourceTree = ""; }; + 3DD1FE86201AA5120086D049 /* SecureTransport_iosTests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SecureTransport_iosTests.plist; sourceTree = ""; }; + 3DD1FE87201AA5130086D049 /* STLegacyTests+clientauth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+clientauth.m"; sourceTree = ""; }; + 3DD1FE88201AA5130086D049 /* STLegacyTests+split.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+split.m"; sourceTree = ""; }; + 3DD1FE89201AA5140086D049 /* STLegacyTests+ciphers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+ciphers.m"; sourceTree = ""; }; + 3DD1FE8A201AA5140086D049 /* STLegacyTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STLegacyTests.h; sourceTree = ""; }; + 3DD1FE8B201AA5150086D049 /* STLegacyTests+sessioncache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+sessioncache.m"; sourceTree = ""; }; + 3DD1FE8C201AA5150086D049 /* STLegacyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STLegacyTests.m; sourceTree = ""; }; + 3DD1FF4D201C07F30086D049 /* SecureTransport_macos_tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecureTransport_macos_tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3DD1FFA8201FC5C20086D049 /* libcoretls.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcoretls.tbd; path = usr/lib/libcoretls.tbd; sourceTree = SDKROOT; }; + 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcoretls_cfhelpers.tbd; path = usr/lib/libcoretls_cfhelpers.tbd; sourceTree = SDKROOT; }; + 3DD1FFD0201FDB1D0086D049 /* SecureTransport_ios_tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecureTransport_ios_tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 433E519D1B66D5F600482618 /* AppSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppSupport.framework; path = System/Library/PrivateFrameworks/AppSupport.framework; sourceTree = SDKROOT; }; 4381690C1B4EDCBD00C54D58 /* SOSCCAuthPlugin.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SOSCCAuthPlugin.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 4381690F1B4EDCBD00C54D58 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -9088,9 +9838,14 @@ 470415DD1E5E15B3001F3D95 /* seckeychainnetworkextensionstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = seckeychainnetworkextensionstest.entitlements; path = RegressionTests/seckeychainnetworkextensionstest/seckeychainnetworkextensionstest.entitlements; sourceTree = SOURCE_ROOT; }; 470ACEF21F58C3A600D1D5BD /* SecDbKeychainItemV7.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainItemV7.h; sourceTree = ""; }; 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainItemV7.m; sourceTree = ""; }; + 470D966C1FCDE4BA0065FE90 /* KeychainModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = KeychainModel.xcdatamodel; sourceTree = ""; }; + 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCDKeychain.h; sourceTree = ""; }; + 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecCDKeychain.m; sourceTree = ""; }; + 470D96841FCE34370065FE90 /* CDKeychainTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CDKeychainTests.m; sourceTree = ""; }; 471024D91E79CB6D00844C09 /* CKKSTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSTests.h; sourceTree = ""; }; + 4718AE2D205B39620068EC3F /* securityd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = securityd; sourceTree = BUILT_PRODUCTS_DIR; }; + 4718AEE2205B39C40068EC3F /* libsecurityd_bridge.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd_bridge.a; sourceTree = BUILT_PRODUCTS_DIR; }; 472339611FD7155C00CB6A72 /* libprequelite.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libprequelite.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.Internal.sdk/usr/lib/libprequelite.dylib; sourceTree = DEVELOPER_DIR; }; - 472339681FD7156700CB6A72 /* CoreCDP.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreCDP.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.Internal.sdk/System/Library/PrivateFrameworks/CoreCDP.framework; sourceTree = DEVELOPER_DIR; }; 4723C9BC1F152EB10082882F /* SFSQLite.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFSQLite.m; sourceTree = ""; }; 4723C9BD1F152EB10082882F /* SFSQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFSQLite.h; sourceTree = ""; }; 4723C9BE1F152EB10082882F /* SFObjCType.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFObjCType.m; sourceTree = ""; }; @@ -9137,6 +9892,12 @@ 47702B2E1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = seckeychainnetworkextensionunauthorizedaccesstest; sourceTree = BUILT_PRODUCTS_DIR; }; 47702B351E5F495C00B29577 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RegressionTests/seckeychainnetworkextensionunauthorizedaccesstest/main.m; sourceTree = SOURCE_ROOT; }; 47702B381E5F499A00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = seckeychainnetworkextensionunauthorizedaccesstest.entitlements; path = RegressionTests/seckeychainnetworkextensionunauthorizedaccesstest/seckeychainnetworkextensionunauthorizedaccesstest.entitlements; sourceTree = SOURCE_ROOT; }; + 4771D972209A755800BA9772 /* KeychainDataclassOwner.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainDataclassOwner.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 4771D975209A755800BA9772 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4771D97E209A75FE00BA9772 /* KeychainDataclassOwner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainDataclassOwner.h; sourceTree = ""; }; + 4771D97F209A75FE00BA9772 /* KeychainDataclassOwner.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainDataclassOwner.m; sourceTree = ""; }; + 4771D99F209B7C2600BA9772 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.Internal.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; + 4771D9A1209B7C3900BA9772 /* Accounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accounts.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.Internal.sdk/System/Library/Frameworks/Accounts.framework; sourceTree = DEVELOPER_DIR; }; 477A1F4C20320E4900ACD81D /* Accounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accounts.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/Frameworks/Accounts.framework; sourceTree = DEVELOPER_DIR; }; 477A1FE1203763A500ACD81D /* KeychainAPITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainAPITests.m; sourceTree = ""; }; 477A1FEB2037A0E000ACD81D /* KeychainXCTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainXCTest.h; sourceTree = ""; }; @@ -9157,12 +9918,17 @@ 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainSerializedItemV7.h; sourceTree = ""; }; 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainSerializedItemV7.m; sourceTree = ""; }; 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFKeychainControl.h; sourceTree = ""; }; + 47B503C5203B97A000722164 /* SFCredentialStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFCredentialStoreTests.m; sourceTree = ""; }; + 47C2F1832059CB680062DE30 /* KeychainResources.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainResources.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 47C2F1862059CB680062DE30 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47C51B841EEA657D0032D9E5 /* SecurityUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecurityUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 47C51B861EEA657D0032D9E5 /* SecurityUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecurityUnitTests.m; sourceTree = ""; }; 47C51B881EEA657D0032D9E5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47CEED1E1E60DE900044EAB4 /* CKKSManifest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSManifest.h; sourceTree = ""; }; 47CEED1F1E60DE900044EAB4 /* CKKSManifest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSManifest.m; sourceTree = ""; }; 47D1838B1FB3827700CFCD89 /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = Platforms/iPhoneOS.platform/Developer/AppleInternal/Library/Frameworks/OCMock.framework; sourceTree = DEVELOPER_DIR; }; + 47FF17241FD60ACA00875565 /* SFKeychainServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFKeychainServer.h; sourceTree = ""; }; + 47FF17251FD60ACA00875565 /* SFKeychainServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFKeychainServer.m; sourceTree = ""; }; 48284A041D1DB06E00C76CB7 /* README_os_log_prefs.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README_os_log_prefs.txt; path = OSX/sec/os_log/README_os_log_prefs.txt; sourceTree = ""; }; 483E79891DC875F2005C0008 /* secd-67-prefixedKeyIDs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-67-prefixedKeyIDs.m"; sourceTree = ""; }; 485B64081DC16E8300B771B9 /* SOSKeyedPubKeyIdentifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSKeyedPubKeyIdentifier.c; sourceTree = ""; }; @@ -9172,11 +9938,14 @@ 48776C7C1DA5BB5F00CC09B9 /* SOSRingRecovery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSRingRecovery.m; sourceTree = ""; }; 48776C7D1DA5BB5F00CC09B9 /* SOSRingRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSRingRecovery.h; sourceTree = ""; }; 48776C801DA5BC0E00CC09B9 /* SOSAccountRecovery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAccountRecovery.m; sourceTree = ""; }; + 4885DCAB207FF0780071FB7B /* ClientInfoByNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ClientInfoByNotification.m; path = MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m; sourceTree = SOURCE_ROOT; }; 48C2F9321E4BCFC30093D70C /* accountCirclesViewsPrint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = accountCirclesViewsPrint.m; sourceTree = ""; }; 48C2F9331E4BCFC30093D70C /* accountCirclesViewsPrint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = accountCirclesViewsPrint.h; sourceTree = ""; }; 48CC58971DA5FF0B00EBD9DB /* secd-66-account-recovery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-66-account-recovery.m"; sourceTree = ""; }; 48E6171A1DBEC40D0098EAAD /* SOSBackupInformation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSBackupInformation.m; sourceTree = ""; }; 48E6171B1DBEC40D0098EAAD /* SOSBackupInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSBackupInformation.h; sourceTree = ""; }; + 48FE668F20E6E69B00FAEF17 /* SOSAuthKitHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAuthKitHelpers.m; sourceTree = ""; }; + 48FE669520E6E69C00FAEF17 /* SOSAuthKitHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSAuthKitHelpers.h; sourceTree = ""; }; 4AF7FFF315AFB73800B9D400 /* SecOTR.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecOTR.h; sourceTree = ""; }; 4AF7FFF415AFB73800B9D400 /* SecOTRDHKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecOTRDHKey.h; sourceTree = ""; }; 4AF7FFF515AFB73800B9D400 /* SecOTRErrors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecOTRErrors.h; sourceTree = ""; }; @@ -9211,6 +9980,7 @@ 4C3DD6AF179755560093F9D8 /* NSDate+TimeIntervalDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+TimeIntervalDescription.m"; sourceTree = ""; }; 4C4296300BB0A68200491999 /* SecTrustSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrustSettings.h; path = trust/SecTrustSettings.h; sourceTree = ""; }; 4C465C7D13AFD82300E841AC /* SecurityDevTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SecurityDevTests-Info.plist"; sourceTree = ""; }; + 4C47FA8D20A51DC700384CB6 /* AppleFSCompression.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppleFSCompression.framework; path = System/Library/PrivateFrameworks/AppleFSCompression.framework; sourceTree = SDKROOT; }; 4C4CB7100DDA44900026B660 /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = entitlements.plist; sourceTree = ""; }; 4C4CE9070AF81ED80056B01D /* TODO */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = TODO; sourceTree = ""; }; 4C4CE9120AF81F0E0056B01D /* README */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README; sourceTree = ""; }; @@ -9316,8 +10086,13 @@ 5346481C173322BD00FE9172 /* KeychainSyncAccountNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeychainSyncAccountNotification.h; sourceTree = ""; }; 5346481D173322BD00FE9172 /* KeychainSyncAccountNotification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainSyncAccountNotification.m; sourceTree = ""; }; 53C0E1F2177FAC2C00F8A018 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/CloudKeychain.strings; sourceTree = ""; }; + 5A4E381A207529480047F40F /* SecProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocol.h; path = protocol/SecProtocol.h; sourceTree = ""; }; 5A94C6D1203CC1C60066E391 /* AOSAccountsLite.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AOSAccountsLite.framework; path = System/Library/PrivateFrameworks/AOSAccountsLite.framework; sourceTree = SDKROOT; }; 5A94C6D4203CC2590066E391 /* AuthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AuthKit.framework; path = System/Library/PrivateFrameworks/AuthKit.framework; sourceTree = SDKROOT; }; + 5AC6BFA52077CD130051737D /* SecProtocolTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolTypes.h; path = protocol/SecProtocolTypes.h; sourceTree = ""; }; + 5AFCF32220746AD80010D4B5 /* SecProtocolOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolOptions.h; path = protocol/SecProtocolOptions.h; sourceTree = ""; }; + 5AFCF32820746AE90010D4B5 /* SecProtocolMetadata.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolMetadata.h; path = protocol/SecProtocolMetadata.h; sourceTree = ""; }; + 5AFCF32D20746D9A0010D4B5 /* SecProtocolObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolObject.h; path = protocol/SecProtocolObject.h; sourceTree = ""; }; 5E10992519A5E55800A60E2B /* ISACLProtectedItems.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ISACLProtectedItems.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 5E10992919A5E55800A60E2B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E10994E19A5E5CE00A60E2B /* ISProtectedItems.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ISProtectedItems.plist; sourceTree = ""; }; @@ -9342,14 +10117,6 @@ 6C1520CD1DCCF57A00C85C6D /* secd.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = secd.8; sourceTree = ""; }; 6C1A29FC1F882788002312D8 /* SFAnalyticsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsTests.m; sourceTree = ""; }; 6C34462F1E24F6BE00F9522B /* CKKSRateLimiterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSRateLimiterTests.m; sourceTree = ""; }; - 6C34464F1E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainCKKSRateLimiterAggregatedScores.h; path = analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h; sourceTree = ""; }; - 6C3446501E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainCKKSRateLimiterAggregatedScores.m; path = analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.m; sourceTree = ""; }; - 6C3446511E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainCKKSRateLimiterOverload.h; path = analytics/awd/AWDKeychainCKKSRateLimiterOverload.h; sourceTree = ""; }; - 6C3446521E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainCKKSRateLimiterOverload.m; path = analytics/awd/AWDKeychainCKKSRateLimiterOverload.m; sourceTree = ""; }; - 6C3446531E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainCKKSRateLimiterTopWriters.h; path = analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h; sourceTree = ""; }; - 6C3446541E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainCKKSRateLimiterTopWriters.m; path = analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.m; sourceTree = ""; }; - 6C3446551E2534E800F9522B /* AwdMetadata-0x60-Keychain.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = "AwdMetadata-0x60-Keychain.bin"; path = "analytics/awd/AwdMetadata-0x60-Keychain.bin"; sourceTree = ""; }; - 6C3446561E2534E800F9522B /* AWDMetricIds_Keychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDMetricIds_Keychain.h; path = analytics/awd/AWDMetricIds_Keychain.h; sourceTree = ""; }; 6C4605B81F882B9B001421B6 /* KeychainAnalyticsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainAnalyticsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 6C5232D41E3C183F00330DB1 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/CloudKit.framework; sourceTree = DEVELOPER_DIR; }; 6C588D791EAA149F00D7E322 /* RateLimiterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RateLimiterTests.m; sourceTree = ""; }; @@ -9367,10 +10134,10 @@ 6C758CB21F8826100075BD78 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAnalytics.m; path = Analytics/Clients/SOSAnalytics.m; sourceTree = SOURCE_ROOT; }; 6C7BB0042006B4EF004D1B6B /* SOSAnalytics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAnalytics.h; path = Analytics/Clients/SOSAnalytics.h; sourceTree = SOURCE_ROOT; }; + 6C814A4A2050B4B600CB391B /* LocalKeychainAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocalKeychainAnalytics.h; sourceTree = ""; }; + 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LocalKeychainAnalytics.m; sourceTree = ""; }; 6C860C741F4F63AD004100A1 /* SOSEnsureBackup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSEnsureBackup.h; sourceTree = ""; }; 6C860C7A1F4F63DB004100A1 /* SOSEnsureBackup.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSEnsureBackup.m; sourceTree = ""; }; - 6C869A771F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainSOSKeychainBackupFailed.m; path = analytics/awd/AWDKeychainSOSKeychainBackupFailed.m; sourceTree = ""; }; - 6C869A781F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainSOSKeychainBackupFailed.h; path = analytics/awd/AWDKeychainSOSKeychainBackupFailed.h; sourceTree = ""; }; 6C8CE6BB1FA248B50032ADF0 /* SFAnalyticsActivityTracker+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFAnalyticsActivityTracker+Internal.h"; sourceTree = ""; }; 6C8CE6C31FA24A670032ADF0 /* SFAnalyticsSampler+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFAnalyticsSampler+Internal.h"; sourceTree = ""; }; 6C9808611E788AEB00E70590 /* CKKSCloudKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CKKSCloudKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -9393,8 +10160,6 @@ 6CCDF7841E3C25FA003F2555 /* KeychainEntitledTestRunner */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = KeychainEntitledTestRunner; sourceTree = BUILT_PRODUCTS_DIR; }; 6CCDF78B1E3C26BC003F2555 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 6CCDF7911E3C2D69003F2555 /* CKKSCloudKitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSCloudKitTests.m; sourceTree = ""; }; - 6CD8D3B11EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainSecDbMarkedCorrupt.h; path = analytics/awd/AWDKeychainSecDbMarkedCorrupt.h; sourceTree = ""; }; - 6CD8D3B21EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainSecDbMarkedCorrupt.m; path = analytics/awd/AWDKeychainSecDbMarkedCorrupt.m; sourceTree = ""; }; 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsMultiSampler.m; sourceTree = ""; }; 6CDB5FF31FA78CB500410924 /* SFAnalyticsMultiSampler+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SFAnalyticsMultiSampler+Internal.h"; sourceTree = ""; }; 6CDB5FF41FA78CB500410924 /* SFAnalyticsMultiSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsMultiSampler.h; sourceTree = ""; }; @@ -9463,6 +10228,11 @@ 8E64DB4C1C17CD3F0076C9DF /* com.apple.security.cloudkeychainproxy3.ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.security.cloudkeychainproxy3.ios.plist; path = KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.ios.plist; sourceTree = ""; }; 8E64DB4D1C17CD400076C9DF /* com.apple.security.cloudkeychainproxy3.osx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.security.cloudkeychainproxy3.osx.plist; path = KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.osx.plist; sourceTree = ""; }; 8ED6F6C8110904E300D2B368 /* SecPBKDF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecPBKDF.h; sourceTree = ""; }; + A6B1BA78207BD9D400F1E099 /* notarization.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = notarization.cpp; sourceTree = ""; }; + A6B1BA79207BD9D400F1E099 /* notarization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = notarization.h; sourceTree = ""; }; + AA44E0D02032513F001EA371 /* SecProtocol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecProtocol.c; path = protocol/SecProtocol.c; sourceTree = SOURCE_ROOT; }; + AA44E0D120325140001EA371 /* SecProtocolTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecProtocolTypes.m; path = protocol/SecProtocolTypes.m; sourceTree = SOURCE_ROOT; }; + AA44E0D920325177001EA371 /* SecProtocolPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecProtocolPriv.h; path = protocol/SecProtocolPriv.h; sourceTree = ""; }; ACBAF6DD1E9417F40007BA2F /* libsecurity_transform_regressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_transform_regressions.a; sourceTree = BUILT_PRODUCTS_DIR; }; ACBAF6E31E941AE00007BA2F /* transform_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = transform_regressions.h; path = OSX/libsecurity_transform/regressions/transform_regressions.h; sourceTree = ""; }; ACBAF6E51E941AE00007BA2F /* transform-01-sigverify.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "transform-01-sigverify.m"; path = "OSX/libsecurity_transform/regressions/transform-01-sigverify.m"; sourceTree = ""; }; @@ -9573,25 +10343,9 @@ BEF88C741EB0008E00357577 /* TPPolicyDocumentTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPPolicyDocumentTests.m; path = keychain/trust/TrustedPeersTests/TPPolicyDocumentTests.m; sourceTree = SOURCE_ROOT; }; BEF88C751EB0008E00357577 /* TPUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPUtilsTests.m; path = keychain/trust/TrustedPeersTests/TPUtilsTests.m; sourceTree = SOURCE_ROOT; }; BEF88C761EB0008E00357577 /* TPVoucherTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPVoucherTests.m; path = keychain/trust/TrustedPeersTests/TPVoucherTests.m; sourceTree = SOURCE_ROOT; }; - CD23B4921DA06EB30047EDE9 /* IDSPersistentState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IDSPersistentState.h; path = KeychainSyncingOverIDSProxy/IDSPersistentState.h; sourceTree = ""; }; - CD23B4931DA06EB30047EDE9 /* IDSPersistentState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = IDSPersistentState.m; path = KeychainSyncingOverIDSProxy/IDSPersistentState.m; sourceTree = ""; }; - CD23B4941DA06EB30047EDE9 /* IDSProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IDSProxy.h; path = KeychainSyncingOverIDSProxy/IDSProxy.h; sourceTree = ""; }; - CD23B4951DA06EB30047EDE9 /* IDSProxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = IDSProxy.m; path = KeychainSyncingOverIDSProxy/IDSProxy.m; sourceTree = ""; }; - CD23B4961DA06EB30047EDE9 /* keychainsyncingoveridsproxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = keychainsyncingoveridsproxy.m; path = KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m; sourceTree = ""; }; - CD23B4971DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "KeychainSyncingOverIDSProxy+ReceiveMessage.h"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h"; sourceTree = ""; }; - CD23B4981DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "KeychainSyncingOverIDSProxy+ReceiveMessage.m"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m"; sourceTree = ""; }; - CD23B4991DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "KeychainSyncingOverIDSProxy+SendMessage.h"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h"; sourceTree = ""; }; - CD23B49A1DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "KeychainSyncingOverIDSProxy+SendMessage.m"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m"; sourceTree = ""; }; - CD23B4A81DA06ED10047EDE9 /* com.apple.private.alloy.keychainsync.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = com.apple.private.alloy.keychainsync.plist; path = KeychainSyncingOverIDSProxy/com.apple.private.alloy.keychainsync.plist; sourceTree = ""; }; - CD276C271A83F60C003226BC /* KeychainSyncingOverIDSProxy.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainSyncingOverIDSProxy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; CD2F99D91DFC995B00769430 /* libsqlite3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.0.dylib; path = usr/lib/libsqlite3.0.dylib; sourceTree = SDKROOT; }; CD31F8601DCD4C1400414B46 /* SOSAccountTrust.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAccountTrust.m; path = SecureObjectSync/SOSAccountTrust.m; sourceTree = ""; }; CD31F8611DCD4C1400414B46 /* SOSAccountTrust.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAccountTrust.h; path = SecureObjectSync/SOSAccountTrust.h; sourceTree = ""; }; - CD6130D31DA06FC600E1E42F /* com.apple.security.keychainsyncingoveridsproxy.ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.security.keychainsyncingoveridsproxy.ios.plist; path = KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.ios.plist; sourceTree = ""; }; - CD6130D41DA06FC600E1E42F /* com.apple.security.keychainsyncingoveridsproxy.osx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.security.keychainsyncingoveridsproxy.osx.plist; path = KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.osx.plist; sourceTree = ""; }; - CD6130D71DA06FC600E1E42F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = ""; }; - CD6130D81DA06FC600E1E42F /* KeychainSyncingOverIDSProxy-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "KeychainSyncingOverIDSProxy-Info.plist"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist"; sourceTree = ""; }; - CD6130D91DA06FC600E1E42F /* keychainsyncingoveridsproxy.entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = keychainsyncingoveridsproxy.entitlements.plist; path = KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist; sourceTree = ""; }; CD744683195A00BB00FB01C0 /* IDS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IDS.framework; path = System/Library/PrivateFrameworks/IDS.framework; sourceTree = SDKROOT; }; CD9021471DE27A9E00F81DC4 /* SOSAccountPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSAccountPriv.h; sourceTree = ""; }; CDA43D251DFCA0790038E038 /* AggregateDictionary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AggregateDictionary.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.Internal.sdk/System/Library/PrivateFrameworks/AggregateDictionary.framework; sourceTree = DEVELOPER_DIR; }; @@ -9611,8 +10365,6 @@ D41D36701EB14D87007FA978 /* libDiagnosticMessagesClient.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libDiagnosticMessagesClient.tbd; path = usr/lib/libDiagnosticMessagesClient.tbd; sourceTree = SDKROOT; }; D43761641EB2996C00954447 /* SecRevocationNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecRevocationNetworking.h; path = OSX/sec/securityd/SecRevocationNetworking.h; sourceTree = ""; }; D43761651EB2996C00954447 /* SecRevocationNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecRevocationNetworking.m; path = OSX/sec/securityd/SecRevocationNetworking.m; sourceTree = ""; }; - D43DBED51E99D17100C04AEA /* asynchttp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asynchttp.c; path = OSX/sec/securityd/asynchttp.c; sourceTree = ""; }; - D43DBED61E99D17100C04AEA /* asynchttp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asynchttp.h; path = OSX/sec/securityd/asynchttp.h; sourceTree = ""; }; D43DBED71E99D17100C04AEA /* nameconstraints.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nameconstraints.c; path = OSX/sec/securityd/nameconstraints.c; sourceTree = ""; }; D43DBED81E99D17100C04AEA /* nameconstraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = nameconstraints.h; path = OSX/sec/securityd/nameconstraints.h; sourceTree = ""; }; D43DBED91E99D17100C04AEA /* OTATrustUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTATrustUtilities.m; path = OSX/sec/securityd/OTATrustUtilities.m; sourceTree = ""; }; @@ -9623,7 +10375,7 @@ D43DBEDE1E99D17200C04AEA /* policytree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = policytree.h; path = OSX/sec/securityd/policytree.h; sourceTree = ""; }; D43DBEDF1E99D17200C04AEA /* SecCAIssuerCache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCAIssuerCache.c; path = OSX/sec/securityd/SecCAIssuerCache.c; sourceTree = ""; }; D43DBEE01E99D17200C04AEA /* SecCAIssuerCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCAIssuerCache.h; path = OSX/sec/securityd/SecCAIssuerCache.h; sourceTree = ""; }; - D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCAIssuerRequest.c; path = OSX/sec/securityd/SecCAIssuerRequest.c; sourceTree = ""; }; + D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecCAIssuerRequest.m; path = OSX/sec/securityd/SecCAIssuerRequest.m; sourceTree = ""; }; D43DBEE21E99D17200C04AEA /* SecCAIssuerRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCAIssuerRequest.h; path = OSX/sec/securityd/SecCAIssuerRequest.h; sourceTree = ""; }; D43DBEE31E99D17200C04AEA /* SecCertificateServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCertificateServer.c; path = OSX/sec/securityd/SecCertificateServer.c; sourceTree = ""; }; D43DBEE41E99D17200C04AEA /* SecCertificateServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCertificateServer.h; path = OSX/sec/securityd/SecCertificateServer.h; sourceTree = ""; }; @@ -9651,6 +10403,7 @@ D43DBEFA1E99D17300C04AEA /* SecTrustStoreServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrustStoreServer.h; path = OSX/sec/securityd/SecTrustStoreServer.h; sourceTree = ""; }; D43DDE511F620F09009742A5 /* SecPolicyChecks.list */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecPolicyChecks.list; sourceTree = ""; }; D43DDE581F638061009742A5 /* SecPolicy.list */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecPolicy.list; sourceTree = ""; }; + D44D08B420AB890E0023C439 /* Security.apinotes */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Security.apinotes; path = base/Security.apinotes; sourceTree = ""; }; D45068681E948A9E00FA7675 /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = entitlements.plist; path = OSX/trustd/macOS/entitlements.plist; sourceTree = ""; }; D45068691E948ACE00FA7675 /* entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = entitlements.plist; path = OSX/trustd/iOS/entitlements.plist; sourceTree = ""; }; D453C38A1FEC669300DE349B /* trust_update.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = trust_update.m; sourceTree = ""; }; @@ -9662,6 +10415,7 @@ D46246AF1F9AE73F00D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; D46246C31F9AEA5200D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; D46246CE1F9AEAE300D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; + D46513072097954B005D93FE /* si-23-sectrust-ocsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-23-sectrust-ocsp.h"; sourceTree = ""; }; D479F6E01F980F8F00388D28 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Trust.strings; sourceTree = ""; }; D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = lib_ios_x64.xcconfig; path = xcconfig/lib_ios_x64.xcconfig; sourceTree = ""; }; D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = lib_ios_x64_shim.xcconfig; path = xcconfig/lib_ios_x64_shim.xcconfig; sourceTree = ""; }; @@ -9670,11 +10424,18 @@ D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCFAllocator.h; sourceTree = ""; }; D487FBB71DB8357300D4BB0B /* si-29-sectrust-sha1-deprecation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-29-sectrust-sha1-deprecation.m"; sourceTree = ""; }; D487FBB91DB835B500D4BB0B /* si-29-sectrust-sha1-deprecation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-29-sectrust-sha1-deprecation.h"; sourceTree = ""; }; + D48BD193206C47530075DDC9 /* si-35-cms-expiration-time.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-35-cms-expiration-time.m"; sourceTree = ""; }; + D48BD195206C476B0075DDC9 /* si-35-cms-expiration-time.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-35-cms-expiration-time.h"; sourceTree = ""; }; D48F029B1EA1671B00ACC3C9 /* si-61-pkcs12.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-61-pkcs12.h"; sourceTree = ""; }; + D4911167209558900066A1E4 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + D4961BBD2079423300F16DA7 /* TrustURLSessionDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TrustURLSessionDelegate.m; path = OSX/sec/securityd/TrustURLSessionDelegate.m; sourceTree = ""; }; + D4961BC52079426000F16DA7 /* TrustURLSessionDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TrustURLSessionDelegate.h; path = OSX/sec/securityd/TrustURLSessionDelegate.h; sourceTree = ""; }; D4AA647C1E97144700D317ED /* si-18-certificate-parse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-18-certificate-parse.m"; sourceTree = ""; }; D4AA64831E97270300D317ED /* si-18-certificate-parse */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "si-18-certificate-parse"; path = "OSX/shared_regressions/si-18-certificate-parse"; sourceTree = SOURCE_ROOT; }; D4ADA30E1E2B1E650031CEA3 /* trustd-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "trustd-Info.plist"; path = "OSX/trustd/trustd-Info.plist"; sourceTree = ""; }; D4ADA3191E2B41670031CEA3 /* libtrustd.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtrustd.a; sourceTree = BUILT_PRODUCTS_DIR; }; + D4B6D57B2069D8450099FBEF /* si-34-cms-timestamp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-34-cms-timestamp.m"; sourceTree = ""; }; + D4B6D5822069D85B0099FBEF /* si-34-cms-timestamp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-34-cms-timestamp.h"; sourceTree = ""; }; D4B858661D370D9A003B2D95 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.Internal.sdk/System/Library/Frameworks/MobileCoreServices.framework; sourceTree = DEVELOPER_DIR; }; D4BEECE61E93093A00F76D1A /* trustd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = trustd.c; path = OSX/trustd/trustd.c; sourceTree = ""; }; D4C263C51F8FF2A9001317EA /* generateErrStrings.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = generateErrStrings.pl; path = OSX/lib/generateErrStrings.pl; sourceTree = ""; usesTabs = 1; }; @@ -9696,10 +10457,15 @@ DA30D6781DF8C8FB00EC6B43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; DA30D6831DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeychainSyncAccountUpdater.h; sourceTree = ""; }; DA30D6841DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainSyncAccountUpdater.m; sourceTree = ""; }; + DA5B871A2065A8410093F083 /* SecAutorelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAutorelease.h; path = src/SecAutorelease.h; sourceTree = ""; }; + DA5B871B2065A8430093F083 /* SecAutorelease.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecAutorelease.m; path = src/SecAutorelease.m; sourceTree = ""; }; DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSControlServer.m; sourceTree = ""; }; DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSControlServer.h; sourceTree = ""; }; DAB27ADA1FA29EB700DEBBDE /* SOSControlServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSControlServer.h; sourceTree = ""; }; DAB27AE01FA29EB800DEBBDE /* SOSControlServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSControlServer.m; sourceTree = ""; }; + DAE40BCE20CF3E47002D5674 /* secitemcanarytest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secitemcanarytest; sourceTree = BUILT_PRODUCTS_DIR; }; + DAE40BD720CF3F04002D5674 /* secitemcanarytest.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = secitemcanarytest.entitlements; sourceTree = ""; }; + DAE40BD820CF3F04002D5674 /* secitemcanarytest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = secitemcanarytest.m; sourceTree = ""; }; DAEE05551FAD3FC500DF27F3 /* AutoreleaseTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = AutoreleaseTest.c; sourceTree = ""; }; DAEE055B1FAD3FC600DF27F3 /* AutoreleaseTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoreleaseTest.h; sourceTree = ""; }; DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = macos_legacy_lib.xcconfig; path = xcconfig/macos_legacy_lib.xcconfig; sourceTree = ""; }; @@ -10440,7 +11206,6 @@ DC24B5811DA420D700330B48 /* SOSEnginePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSEnginePriv.h; sourceTree = ""; }; DC24B5821DA420D700330B48 /* SOSPersist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSPersist.h; sourceTree = ""; }; DC24B5831DA422BE00330B48 /* base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = base.xcconfig; path = OSX/config/base.xcconfig; sourceTree = ""; }; - DC24B5841DA432C600330B48 /* KeychainSyncingOverIDSProxy.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = KeychainSyncingOverIDSProxy.8; path = KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy.8; sourceTree = SOURCE_ROOT; }; DC24B5851DA432E900330B48 /* CloudKeychainProxy.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CloudKeychainProxy.8; path = OSX/sec/CloudKeychainProxy/CloudKeychainProxy.8; sourceTree = ""; }; DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.0.dylib; path = usr/lib/libsqlite3.0.dylib; sourceTree = SDKROOT; }; DC2C5F5A1F0EB97E00FEBDA7 /* CKKSNotifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSNotifier.h; sourceTree = ""; }; @@ -10692,6 +11457,8 @@ DC610A681D78FA87002223DE /* validation.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = validation.sh; path = OSX/codesign_tests/validation.sh; sourceTree = ""; }; DC610AB71D7910C3002223DE /* gk_reset_check */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gk_reset_check; sourceTree = BUILT_PRODUCTS_DIR; }; DC610AB91D7910F8002223DE /* gk_reset_check.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gk_reset_check.c; path = OSX/gk_reset_check/gk_reset_check.c; sourceTree = ""; }; + DC63D70220B3930700D088AD /* libxar.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxar.tbd; path = usr/lib/libxar.tbd; sourceTree = SDKROOT; }; + DC63D70920B3933000D088AD /* libOpenScriptingUtil.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libOpenScriptingUtil.tbd; path = usr/lib/libOpenScriptingUtil.tbd; sourceTree = SDKROOT; }; DC6593C91ED8DA9200C19462 /* CKKSTests+CurrentPointerAPI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CKKSTests+CurrentPointerAPI.m"; sourceTree = ""; }; DC6593D21ED8DBCE00C19462 /* CKKSTests+API.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CKKSTests+API.h"; sourceTree = ""; }; DC65E7BE1D8CBB1500152EF0 /* readline.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = readline.c; sourceTree = ""; }; @@ -10812,6 +11579,7 @@ DC88344B1D8A21AA00CE0ACA /* oidsattr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oidsattr.c; sourceTree = ""; }; DC88344E1D8A21AA00CE0ACA /* oidsocsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oidsocsp.c; sourceTree = ""; }; DC88344F1D8A21AA00CE0ACA /* oidsocsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oidsocsp.h; sourceTree = ""; }; + DC8D238C2064649400E163C8 /* CKKSAPSHandlingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSAPSHandlingTests.m; sourceTree = ""; }; DC8E04901D7F6780006D80EB /* lib_ios.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = lib_ios.xcconfig; path = xcconfig/lib_ios.xcconfig; sourceTree = ""; }; DC9082C21EA0276000D0C1C5 /* CKKSZoneChangeFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSZoneChangeFetcher.h; sourceTree = ""; }; DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSZoneChangeFetcher.m; sourceTree = ""; }; @@ -10839,6 +11607,8 @@ DCAD9B421F8D939C00C5E2AE /* CKKSFixups.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSFixups.h; sourceTree = ""; }; DCAD9B431F8D939C00C5E2AE /* CKKSFixups.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSFixups.m; sourceTree = ""; }; DCAD9B481F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CloudKitKeychainSyncingFixupTests.m; sourceTree = ""; }; + DCAE1DD52073FCDE00B4F687 /* NSError+UsefulConstructors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+UsefulConstructors.h"; sourceTree = ""; }; + DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSError+UsefulConstructors.m"; sourceTree = ""; }; DCB2214A1E8B0861001598BC /* server_xpc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = server_xpc.m; sourceTree = ""; }; DCB2215B1E8B098D001598BC /* server_endpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = server_endpoint.h; sourceTree = ""; }; DCB332361F467CC200178C30 /* macos_tapi_hacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = macos_tapi_hacks.h; path = OSX/macos_tapi_hacks.h; sourceTree = ""; }; @@ -11203,6 +11973,8 @@ DCBF2F831F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSHealTLKSharesOperation.h; sourceTree = ""; }; DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSHealTLKSharesOperation.m; sourceTree = ""; }; DCC0800D1CFF7903005C35C8 /* CSSMOID.exp-in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "CSSMOID.exp-in"; sourceTree = ""; }; + DCC5860120BF8A98005C7269 /* SecBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecBase.h; sourceTree = ""; }; + DCC5860220BF8A98005C7269 /* SecBase.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecBase.c; sourceTree = ""; }; DCC78C371D8085D800865A7C /* ios6_1_keychain_2_db.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ios6_1_keychain_2_db.h; sourceTree = ""; }; DCC78C381D8085D800865A7C /* ios8-inet-keychain-2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ios8-inet-keychain-2.h"; sourceTree = ""; }; DCC78C391D8085D800865A7C /* secd-03-corrupted-items.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-03-corrupted-items.m"; sourceTree = ""; }; @@ -11251,10 +12023,7 @@ DCC78C651D8085D800865A7C /* secd-71-engine-save-sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "secd-71-engine-save-sample1.h"; sourceTree = ""; }; DCC78C661D8085D800865A7C /* secd-74-engine-beer-servers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-74-engine-beer-servers.m"; sourceTree = ""; }; DCC78C671D8085D800865A7C /* secd-75-engine-views.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-75-engine-views.m"; sourceTree = ""; }; - DCC78C681D8085D800865A7C /* secd-76-idstransport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-76-idstransport.m"; sourceTree = ""; }; - DCC78C691D8085D800865A7C /* secd_77_ids_messaging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = secd_77_ids_messaging.m; sourceTree = ""; }; DCC78C6A1D8085D800865A7C /* secd-80-views-basic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-80-views-basic.m"; sourceTree = ""; }; - DCC78C6B1D8085D800865A7C /* secd-82-secproperties-basic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-82-secproperties-basic.m"; sourceTree = ""; }; DCC78C6C1D8085D800865A7C /* secd-81-item-acl-stress.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-81-item-acl-stress.m"; sourceTree = ""; }; DCC78C6D1D8085D800865A7C /* secd-81-item-acl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-81-item-acl.m"; sourceTree = ""; }; DCC78C6E1D8085D800865A7C /* secd-82-persistent-ref.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-82-persistent-ref.m"; sourceTree = ""; }; @@ -11410,8 +12179,6 @@ DCC78D6C1D8085F200865A7C /* SOSPeerInfoInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSPeerInfoInternal.h; sourceTree = ""; }; DCC78D6D1D8085F200865A7C /* SOSPeerInfoRingState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSPeerInfoRingState.m; sourceTree = ""; }; DCC78D6E1D8085F200865A7C /* SOSPeerInfoRingState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSPeerInfoRingState.h; sourceTree = ""; }; - DCC78D6F1D8085F200865A7C /* SOSPeerInfoSecurityProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSPeerInfoSecurityProperties.m; sourceTree = ""; }; - DCC78D701D8085F200865A7C /* SOSPeerInfoSecurityProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSPeerInfoSecurityProperties.h; sourceTree = ""; }; DCC78D721D8085F200865A7C /* SOSKVSKeys.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSKVSKeys.m; sourceTree = ""; }; DCC78D731D8085F200865A7C /* SOSKVSKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSKVSKeys.h; sourceTree = ""; }; DCC78D741D8085F200865A7C /* SOSTransport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransport.m; sourceTree = ""; }; @@ -11426,8 +12193,6 @@ DCC78D7D1D8085F200865A7C /* SOSTransportKeyParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportKeyParameter.h; sourceTree = ""; }; DCC78D801D8085F200865A7C /* SOSTransportMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransportMessage.m; sourceTree = ""; }; DCC78D811D8085F200865A7C /* SOSTransportMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportMessage.h; sourceTree = ""; }; - DCC78D821D8085F200865A7C /* SOSTransportMessageIDS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransportMessageIDS.m; sourceTree = ""; }; - DCC78D831D8085F200865A7C /* SOSTransportMessageIDS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportMessageIDS.h; sourceTree = ""; }; DCC78D841D8085F200865A7C /* SOSTransportMessageKVS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransportMessageKVS.m; sourceTree = ""; }; DCC78D851D8085F200865A7C /* SOSTransportMessageKVS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportMessageKVS.h; sourceTree = ""; }; DCC78D871D8085F200865A7C /* SOSARCDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSARCDefines.h; sourceTree = ""; }; @@ -11552,7 +12317,6 @@ DCC78E091D8085FC00865A7C /* si-87-sectrust-name-constraints.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-87-sectrust-name-constraints.m"; sourceTree = ""; }; DCC78E0A1D8085FC00865A7C /* si-87-sectrust-name-constraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-87-sectrust-name-constraints.h"; sourceTree = ""; }; DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-89-cms-hash-agility.m"; sourceTree = ""; }; - DCC78E0C1D8085FC00865A7C /* si-89-cms-hash-agility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-89-cms-hash-agility.h"; sourceTree = ""; }; DCC78E0D1D8085FC00865A7C /* si-90-emcs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-90-emcs.m"; sourceTree = ""; }; DCC78E0E1D8085FC00865A7C /* si-95-cms-basic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-95-cms-basic.c"; sourceTree = ""; }; DCC78E0F1D8085FC00865A7C /* si-95-cms-basic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-95-cms-basic.h"; sourceTree = ""; }; @@ -11587,14 +12351,14 @@ DCC78E3E1D8085FC00865A7C /* SecCertificateRequest.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCertificateRequest.c; sourceTree = ""; }; DCC78E401D8085FC00865A7C /* SecCFAllocator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCFAllocator.c; sourceTree = ""; }; DCC78E421D8085FC00865A7C /* SecCMS.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCMS.c; sourceTree = ""; }; - DCC78E441D8085FC00865A7C /* SecCTKKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCTKKey.c; sourceTree = ""; }; + DCC78E441D8085FC00865A7C /* SecCTKKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecCTKKey.m; sourceTree = ""; }; DCC78E451D8085FC00865A7C /* SecCTKKeyPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCTKKeyPriv.h; sourceTree = ""; }; DCC78E461D8085FC00865A7C /* SecDH.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecDH.c; sourceTree = ""; }; DCC78E481D8085FC00865A7C /* SecDigest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecDigest.c; sourceTree = ""; }; - DCC78E491D8085FC00865A7C /* SecECKey.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecECKey.c; sourceTree = ""; }; + DCC78E491D8085FC00865A7C /* SecECKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecECKey.m; sourceTree = ""; }; DCC78E4C1D8085FC00865A7C /* SecEMCS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecEMCS.m; sourceTree = ""; }; DCC78E4E1D8085FC00865A7C /* SecExports.exp-in */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SecExports.exp-in"; sourceTree = ""; }; - DCC78E4F1D8085FC00865A7C /* SecFramework.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecFramework.c; sourceTree = ""; }; + DCC78E4F1D8085FC00865A7C /* SecFramework.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = SecFramework.c; path = OSX/sec/Security/SecFramework.c; sourceTree = ""; }; DCC78E521D8085FC00865A7C /* SecIdentity.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecIdentity.c; sourceTree = ""; }; DCC78E551D8085FC00865A7C /* SecImportExport.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecImportExport.c; sourceTree = ""; }; DCC78E581D8085FC00865A7C /* SecItem.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecItem.c; sourceTree = ""; }; @@ -11602,7 +12366,7 @@ DCC78E5C1D8085FC00865A7C /* SecItemConstants.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecItemConstants.c; sourceTree = ""; }; DCC78E5F1D8085FC00865A7C /* SecItemShim.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecItemShim.h; sourceTree = ""; }; DCC78E601D8085FC00865A7C /* SecKey.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecKey.c; sourceTree = ""; }; - DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecKeyAdaptors.c; sourceTree = ""; }; + DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecKeyAdaptors.m; sourceTree = ""; }; DCC78E651D8085FC00865A7C /* SecLogging.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecLogging.c; sourceTree = ""; }; DCC78E661D8085FC00865A7C /* SecLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecLogging.h; sourceTree = ""; }; DCC78E671D8085FC00865A7C /* SecOnOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOnOSX.h; sourceTree = ""; }; @@ -11972,6 +12736,9 @@ DCD06B231D8E0D7D007602F1 /* cfutilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = cfutilities.cpp; sourceTree = ""; }; DCD06BC21D8E0DC2007602F1 /* utilities_dtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utilities_dtrace.h; path = derived_src/security_utilities/utilities_dtrace.h; sourceTree = BUILT_PRODUCTS_DIR; }; DCD06BC51D8E0DD3007602F1 /* security_utilities.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = security_utilities.d; path = lib/security_utilities.d; sourceTree = ""; }; + DCD45353209A5B260086CBFC /* si-cms-signing-identity-p12.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-cms-signing-identity-p12.h"; sourceTree = ""; }; + DCD45354209A5B260086CBFC /* si-cms-signing-identity-p12.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "si-cms-signing-identity-p12.c"; sourceTree = ""; }; + DCD45358209A5C2D0086CBFC /* kc-keychain-file-helpers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "kc-keychain-file-helpers.c"; path = "regressions/kc-keychain-file-helpers.c"; sourceTree = ""; }; DCD662F31E329B6800188186 /* CKKSNewTLKOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSNewTLKOperation.h; sourceTree = ""; }; DCD662F41E329B6800188186 /* CKKSNewTLKOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSNewTLKOperation.m; sourceTree = ""; }; DCD66D731D8204A700DB1393 /* libSecTrustOSX.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSecTrustOSX.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -11985,6 +12752,8 @@ DCDCC7E41D9B551C006487E8 /* SOSAccountSync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAccountSync.m; sourceTree = ""; }; DCDCCB8D1DF7B8D4006E840E /* CKKSItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSItem.h; sourceTree = ""; }; DCDCCB8E1DF7B8D4006E840E /* CKKSItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSItem.m; sourceTree = ""; }; + DCE2341520A3D4B8009766A3 /* si-cms-hash-agility-data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-cms-hash-agility-data.h"; sourceTree = ""; }; + DCE2341620A3D4B8009766A3 /* si-cms-hash-agility-data.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "si-cms-hash-agility-data.c"; sourceTree = ""; }; DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSCurrentItemPointer.h; sourceTree = ""; }; DCE278DC1ED789EF0083B485 /* CKKSCurrentItemPointer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSCurrentItemPointer.m; sourceTree = ""; }; DCE278E61ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSUpdateCurrentItemPointerOperation.h; sourceTree = ""; }; @@ -12053,7 +12822,6 @@ DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CrashReporterSupport.framework; path = System/Library/PrivateFrameworks/CrashReporterSupport.framework; sourceTree = SDKROOT; }; DCE4E93B1D7F3E0900AFB96E /* AOSUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AOSUI.framework; path = System/Library/PrivateFrameworks/AOSUI.framework; sourceTree = SDKROOT; }; DCE4E93E1D7F3E4000AFB96E /* AOSAccounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AOSAccounts.framework; path = System/Library/PrivateFrameworks/AOSAccounts.framework; sourceTree = SDKROOT; }; - DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreCDP.framework; path = System/Library/PrivateFrameworks/CoreCDP.framework; sourceTree = SDKROOT; }; DCE4E9451D7F3E8700AFB96E /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = "OSX/Keychain Circle Notification/en.lproj/Localizable.strings"; sourceTree = SOURCE_ROOT; }; DCE4E9461D7F3E8700AFB96E /* com.apple.security.keychain-circle-notification.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "com.apple.security.keychain-circle-notification.plist"; sourceTree = ""; }; DCE4E9481D7F3E8700AFB96E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = "OSX/Keychain Circle Notification/en.lproj/InfoPlist.strings"; sourceTree = SOURCE_ROOT; }; @@ -12065,6 +12833,7 @@ DCEA5D951E3014250089CF55 /* CKKSZone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSZone.h; sourceTree = ""; }; DCEA5D961E3014250089CF55 /* CKKSZone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSZone.m; sourceTree = ""; }; DCEE1E851D93424D00DC0EB7 /* com.apple.securityd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.securityd.plist; path = OSX/sec/ipc/com.apple.securityd.plist; sourceTree = SOURCE_ROOT; }; + DCF158C52064895C00B87B6D /* CKKSAPSReceiverTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSAPSReceiverTests.h; sourceTree = ""; }; DCF783141D88B4DE00E694BB /* libsecurity_apple_csp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_apple_csp.a; sourceTree = BUILT_PRODUCTS_DIR; }; DCF783151D88B60D00E694BB /* aesCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aesCommon.h; sourceTree = ""; }; DCF783161D88B60D00E694BB /* aescsp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aescsp.cpp; sourceTree = ""; }; @@ -12487,6 +13256,15 @@ E7FE40C71DC8084600F0F5B6 /* CKDSimulatedAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CKDSimulatedAccount.h; path = ../../SOSCircle/Regressions/CKDSimulatedAccount.h; sourceTree = ""; }; E7FE40C81DC8084600F0F5B6 /* CKDSimulatedAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKDSimulatedAccount.m; path = ../../SOSCircle/Regressions/CKDSimulatedAccount.m; sourceTree = ""; }; E7FEFB80169E26E200E18152 /* sub_commands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sub_commands.h; sourceTree = ""; }; + EB056E3E1FE5E390000A771E /* DeviceSimulator.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = DeviceSimulator.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; + EB056E401FE5E390000A771E /* DeviceSimulatorProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceSimulatorProtocol.h; sourceTree = ""; }; + EB056E411FE5E390000A771E /* DeviceSimulator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceSimulator.h; sourceTree = ""; }; + EB056E421FE5E390000A771E /* DeviceSimulator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeviceSimulator.m; sourceTree = ""; }; + EB056E441FE5E390000A771E /* DeviceSimulatorMain.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeviceSimulatorMain.m; sourceTree = ""; }; + EB056E461FE5E391000A771E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EB05C4F11FE5E48A00D68712 /* MultiDeviceSimulatorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MultiDeviceSimulatorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB05C4F31FE5E48B00D68712 /* MultiDeviceSimulatorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MultiDeviceSimulatorTests.m; sourceTree = ""; }; + EB05C4F51FE5E48B00D68712 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; EB0BC93E1C3C791500785842 /* secedumodetest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secedumodetest; sourceTree = BUILT_PRODUCTS_DIR; }; EB0BC9651C3C794700785842 /* secedumodetest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = secedumodetest.entitlements; path = secedumodetest/secedumodetest.entitlements; sourceTree = ""; }; EB0BC9661C3C794700785842 /* secedumodetest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = secedumodetest.m; path = secedumodetest/secedumodetest.m; sourceTree = ""; }; @@ -12553,11 +13331,17 @@ EBB8399B1E295B8F00853BAC /* secfuzzer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = secfuzzer.m; sourceTree = ""; }; EBB839A51E29665D00853BAC /* secfuzzer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secfuzzer; sourceTree = BUILT_PRODUCTS_DIR; }; EBC15B1B1DB4306C00126882 /* com.apple.secd.sb */ = {isa = PBXFileReference; lastKnownFileType = text; path = com.apple.secd.sb; sourceTree = ""; }; + EBC73F4A209A0BEF00AE3350 /* install-test-framework.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "install-test-framework.sh"; path = "xcscripts/install-test-framework.sh"; sourceTree = ""; }; + EBCE165C1FE6F4CE002E7CCC /* DeviceSimulator-Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "DeviceSimulator-Entitlements.plist"; sourceTree = ""; }; + EBCE165E1FE7313C002E7CCC /* MultiDeviceNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MultiDeviceNetworking.h; sourceTree = ""; }; + EBCE165F1FE7313C002E7CCC /* MultiDeviceNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MultiDeviceNetworking.m; sourceTree = ""; }; + EBCE16611FE73327002E7CCC /* MultiDeviceNetworkingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MultiDeviceNetworkingProtocol.h; sourceTree = ""; }; EBCF01001DF501310055AF97 /* swcagent-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "swcagent-entitlements.plist"; sourceTree = ""; }; EBCF73F11CE45F8600BED7CA /* secitemfunctionality.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = secitemfunctionality.entitlements; path = secitemfunctionality/secitemfunctionality.entitlements; sourceTree = ""; }; EBCF73F21CE45F8600BED7CA /* secitemfunctionality.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = secitemfunctionality.m; path = secitemfunctionality/secitemfunctionality.m; sourceTree = ""; }; EBCF73FC1CE45F9C00BED7CA /* secitemfunctionality */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secitemfunctionality; sourceTree = BUILT_PRODUCTS_DIR; }; EBD8AD632004B45500588BBA /* SecurityCustomSignposts.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = SecurityCustomSignposts.plist; path = base/SecurityCustomSignposts.plist; sourceTree = ""; }; + EBE202752092913500B48020 /* SecurityInduceLowDisk.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = SecurityInduceLowDisk.plist; sourceTree = ""; }; EBE54D771BE33227000C4856 /* libmis.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libmis.dylib; path = usr/lib/libmis.dylib; sourceTree = SDKROOT; }; EBE700FE204676E700E00A87 /* secdmock_db_version_11_1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = secdmock_db_version_11_1.h; sourceTree = ""; }; EBEEEE351EA31A8300E15F5C /* SOSControlHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSControlHelper.h; sourceTree = ""; }; @@ -12594,6 +13378,7 @@ EB3409B01C1D627400D77661 /* Foundation.framework in Frameworks */, DCD22D8B1D8CCC58001C9B81 /* libASN1_not_installed.a in Frameworks */, DC59E9A71D91C7C7001BDDF5 /* libCMS.a in Frameworks */, + D491116C2095594A0066A1E4 /* CoreData.framework in Frameworks */, DC00ABD71D821F3F00513D74 /* libsecurity.a in Frameworks */, DC00ABD81D821F4300513D74 /* libsecdRegressions.a in Frameworks */, DC00ABD91D821F4700513D74 /* libsecurityd_ios.a in Frameworks */, @@ -12611,7 +13396,6 @@ 0C0BDB8F1756A6D500BC1A7E /* libMobileGestalt.dylib in Frameworks */, 0C0BDB881756A51000BC1A7E /* libsqlite3.dylib in Frameworks */, BE8ABDD81DC2DD9100EC2D58 /* libz.dylib in Frameworks */, - 0C59605D1FB2D95D0095BA29 /* libprequelite.tbd in Frameworks */, 4469FBFF1AA0A4820021AA26 /* libctkclient_test.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -12656,6 +13440,7 @@ 0C85DFF51FB38BB6000343A7 /* libaks_acl.a in Frameworks */, 0C85DFF61FB38BB6000343A7 /* libDER.a in Frameworks */, 0C85DFF71FB38BB6000343A7 /* libbsm.dylib in Frameworks */, + D491116E209559510066A1E4 /* CoreData.framework in Frameworks */, 0C85DFF81FB38BB6000343A7 /* libcoreauthd_client.a in Frameworks */, 0C85DFF91FB38BB6000343A7 /* libctkclient.a in Frameworks */, 0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */, @@ -12671,6 +13456,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 0C9AEEB020783FBB00BF6237 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C9AEEBB20783FF900BF6237 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0CF406342072E3E3003D6A7F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C5663EF20BE2E220035F362 /* libutilities.a in Frameworks */, + 0C9AEEBE207843D000BF6237 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 225394AF1E3080A600D3CD9B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -12678,6 +13480,34 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3DD1FF2F201C07F30086D049 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3DD1FFAA201FC5C30086D049 /* libcoretls.tbd in Frameworks */, + 3DD1FFAB201FC5C30086D049 /* libcoretls_cfhelpers.tbd in Frameworks */, + 3DD1FFA7201FC5B90086D049 /* Foundation.framework in Frameworks */, + 3DD1FFA5201FC59D0086D049 /* libsecurity_ssl.a in Frameworks */, + 3DD1FFA4201FC58F0086D049 /* libutilities.a in Frameworks */, + 3DD1FFA3201FC5870086D049 /* libDiagnosticMessagesClient.tbd in Frameworks */, + 3DD1FFA2201FC5800086D049 /* SecurityFoundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3DD1FFC3201FDB1D0086D049 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3DD1FFD2201FDCA80086D049 /* Security.framework in Frameworks */, + 3DD1FFC4201FDB1D0086D049 /* libcoretls.tbd in Frameworks */, + 3DD1FFC5201FDB1D0086D049 /* libcoretls_cfhelpers.tbd in Frameworks */, + 3DD1FFC6201FDB1D0086D049 /* Foundation.framework in Frameworks */, + 3DD1FFC8201FDB1D0086D049 /* libsecurity_ssl.a in Frameworks */, + 3DD1FFC9201FDB1D0086D049 /* libutilities.a in Frameworks */, + 3DD1FFCB201FDB1D0086D049 /* SecurityFoundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 438169091B4EDCBD00C54D58 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -12697,35 +13527,60 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4718AE17205B39620068EC3F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4718AEE7205B3A420068EC3F /* libsecurityd_bridge.a in Frameworks */, + 4718AE19205B39620068EC3F /* libMobileGestalt.dylib in Frameworks */, + 4718AE1A205B39620068EC3F /* Foundation.framework in Frameworks */, + 4718AE1B205B39620068EC3F /* libutilities.a in Frameworks */, + 4718AE1C205B39620068EC3F /* CoreFoundation.framework in Frameworks */, + 4718AE1E205B39620068EC3F /* libSecureObjectSyncServer.a in Frameworks */, + 4718AE1F205B39620068EC3F /* libSecureObjectSyncFramework.a in Frameworks */, + 4718AE20205B39620068EC3F /* libSWCAgent.a in Frameworks */, + 4718AE21205B39620068EC3F /* Security.framework in Frameworks */, + D491116B2095593E0066A1E4 /* CoreData.framework in Frameworks */, + 4718AE22205B39620068EC3F /* SystemConfiguration.framework in Frameworks */, + 4718AE23205B39620068EC3F /* IOKit.framework in Frameworks */, + 4718AE24205B39620068EC3F /* libaks_acl.a in Frameworks */, + 4718AE25205B39620068EC3F /* libsqlite3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4718AE9C205B39C40068EC3F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4727FBB41F9918580003AE36 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 479231F02065C52D00B2718C /* Security.framework in Frameworks */, + 479231EF2065C52200B2718C /* libsecurity.a in Frameworks */, + 479231E82065B31300B2718C /* libsecurityd_ios.a in Frameworks */, 477A1F5220320E4A00ACD81D /* Accounts.framework in Frameworks */, - 472339691FD7156800CB6A72 /* CoreCDP.framework in Frameworks */, 472339671FD7155E00CB6A72 /* libprequelite.dylib in Frameworks */, 47D183911FB3827800CFCD89 /* OCMock.framework in Frameworks */, 4727FBEA1F9922190003AE36 /* libregressionBase.a in Frameworks */, 4727FBE91F9921D10003AE36 /* libACM.a in Frameworks */, 4727FBE71F99218A0003AE36 /* ApplePushService.framework in Frameworks */, 4727FBE51F99217B0003AE36 /* SharedWebCredentials.framework in Frameworks */, - 4727FBE31F9921660003AE36 /* MobileKeyBag.framework in Frameworks */, 4727FBE11F9921300003AE36 /* IOKit.framework in Frameworks */, - 4727FBDF1F99211D0003AE36 /* libaks.a in Frameworks */, - 4727FBDD1F9920F20003AE36 /* libaks_acl.a in Frameworks */, 4727FBDB1F9920CC0003AE36 /* WirelessDiagnostics.framework in Frameworks */, 4727FBD91F9920BC0003AE36 /* SystemConfiguration.framework in Frameworks */, 4727FBD71F99209C0003AE36 /* libSecureObjectSyncServer.a in Frameworks */, 4727FBD61F9920960003AE36 /* libSecureObjectSyncFramework.a in Frameworks */, 4727FBD51F9920510003AE36 /* ProtocolBuffer.framework in Frameworks */, + D4911172209559630066A1E4 /* CoreData.framework in Frameworks */, 4727FBD31F9920290003AE36 /* CloudKit.framework in Frameworks */, 4727FBD11F991F990003AE36 /* libMobileGestalt.dylib in Frameworks */, 4727FBCE1F991F820003AE36 /* SecurityFoundation.framework in Frameworks */, 4727FBCD1F991F660003AE36 /* libsqlite3.dylib in Frameworks */, - 4727FBCB1F991F510003AE36 /* Security.framework in Frameworks */, 4727FBC91F991E5A0003AE36 /* libutilities.a in Frameworks */, - 4727FBC81F991E460003AE36 /* libsecurityd_ios.a in Frameworks */, - 4727FBC71F991E3A0003AE36 /* libsecurity.a in Frameworks */, 4727FBC61F991DE90003AE36 /* libsecdRegressions.a in Frameworks */, 4727FBC51F991C470003AE36 /* Foundation.framework in Frameworks */, ); @@ -12747,18 +13602,29 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4771D96F209A755800BA9772 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4771D9A2209B7C3900BA9772 /* Accounts.framework in Frameworks */, + 4771D9A0209B7C2700BA9772 /* Security.framework in Frameworks */, + 4771D973209A755800BA9772 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 478D427D1FD72A8100CAB645 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 479231EE2065B32200B2718C /* libsecurityd_ios.a in Frameworks */, 477A1F5320320E5100ACD81D /* Accounts.framework in Frameworks */, 478D429F1FD72C8400CAB645 /* AppleSystemInfo.framework in Frameworks */, 478D429E1FD72C4800CAB645 /* CrashReporterSupport.framework in Frameworks */, - 478D427E1FD72A8100CAB645 /* CoreCDP.framework in Frameworks */, 478D427F1FD72A8100CAB645 /* libprequelite.dylib in Frameworks */, 478D42801FD72A8100CAB645 /* OCMock.framework in Frameworks */, 478D42811FD72A8100CAB645 /* libregressionBase.a in Frameworks */, 478D42821FD72A8100CAB645 /* libACM.a in Frameworks */, + D4911173209559630066A1E4 /* CoreData.framework in Frameworks */, 478D42831FD72A8100CAB645 /* ApplePushService.framework in Frameworks */, 478D42841FD72A8100CAB645 /* SharedWebCredentials.framework in Frameworks */, 478D42851FD72A8100CAB645 /* MobileKeyBag.framework in Frameworks */, @@ -12771,17 +13637,25 @@ 478D428C1FD72A8100CAB645 /* libSecureObjectSyncFramework.a in Frameworks */, 478D428D1FD72A8100CAB645 /* ProtocolBuffer.framework in Frameworks */, 478D428E1FD72A8100CAB645 /* CloudKit.framework in Frameworks */, + DC066DF02102563300694EAF /* Security.framework in Frameworks */, 478D42901FD72A8100CAB645 /* SecurityFoundation.framework in Frameworks */, 478D42911FD72A8100CAB645 /* libsqlite3.dylib in Frameworks */, - 478D42921FD72A8100CAB645 /* Security.framework in Frameworks */, 478D42931FD72A8100CAB645 /* libutilities.a in Frameworks */, - 478D42941FD72A8100CAB645 /* libsecurityd_ios.a in Frameworks */, 478D42951FD72A8100CAB645 /* libsecurity.a in Frameworks */, 478D42961FD72A8100CAB645 /* libsecdRegressions.a in Frameworks */, 478D42971FD72A8100CAB645 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; + 47C2F1802059CB680062DE30 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 47C2F1842059CB680062DE30 /* Foundation.framework in Frameworks */, + D49111702095595B0066A1E4 /* CoreData.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 47C51B811EEA657D0032D9E5 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -12822,7 +13696,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D459A1781E9FFE60009ED74B /* CoreCDP.framework in Frameworks */, + 0C9FB40720D872A600864612 /* CoreCDP.framework in Frameworks */, 43DB54551BB1F8920083C3F1 /* ProtectedCloudStorage.framework in Frameworks */, 4C8A38C917B93DF10001B4C0 /* CloudServices.framework in Frameworks */, 4C7913251799A5CC00A9633E /* MobileCoreServices.framework in Frameworks */, @@ -12898,7 +13772,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C59605C1FB2D9280095BA29 /* libprequelite.tbd in Frameworks */, + 0C9FB40920D8735500864612 /* CoreCDP.framework in Frameworks */, 47D13F631E8447FB0063B6E2 /* SecurityFoundation.framework in Frameworks */, EBE9019A1C22852C007308C6 /* AggregateDictionary.framework in Frameworks */, 438168BB1B4ED42300C54D58 /* CoreFoundation.framework in Frameworks */, @@ -12962,8 +13836,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C8BBF261FCB561C00580909 /* CoreCDP.framework in Frameworks */, - 0C59605A1FB2D8E50095BA29 /* libprequelite.tbd in Frameworks */, D46246BA1F9AE7A000D63882 /* libDER.a in Frameworks */, DCCD34001E4001AD00AA4AD1 /* libACM.a in Frameworks */, DCAB14271E40039600C81511 /* libASN1_not_installed.a in Frameworks */, @@ -12987,8 +13859,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D4574AA3203E68E0006D9B82 /* AuthKit.framework in Frameworks */, - D4574AA1203E6893006D9B82 /* Accounts.framework in Frameworks */, + 5AF7630920520870001557AE /* AuthKit.framework in Frameworks */, + 5A4E527B2051D857009D5826 /* Accounts.framework in Frameworks */, D4119E79202BDF580048587B /* libz.tbd in Frameworks */, 6CDB601B1FA93A2000410924 /* libprequelite.tbd in Frameworks */, 6CDB601A1FA93A1800410924 /* libsqlite3.tbd in Frameworks */, @@ -13022,7 +13894,6 @@ 6C9808581E788AEB00E70590 /* libbsm.dylib in Frameworks */, 6C9808591E788AEB00E70590 /* libcoreauthd_client.a in Frameworks */, 6C98085A1E788AEB00E70590 /* libctkclient.a in Frameworks */, - 0C5960651FB2E2800095BA29 /* libprequelite.tbd in Frameworks */, 6C98085B1E788AEB00E70590 /* libsqlite3.0.dylib in Frameworks */, 6C98085C1E788AEB00E70590 /* libz.dylib in Frameworks */, ); @@ -13051,7 +13922,6 @@ 6C9808941E788AFD00E70590 /* libbsm.dylib in Frameworks */, 6C9808951E788AFD00E70590 /* libcoreauthd_client.a in Frameworks */, 6C9808961E788AFD00E70590 /* libctkclient.a in Frameworks */, - 0C59605F1FB2D9F60095BA29 /* libprequelite.tbd in Frameworks */, 6C9808971E788AFD00E70590 /* libsqlite3.0.dylib in Frameworks */, 6C9808981E788AFD00E70590 /* libz.dylib in Frameworks */, ); @@ -13070,8 +13940,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D4574AA2203E68C8006D9B82 /* AuthKit.framework in Frameworks */, - D4574AA0203E618B006D9B82 /* Accounts.framework in Frameworks */, + 5AF762FF2051F990001557AE /* AuthKit.framework in Frameworks */, + 5A4E52792051D7FA009D5826 /* Accounts.framework in Frameworks */, D4119E78202BDF490048587B /* libz.tbd in Frameworks */, 6CAA8D3B1F8431AE007B6E03 /* Foundation.framework in Frameworks */, 6CAA8D3A1F8431A7007B6E03 /* libutilities.a in Frameworks */, @@ -13118,6 +13988,7 @@ DCD8A1E71E09F85400E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, DC00AB831D821C9A00513D74 /* libSWCAgent.a in Frameworks */, 790851EE0CA9B3410083CC4D /* Security.framework in Frameworks */, + D491116A2095593E0066A1E4 /* CoreData.framework in Frameworks */, E71F3E3116EA69A900FAF9B4 /* SystemConfiguration.framework in Frameworks */, 4CAF66190F3A6FCD0064A534 /* IOKit.framework in Frameworks */, 4432B15E1A014D37000958DC /* libaks_acl.a in Frameworks */, @@ -13208,18 +14079,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - CD276C241A83F60C003226BC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - DC65E7311D8CB33800152EF0 /* libutilities.a in Frameworks */, - CD0637551A84060600C81E74 /* Security.framework in Frameworks */, - CD0637571A84068F00C81E74 /* IDS.framework in Frameworks */, - CD0637561A84065F00C81E74 /* IOKit.framework in Frameworks */, - CD276C281A83F60C003226BC /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; D41257CC1E9410A300781F23 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -13251,6 +14110,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DAE40BC820CF3E46002D5674 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DAE40BC920CF3E46002D5674 /* Security.framework in Frameworks */, + DAE40BCA20CF3E46002D5674 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DC0067BC1D87876F005AF8DB /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -13434,6 +14302,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4C47FA9420A51DD800384CB6 /* AppleFSCompression.framework in Frameworks */, CD9F2AFB1DF24BAF00AD3577 /* Foundation.framework in Frameworks */, DCD22D4B1D8CBF54001C9B81 /* libASN1_not_installed.a in Frameworks */, DC00AB6F1D821C3400513D74 /* libSecItemShimOSX.a in Frameworks */, @@ -13510,7 +14379,7 @@ DC3502D61E02118000BC0587 /* libsecurity.a in Frameworks */, DC3502CF1E020E2900BC0587 /* libutilities.a in Frameworks */, DC222C351E02418100B09171 /* CFNetwork.framework in Frameworks */, - 0C8BBF2B1FCB575800580909 /* CoreCDP.framework in Frameworks */, + D491116F209559510066A1E4 /* CoreData.framework in Frameworks */, DC3502DF1E02129F00BC0587 /* Foundation.framework in Frameworks */, DC3502D21E02113900BC0587 /* IOKit.framework in Frameworks */, DC3502E91E02172C00BC0587 /* OCMock.framework in Frameworks */, @@ -13520,7 +14389,6 @@ DC222C361E02419B00B09171 /* libbsm.dylib in Frameworks */, DC3502E41E02130600BC0587 /* libcoreauthd_client.a in Frameworks */, DC3502E21E0212D100BC0587 /* libctkclient.a in Frameworks */, - 0C5960601FB2DA310095BA29 /* libprequelite.tbd in Frameworks */, DC3502CA1E020DC100BC0587 /* libsqlite3.0.dylib in Frameworks */, DC222C321E0240D300B09171 /* libz.dylib in Frameworks */, ); @@ -13571,6 +14439,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0C9FB40820D8731800864612 /* CoreCDP.framework in Frameworks */, DC52EC2F1D80CFB200B0A59C /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -13670,6 +14539,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4C47FA9320A51DC900384CB6 /* AppleFSCompression.framework in Frameworks */, CD9F2AFA1DF249CF00AD3577 /* Foundation.framework in Frameworks */, EBF3745F1DBFB32A0065D840 /* libobjc.dylib in Frameworks */, DC5AC0D61D83548300CF422C /* libDiagnosticMessagesClient.dylib in Frameworks */, @@ -13686,6 +14556,8 @@ DCD22D6F1D8CC728001C9B81 /* libsecurity_cdsa_client.a in Frameworks */, DC5AC0C91D8353D100CF422C /* libbsm.dylib in Frameworks */, DCD22D701D8CC733001C9B81 /* libutilities.a in Frameworks */, + DC63D70820B3931100D088AD /* libxar.tbd in Frameworks */, + DC72BCD720B3A7DF00B26495 /* libOpenScriptingUtil.tbd in Frameworks */, DC5AC0C71D8353C800CF422C /* PCSC.framework in Frameworks */, DC5AC0C51D8353C200CF422C /* Security.framework in Frameworks */, DC5AC0C41D8353BB00CF422C /* System.framework in Frameworks */, @@ -13698,9 +14570,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 47C2F1762059A2300062DE30 /* libprequelite.tbd in Frameworks */, 0CA4EC10202BB5AF002B1D96 /* Accounts.framework in Frameworks */, - 0C8BBF2D1FCB5A2900580909 /* CoreCDP.framework in Frameworks */, - 0C5960631FB2E1A70095BA29 /* libprequelite.tbd in Frameworks */, 47B90C901F350966006500BC /* CrashReporterSupport.framework in Frameworks */, 474B5FC81E662E79007546F8 /* SecurityFoundation.framework in Frameworks */, D43B88721E72298500F86F19 /* MobileAsset.framework in Frameworks */, @@ -13715,6 +14586,7 @@ DCD22D611D8CC2F8001C9B81 /* libbsm.dylib in Frameworks */, DC610A2B1D78F129002223DE /* libcoreauthd_test_client.a in Frameworks */, DC610A2F1D78F129002223DE /* libctkclient_test.a in Frameworks */, + D491116D2095594B0066A1E4 /* CoreData.framework in Frameworks */, DC610A2E1D78F129002223DE /* libsqlite3.dylib in Frameworks */, BEE523D91DACAA2500DD0AA3 /* libz.dylib in Frameworks */, DC65E7C31D8CBBA200152EF0 /* libregressionBase.a in Frameworks */, @@ -13899,7 +14771,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C5960621FB2E0EC0095BA29 /* libprequelite.tbd in Frameworks */, + 0C0582AE20D9657800D7BD7A /* CoreCDP.framework in Frameworks */, 6C1F93111DD5E41A00585608 /* libDiagnosticMessagesClient.dylib in Frameworks */, DCE4E6AE1D7A3C6A00AFB96E /* AppleSystemInfo.framework in Frameworks */, DCE4E6AD1D7A3B9700AFB96E /* libaks.a in Frameworks */, @@ -13936,6 +14808,7 @@ DCE4E7C61D7A468300AFB96E /* libaks.a in Frameworks */, DCE4E75E1D7A43B500AFB96E /* CoreFoundation.framework in Frameworks */, DCE4E7BF1D7A463400AFB96E /* Security.framework in Frameworks */, + 091B39732063B67700ECAB6F /* RemoteServiceDiscovery.framework in Frameworks */, DCE4E7C11D7A463E00AFB96E /* SecurityFoundation.framework in Frameworks */, DCE4E7541D7A43B500AFB96E /* Foundation.framework in Frameworks */, DCE4E7681D7A43B500AFB96E /* IOKit.framework in Frameworks */, @@ -13998,12 +14871,12 @@ DC00AB7C1D821C7100513D74 /* libsecurityd_ios.a in Frameworks */, DCE4E8131D7A4E5300AFB96E /* CoreFoundation.framework in Frameworks */, DCE4E8121D7A4E4F00AFB96E /* IOKit.framework in Frameworks */, + D49111692095593D0066A1E4 /* CoreData.framework in Frameworks */, DCDCCB3C1DF25D74006E840E /* ApplePushService.framework in Frameworks */, DCDCCB3B1DF25D69006E840E /* CloudKit.framework in Frameworks */, DCD22D721D8CC804001C9B81 /* SystemConfiguration.framework in Frameworks */, - DCE4E80F1D7A4E4600AFB96E /* Security.framework in Frameworks */, + DCD504C320CB293700F37D26 /* Security.framework in Frameworks */, DC4DB16A1E26E9F900CD6769 /* ProtocolBuffer.framework in Frameworks */, - 0C8BBFFD1FCE8F3300580909 /* CoreCDP.framework in Frameworks */, DCE4E82C1D7A56FF00AFB96E /* AppleSystemInfo.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -14058,6 +14931,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0C0582B820D9B70D00D7BD7A /* CoreCDP.framework in Frameworks */, CD112FC51DDA31AD00C77A07 /* Accounts.framework in Frameworks */, 0CC319241DA46FBF005D42EA /* ProtectedCloudStorage.framework in Frameworks */, DCE4E9401D7F3E4D00AFB96E /* Security.framework in Frameworks */, @@ -14067,7 +14941,6 @@ DCE4E93A1D7F3DF500AFB96E /* CrashReporterSupport.framework in Frameworks */, DCE4E9381D7F3DB500AFB96E /* Cocoa.framework in Frameworks */, DCE4E9371D7F3DAF00AFB96E /* CloudServices.framework in Frameworks */, - DCE4E9421D7F3E6E00AFB96E /* CoreCDP.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14125,7 +14998,6 @@ buildActionMask = 2147483647; files = ( D4C6C5D01FB3B45E007EA57E /* libarchive.2.dylib in Frameworks */, - 0C59605E1FB2D9990095BA29 /* libprequelite.tbd in Frameworks */, D40B6A8F1E2B643D00CD6EE5 /* libtrustd.a in Frameworks */, DC00ABC01D821EBE00513D74 /* libSharedRegressions.a in Frameworks */, EBE9019B1C2285D4007308C6 /* AggregateDictionary.framework in Frameworks */, @@ -14210,6 +15082,42 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EB056E3B1FE5E390000A771E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EBCE16411FE6DE5A002E7CCC /* libDER.a in Frameworks */, + EBCE16421FE6DE5A002E7CCC /* SecurityFoundation.framework in Frameworks */, + EBCE16431FE6DE5A002E7CCC /* libASN1_not_installed.a in Frameworks */, + EBCE165D1FE71821002E7CCC /* libsecurityd_ios.a in Frameworks */, + EBCE16451FE6DE5A002E7CCC /* libSecureObjectSyncFramework.a in Frameworks */, + EBCE16461FE6DE5A002E7CCC /* libSecureObjectSyncServer.a in Frameworks */, + EBCE16471FE6DE5A002E7CCC /* libsecurity.a in Frameworks */, + EBCE16481FE6DE5A002E7CCC /* libutilities.a in Frameworks */, + EBCE16491FE6DE5A002E7CCC /* CFNetwork.framework in Frameworks */, + EBCE164B1FE6DE5A002E7CCC /* Foundation.framework in Frameworks */, + EBCE164C1FE6DE5A002E7CCC /* IOKit.framework in Frameworks */, + EBCE164E1FE6DE5A002E7CCC /* SystemConfiguration.framework in Frameworks */, + EBCE164F1FE6DE5A002E7CCC /* libACM.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 */, + EBCE16541FE6DE5A002E7CCC /* libprequelite.tbd in Frameworks */, + EBCE16551FE6DE5A002E7CCC /* libsqlite3.0.dylib in Frameworks */, + D4911171209559620066A1E4 /* CoreData.framework in Frameworks */, + EBCE16561FE6DE5A002E7CCC /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EB05C4EE1FE5E48A00D68712 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EBCE166B1FE74688002E7CCC /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EB0BC9391C3C791500785842 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14295,7 +15203,6 @@ EB49B2C1202DEF8D003F34A0 /* libASN1_not_installed.a in Frameworks */, EB49B2C0202DEF7D003F34A0 /* libutilities.a in Frameworks */, EB49B308202FF421003F34A0 /* OCMock.framework in Frameworks */, - EB49B2E2202DFDA3003F34A0 /* CoreCDP.framework in Frameworks */, EB49B2D2202DF17D003F34A0 /* SecurityFoundation.framework in Frameworks */, EB49B2CD202DF0F9003F34A0 /* SystemConfiguration.framework in Frameworks */, EB49B2C7202DF0E9003F34A0 /* IOKit.framework in Frameworks */, @@ -14489,12 +15396,31 @@ 0CF0E2DD1F8EE37C00BD18E4 /* Signin Metrics */ = { isa = PBXGroup; children = ( - 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */, - 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */, + 0CF405FB2072E351003D6A7F /* Resources */, + 0CF0E2E71F8EE40700BD18E4 /* SFSignInAnalytics.h */, + 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */, + 0C108C4B208A677100E8CF70 /* SFSignInAnalytics+Internal.h */, + 0CF405F32072E295003D6A7F /* tests */, ); path = "Signin Metrics"; sourceTree = ""; }; + 0CF405F32072E295003D6A7F /* tests */ = { + isa = PBXGroup; + children = ( + 0CF405F42072E2BF003D6A7F /* SFSignInAnalyticsTests.m */, + ); + path = tests; + sourceTree = ""; + }; + 0CF405FB2072E351003D6A7F /* Resources */ = { + isa = PBXGroup; + children = ( + 0CF405FC2072E352003D6A7F /* SFTMTests-Info.plist */, + ); + path = Resources; + sourceTree = ""; + }; 107226CF0D91DB32003CF14F /* sectask */ = { isa = PBXGroup; children = ( @@ -14506,6 +15432,34 @@ path = ../../../sectask; sourceTree = ""; }; + 3DD1FE72201AA38A0086D049 /* SecureTransportTests */ = { + isa = PBXGroup; + children = ( + 3DD1FE7E201AA50F0086D049 /* SecureTransportTests.m */, + 3DD1FE7A201AA50D0086D049 /* STLegacyTests-Entitlements.plist */, + 3DD1FE8A201AA5140086D049 /* STLegacyTests.h */, + 3DD1FE8C201AA5150086D049 /* STLegacyTests.m */, + 3DD1FE89201AA5140086D049 /* STLegacyTests+ciphers.m */, + 3DD1FE87201AA5130086D049 /* STLegacyTests+clientauth.m */, + 3DD1FE78201AA50C0086D049 /* STLegacyTests+clientauth41.m */, + 3DD1FE83201AA5110086D049 /* STLegacyTests+crashes.m */, + 3DD1FE82201AA5110086D049 /* STLegacyTests+dhe.m */, + 3DD1FE84201AA5120086D049 /* STLegacyTests+falsestart.m */, + 3DD1FE7B201AA50D0086D049 /* STLegacyTests+noconn.m */, + 3DD1FE85201AA5120086D049 /* STLegacyTests+renegotiate.m */, + 3DD1FE8B201AA5150086D049 /* STLegacyTests+sessioncache.m */, + 3DD1FE80201AA5100086D049 /* STLegacyTests+sessionstate.m */, + 3DD1FE7F201AA50F0086D049 /* STLegacyTests+sni.m */, + 3DD1FE88201AA5130086D049 /* STLegacyTests+split.m */, + 3DD1FE81201AA5100086D049 /* STLegacyTests+sslciphers.m */, + 3DD1FE7D201AA50E0086D049 /* STLegacyTests+tls12.m */, + 3DD1FE7C201AA50E0086D049 /* Info.plist */, + 3DD1FE86201AA5120086D049 /* SecureTransport_iosTests.plist */, + 3DD1FE79201AA50D0086D049 /* SecureTransport_macosTests.plist */, + ); + path = SecureTransportTests; + sourceTree = ""; + }; 4381690E1B4EDCBD00C54D58 /* SOSCCAuthPlugin */ = { isa = PBXGroup; children = ( @@ -14525,6 +15479,16 @@ name = seckeychainnetworkextensionstest; sourceTree = ""; }; + 470D96651FCDE45C0065FE90 /* CoreDataKeychain */ = { + isa = PBXGroup; + children = ( + 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */, + 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */, + 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */, + ); + path = CoreDataKeychain; + sourceTree = ""; + }; 4723C9B51F152E8E0082882F /* Analytics */ = { isa = PBXGroup; children = ( @@ -14546,6 +15510,7 @@ 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */, 6C69518E1F75A7DC00F68F91 /* SFAnalyticsSQLiteStore.h */, 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */, + 0CD8D654207D6E65005CDBE8 /* SFAnalytics+Signin.h */, ); path = Analytics; sourceTree = ""; @@ -14566,11 +15531,14 @@ 4727FBB81F9918590003AE36 /* secdxctests */ = { isa = PBXGroup; children = ( - 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */, - 4727FBBB1F9918590003AE36 /* Info.plist */, - 477A1FE1203763A500ACD81D /* KeychainAPITests.m */, 477A1FEB2037A0E000ACD81D /* KeychainXCTest.h */, 477A1FEC2037A0E000ACD81D /* KeychainXCTest.m */, + 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */, + 470D96841FCE34370065FE90 /* CDKeychainTests.m */, + 47B503C5203B97A000722164 /* SFCredentialStoreTests.m */, + 477A1FE1203763A500ACD81D /* KeychainAPITests.m */, + 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */, + 4727FBBB1F9918590003AE36 /* Info.plist */, ); path = secdxctests; sourceTree = ""; @@ -14593,6 +15561,24 @@ name = seckeychainnetworkextensionunauthorizedaccesstest; sourceTree = ""; }; + 4771D974209A755800BA9772 /* KeychainDataclassOwner */ = { + isa = PBXGroup; + children = ( + 4771D975209A755800BA9772 /* Info.plist */, + 4771D97E209A75FE00BA9772 /* KeychainDataclassOwner.h */, + 4771D97F209A75FE00BA9772 /* KeychainDataclassOwner.m */, + ); + path = KeychainDataclassOwner; + sourceTree = ""; + }; + 47C2F1852059CB680062DE30 /* KeychainResources */ = { + isa = PBXGroup; + children = ( + 47C2F1862059CB680062DE30 /* Info.plist */, + ); + path = KeychainResources; + sourceTree = ""; + }; 47C51B851EEA657D0032D9E5 /* SecurityUnitTests */ = { isa = PBXGroup; children = ( @@ -14657,8 +15643,10 @@ DC5AC1FF1D83650C00CF422C /* securityd */, 6C69517B1F758E1000F68F91 /* supd */, DC0BC4E51D8B6AA600070CB0 /* applications */, + EB81D0CB1FE5838B00FD7F16 /* MultiDeviceSimulator */, DC5AC2011D83663C00CF422C /* tests */, EB2CA5311D2C30CD00AB770F /* xcconfig */, + EBC73F44209A0BB200AE3350 /* xcscripts */, EBF374731DC055590065D840 /* security-sysdiagnose */, E7FCBE401314471B000DE34E /* Frameworks */, 4C8BC620097DBC1B00C781D5 /* Libraries */, @@ -14666,8 +15654,6 @@ 4C4CE9120AF81F0E0056B01D /* README */, 4CAB97FD1114CC5300EFB38D /* README.keychain */, 4C4CE9070AF81ED80056B01D /* TODO */, - 0CE98BAD1FA93AA900CF1D54 /* CKKSTests-Info.plist */, - 0C85E0041FB38BB7000343A7 /* OTTests-Info.plist */, ); sourceTree = ""; }; @@ -14690,7 +15676,6 @@ BE442BC118B7FDB800F24DAE /* swcagent */, BE197F2619116FD100BA91D1 /* SharedWebCredentialViewService.app */, 5E10992519A5E55800A60E2B /* ISACLProtectedItems.bundle */, - CD276C271A83F60C003226BC /* KeychainSyncingOverIDSProxy.bundle */, 5EBE247A1B00CCAE0007DB0E /* secacltests */, 4381690C1B4EDCBD00C54D58 /* SOSCCAuthPlugin.bundle */, EB9C1D7A1BDFD0E000F89272 /* secbackupntest */, @@ -14815,8 +15800,19 @@ 6CAA8D201F842FB3007B6E03 /* securityuploadd */, 6C4605B81F882B9B001421B6 /* KeychainAnalyticsTests.xctest */, 0C8BBF081FCB446400580909 /* otctl */, + EB056E3E1FE5E390000A771E /* DeviceSimulator.xpc */, + EB05C4F11FE5E48A00D68712 /* MultiDeviceSimulatorTests.xctest */, 478D429C1FD72A8100CAB645 /* secdxctests_mac.xctest */, EB49B2AE202D877F003F34A0 /* secdmockaks.xctest */, + 3DD1FF4D201C07F30086D049 /* SecureTransport_macos_tests.xctest */, + 3DD1FFD0201FDB1D0086D049 /* SecureTransport_ios_tests.xctest */, + 47C2F1832059CB680062DE30 /* KeychainResources.bundle */, + 4718AE2D205B39620068EC3F /* securityd */, + 4718AEE2205B39C40068EC3F /* libsecurityd_bridge.a */, + 0CF406502072E3E3003D6A7F /* SignInAnalyticsTests_ios.xctest */, + 0C9AEEB720783FBB00BF6237 /* SignInAnalyticsTests_osx.xctest */, + DAE40BCE20CF3E47002D5674 /* secitemcanarytest */, + 4771D972209A755800BA9772 /* KeychainDataclassOwner.bundle */, ); name = Products; sourceTree = ""; @@ -14901,6 +15897,7 @@ 4C922CB2097F1984004CEEBD /* Security */ = { isa = PBXGroup; children = ( + D44D08B420AB890E0023C439 /* Security.apinotes */, DC1785981D778C5300B50D50 /* cssmapple.h */, 4C28BCD60986EBCB0020C665 /* certextensions.h */, 4C696B3709BFA94F000CBC75 /* SecBase.h */, @@ -14916,8 +15913,15 @@ 4CF0487F0A5F016300268236 /* SecItemPriv.h */, 4C7072840AC9EA4E007CC205 /* SecKey.h */, 4C7072D30AC9ED5A007CC205 /* SecKeyPriv.h */, + 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */, 4CBA0E860BB33C0000E72B55 /* SecPolicy.h */, 4C6416D40BB34F00001C83FD /* SecPolicyPriv.h */, + 5AFCF32D20746D9A0010D4B5 /* SecProtocolObject.h */, + 5AFCF32220746AD80010D4B5 /* SecProtocolOptions.h */, + 5A4E381A207529480047F40F /* SecProtocol.h */, + 5AC6BFA52077CD130051737D /* SecProtocolTypes.h */, + 5AFCF32820746AE90010D4B5 /* SecProtocolMetadata.h */, + AA44E0D920325177001EA371 /* SecProtocolPriv.h */, 4C2F81D40BF121D2003C4F77 /* SecRandom.h */, 107226D10D91DB32003CF14F /* SecTask.h */, DCD068031D8CDF7E007602F1 /* SecTaskPriv.h */, @@ -15035,7 +16039,6 @@ 6C34464D1E2534C200F9522B /* Analytics */ = { isa = PBXGroup; children = ( - 6C34464E1E2534D200F9522B /* AWD */, EBB407AF1EBA433A00A541A5 /* CKKSPowerCollection.h */, EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */, 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */, @@ -15044,25 +16047,6 @@ name = Analytics; sourceTree = ""; }; - 6C34464E1E2534D200F9522B /* AWD */ = { - isa = PBXGroup; - children = ( - 6C869A781F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.h */, - 6C869A771F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.m */, - 6CD8D3B11EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.h */, - 6CD8D3B21EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.m */, - 6C34464F1E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.h */, - 6C3446501E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.m */, - 6C3446511E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.h */, - 6C3446521E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.m */, - 6C3446531E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.h */, - 6C3446541E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.m */, - 6C3446551E2534E800F9522B /* AwdMetadata-0x60-Keychain.bin */, - 6C3446561E2534E800F9522B /* AWDMetricIds_Keychain.h */, - ); - name = AWD; - sourceTree = ""; - }; 6C69517B1F758E1000F68F91 /* supd */ = { isa = PBXGroup; children = ( @@ -15095,6 +16079,8 @@ children = ( 6C7BB0042006B4EF004D1B6B /* SOSAnalytics.h */, 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */, + 6C814A4A2050B4B600CB391B /* LocalKeychainAnalytics.h */, + 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */, ); path = Clients; sourceTree = ""; @@ -15199,6 +16185,15 @@ path = DigicertMalaysia; sourceTree = ""; }; + AA44E0CF2032511C001EA371 /* Protocol */ = { + isa = PBXGroup; + children = ( + AA44E0D02032513F001EA371 /* SecProtocol.c */, + AA44E0D120325140001EA371 /* SecProtocolTypes.m */, + ); + path = Protocol; + sourceTree = ""; + }; ACBAF6DF1E941A800007BA2F /* regressions */ = { isa = PBXGroup; children = ( @@ -15357,53 +16352,11 @@ 0CE760511E1314F700B4381E /* SOSAccountTrustClassic+Identity.h */, 0CE760471E12F2F200B4381E /* SOSAccountTrustClassic+Expansion.m */, 0CE7604F1E1301DC00B4381E /* SOSAccountTrustClassic+Expansion.h */, - 0C4899261E0F399B00C6CF70 /* SOSAccountTrustOctagon.h */, - 0C4899241E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m */, ); name = AccountTrust; path = ..; sourceTree = ""; }; - CD6130CC1DA06F5700E1E42F /* KeychainSyncingOverIDSProxy */ = { - isa = PBXGroup; - children = ( - CD23B4961DA06EB30047EDE9 /* keychainsyncingoveridsproxy.m */, - CD23B4971DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.h */, - CD23B4981DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m */, - CD23B4991DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.h */, - CD23B49A1DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m */, - CD23B4931DA06EB30047EDE9 /* IDSPersistentState.m */, - CD23B4921DA06EB30047EDE9 /* IDSPersistentState.h */, - CD23B4951DA06EB30047EDE9 /* IDSProxy.m */, - CD23B4941DA06EB30047EDE9 /* IDSProxy.h */, - CD6130D21DA06FA800E1E42F /* Supporting Files */, - ); - name = KeychainSyncingOverIDSProxy; - sourceTree = ""; - }; - CD6130D21DA06FA800E1E42F /* Supporting Files */ = { - isa = PBXGroup; - children = ( - CD6130D31DA06FC600E1E42F /* com.apple.security.keychainsyncingoveridsproxy.ios.plist */, - CD6130D41DA06FC600E1E42F /* com.apple.security.keychainsyncingoveridsproxy.osx.plist */, - CD6130D51DA06FC600E1E42F /* en.lproj */, - CD6130D81DA06FC600E1E42F /* KeychainSyncingOverIDSProxy-Info.plist */, - CD6130D91DA06FC600E1E42F /* keychainsyncingoveridsproxy.entitlements.plist */, - CD23B4A81DA06ED10047EDE9 /* com.apple.private.alloy.keychainsync.plist */, - DC24B5841DA432C600330B48 /* KeychainSyncingOverIDSProxy.8 */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - CD6130D51DA06FC600E1E42F /* en.lproj */ = { - isa = PBXGroup; - children = ( - CD6130D61DA06FC600E1E42F /* InfoPlist.strings */, - ); - name = en.lproj; - path = KeychainSyncingOverIDSProxy/en.lproj; - sourceTree = ""; - }; DA30D6771DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */ = { isa = PBXGroup; children = ( @@ -15414,6 +16367,15 @@ path = KeychainSyncAccountUpdater; sourceTree = ""; }; + DAE40BD620CF3F04002D5674 /* secitemcanarytest */ = { + isa = PBXGroup; + children = ( + DAE40BD720CF3F04002D5674 /* secitemcanarytest.entitlements */, + DAE40BD820CF3F04002D5674 /* secitemcanarytest.m */, + ); + path = secitemcanarytest; + sourceTree = ""; + }; DC0BC4E51D8B6AA600070CB0 /* applications */ = { isa = PBXGroup; children = ( @@ -16062,6 +17024,7 @@ DC0BCA481D8B82CD00070CB0 /* regressions */ = { isa = PBXGroup; children = ( + 3DD1FE72201AA38A0086D049 /* SecureTransportTests */, DC0BCA2F1D8B82CD00070CB0 /* test-certs */, DC0BCA301D8B82CD00070CB0 /* cert-1.h */, DC0BCA311D8B82CD00070CB0 /* identity-1.h */, @@ -16248,6 +17211,8 @@ EBF3749B1DC064200065D840 /* SecADWrapper.h */, DC0BCC3C1D8C68CF00070CB0 /* SecAKSWrappers.c */, DC0BCC3D1D8C68CF00070CB0 /* SecAKSWrappers.h */, + DA5B871A2065A8410093F083 /* SecAutorelease.h */, + DA5B871B2065A8430093F083 /* SecAutorelease.m */, DC0BCC3E1D8C68CF00070CB0 /* SecBuffer.c */, DC0BCC3F1D8C68CF00070CB0 /* SecBuffer.h */, DC0BCC401D8C68CF00070CB0 /* SecCoreCrypto.c */, @@ -16331,7 +17296,7 @@ D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */, DCC78E421D8085FC00865A7C /* SecCMS.c */, 79BDD3C00D60DB84000D84D3 /* SecCMS.h */, - DCC78E441D8085FC00865A7C /* SecCTKKey.c */, + DCC78E441D8085FC00865A7C /* SecCTKKey.m */, DCC78E451D8085FC00865A7C /* SecCTKKeyPriv.h */, DCC78E381D8085FC00865A7C /* SecCertificate.c */, 4CEF4CA70C5551FE00062475 /* SecCertificateInternal.h */, @@ -16339,12 +17304,11 @@ DCC78E461D8085FC00865A7C /* SecDH.c */, 7940D4110C3ACF9000FDB5D8 /* SecDH.h */, DCC78E481D8085FC00865A7C /* SecDigest.c */, - DCC78E491D8085FC00865A7C /* SecECKey.c */, + DCC78E491D8085FC00865A7C /* SecECKey.m */, 4CD3BA601106FF4D00BE8B75 /* SecECKey.h */, 78F92F10195128D70023B54B /* SecECKeyPriv.h */, DCC78E4C1D8085FC00865A7C /* SecEMCS.m */, EB69AB091BF4347700913AF1 /* SecEMCSPriv.h */, - DCC78E4F1D8085FC00865A7C /* SecFramework.c */, 4C0B906C0ACCBD240077CD03 /* SecFramework.h */, 4C8E99C20FC601D50072EB4C /* SecFrameworkStrings.h */, DCC78E521D8085FC00865A7C /* SecIdentity.c */, @@ -16359,8 +17323,9 @@ 4CEDF7370F3A6CFB0027C4FE /* SecItemInternal.h */, DCC78E5F1D8085FC00865A7C /* SecItemShim.h */, DCC78E601D8085FC00865A7C /* SecKey.c */, - DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */, + DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */, 4C04A90811924BBC0020550C /* SecKeyInternal.h */, + 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */, DCC78E651D8085FC00865A7C /* SecLogging.c */, DCC78E661D8085FC00865A7C /* SecLogging.h */, 4AF7FFF315AFB73800B9D400 /* SecOTR.h */, @@ -16423,6 +17388,8 @@ DCC78E9C1D8085FC00865A7C /* vmdh.c */, 4C7391770B01745000C4CBFA /* vmdh.h */, 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */, + DCC5860120BF8A98005C7269 /* SecBase.h */, + DCC5860220BF8A98005C7269 /* SecBase.c */, ); name = src; sourceTree = ""; @@ -16663,6 +17630,7 @@ DCAD9B481F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m */, DCBF2F7C1F90084D00ED0CA4 /* CKKSTLKSharingTests.m */, DC08D1CB1E64FCC5006237DA /* CKKSSOSTests.m */, + DC8D238C2064649400E163C8 /* CKKSAPSHandlingTests.m */, DC9C750F1E4BCC5100F1CA0D /* CKKSOperationTests.m */, DC222C891E089BAE00B09171 /* CKKSSQLTests.m */, DC4DB15E1E2590B100CD6769 /* CKKSAESSIVEncryptionTests.m */, @@ -16680,6 +17648,7 @@ DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */, 6C588D791EAA149F00D7E322 /* RateLimiterTests.m */, 4723C9D11F1531970082882F /* CKKSLoggerTests.m */, + DCF158C52064895C00B87B6D /* CKKSAPSReceiverTests.h */, DCE7F2081F21726500DDB0F7 /* CKKSAPSReceiverTests.m */, DC9C95951F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m */, ); @@ -16770,6 +17739,8 @@ DC59E9AA1D91C9BE001BDDF5 /* Security.framework (Shared) */ = { isa = PBXGroup; children = ( + DCC78E4F1D8085FC00865A7C /* SecFramework.c */, + AA44E0CF2032511C001EA371 /* Protocol */, 4723C9B51F152E8E0082882F /* Analytics */, DCD067621D8CDE9B007602F1 /* codesigning */, DCD06AA81D8E0D3D007602F1 /* security_utilities */, @@ -17162,7 +18133,6 @@ E7D847C61C6BE9710025BB44 /* KeychainCircle.framework */, DCE4E9121D7F3D5400AFB96E /* Keychain Circle Notification */, DCE4E8DE1D7F39DB00AFB96E /* Cloud Keychain Utility */, - CD6130CC1DA06F5700E1E42F /* KeychainSyncingOverIDSProxy */, E7A5F4D11C0CFF4E00F3BEBB /* KVSKeychainSyncingProxy */, 4381690E1B4EDCBD00C54D58 /* SOSCCAuthPlugin */, ); @@ -17386,6 +18356,7 @@ DC6D2C941DD3B20400BE372D /* keychain */ = { isa = PBXGroup; children = ( + DCAE1DCF2073FCA400B4F687 /* categories */, 0C7CEA391FE9CE3900125C79 /* behavior */, 0C8BBEF61FCB402900580909 /* otctl */, 0C8BBE831FC9DA1700580909 /* Octagon Trust */, @@ -17394,6 +18365,9 @@ 6C34464D1E2534C200F9522B /* Analytics */, BEF88C451EAFFFED00357577 /* TrustedPeers */, DC9B7AD31DCBF336004E9385 /* CloudKit Syncing */, + 470D96651FCDE45C0065FE90 /* CoreDataKeychain */, + 47C2F1852059CB680062DE30 /* KeychainResources */, + 4771D974209A755800BA9772 /* KeychainDataclassOwner */, ); path = keychain; sourceTree = ""; @@ -17557,6 +18531,15 @@ name = Helpers; sourceTree = ""; }; + DCAE1DCF2073FCA400B4F687 /* categories */ = { + isa = PBXGroup; + children = ( + DCAE1DD52073FCDE00B4F687 /* NSError+UsefulConstructors.h */, + DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */, + ); + path = categories; + sourceTree = ""; + }; DCB340651D8A24CC0054D16E /* authorization */ = { isa = PBXGroup; children = ( @@ -18025,6 +19008,7 @@ DCB344421D8A35270054D16E /* kc-key-helpers.h */, DCB344431D8A35270054D16E /* kc-identity-helpers.h */, DCB344441D8A35270054D16E /* kc-keychain-file-helpers.h */, + DCD45358209A5C2D0086CBFC /* kc-keychain-file-helpers.c */, DCB344451D8A35270054D16E /* kc-01-keychain-creation.c */, DCB344461D8A35270054D16E /* kc-02-unlock-noui.c */, DCB344471D8A35270054D16E /* kc-03-status.c */, @@ -18133,11 +19117,8 @@ DCC78C651D8085D800865A7C /* secd-71-engine-save-sample1.h */, DCC78C661D8085D800865A7C /* secd-74-engine-beer-servers.m */, DCC78C671D8085D800865A7C /* secd-75-engine-views.m */, - DCC78C681D8085D800865A7C /* secd-76-idstransport.m */, - DCC78C691D8085D800865A7C /* secd_77_ids_messaging.m */, 7281E08B1DFD0A380021E1B7 /* secd-80-views-alwayson.m */, DCC78C6A1D8085D800865A7C /* secd-80-views-basic.m */, - DCC78C6B1D8085D800865A7C /* secd-82-secproperties-basic.m */, DCC78C6C1D8085D800865A7C /* secd-81-item-acl-stress.m */, DCC78C6D1D8085D800865A7C /* secd-81-item-acl.m */, DCC78C6E1D8085D800865A7C /* secd-82-persistent-ref.m */, @@ -18157,7 +19138,6 @@ 7281E08E1DFD0D810021E1B7 /* secd-210-keyinterest.m */, 522B28081E64B48E002B5638 /* secd-230-keybagtable.m */, DCFAEDD11D9998DD005187E4 /* secd-668-ghosts.m */, - 0C5F4FD71F952FEA00AF1616 /* secd-700-sftm.m */, DCC78C791D8085D800865A7C /* SOSAccountTesting.h */, DCC78C7A1D8085D800865A7C /* SecdTestKeychainUtilities.c */, DCC78C7B1D8085D800865A7C /* SecdTestKeychainUtilities.h */, @@ -18212,6 +19192,8 @@ 470ACEF21F58C3A600D1D5BD /* SecDbKeychainItemV7.h */, 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */, 47D1837D1FB1183D00CFCD89 /* SecDbKeychainV7-protobufs */, + 47FF17241FD60ACA00875565 /* SFKeychainServer.h */, + 47FF17251FD60ACA00875565 /* SFKeychainServer.m */, 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */, 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */, ); @@ -18389,8 +19371,6 @@ DCC78D6C1D8085F200865A7C /* SOSPeerInfoInternal.h */, DCC78D6D1D8085F200865A7C /* SOSPeerInfoRingState.m */, DCC78D6E1D8085F200865A7C /* SOSPeerInfoRingState.h */, - DCC78D6F1D8085F200865A7C /* SOSPeerInfoSecurityProperties.m */, - DCC78D701D8085F200865A7C /* SOSPeerInfoSecurityProperties.h */, ); name = PeerInfo; sourceTree = ""; @@ -18414,8 +19394,6 @@ DCC78D7D1D8085F200865A7C /* SOSTransportKeyParameter.h */, DCC78D801D8085F200865A7C /* SOSTransportMessage.m */, DCC78D811D8085F200865A7C /* SOSTransportMessage.h */, - DCC78D821D8085F200865A7C /* SOSTransportMessageIDS.m */, - DCC78D831D8085F200865A7C /* SOSTransportMessageIDS.h */, DCC78D841D8085F200865A7C /* SOSTransportMessageKVS.m */, DCC78D851D8085F200865A7C /* SOSTransportMessageKVS.h */, 0CAC5DBE1EB3DA4C00AD884B /* SOSPeerRateLimiter.m */, @@ -18448,6 +19426,8 @@ EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */, DAB27ADA1FA29EB700DEBBDE /* SOSControlServer.h */, DAB27AE01FA29EB800DEBBDE /* SOSControlServer.m */, + 48FE669520E6E69C00FAEF17 /* SOSAuthKitHelpers.h */, + 48FE668F20E6E69B00FAEF17 /* SOSAuthKitHelpers.m */, ); path = SecureObjectSync; sourceTree = ""; @@ -18584,6 +19564,7 @@ DCC78DBE1D8085FC00865A7C /* si-22-sectrust-iap.c */, DCC78DBF1D8085FC00865A7C /* si-22-sectrust-iap.h */, DCC78DC01D8085FC00865A7C /* si-23-sectrust-ocsp.c */, + D46513072097954B005D93FE /* si-23-sectrust-ocsp.h */, DCC78DC11D8085FC00865A7C /* si-24-sectrust-digicert-malaysia.c */, DCC78DC21D8085FC00865A7C /* si-24-sectrust-diginotar.c */, DCC78DC31D8085FC00865A7C /* si-24-sectrust-itms.c */, @@ -18603,6 +19584,10 @@ D4CFAA7D1E660BB3004746AA /* si-32-sectrust-pinning-required.m */, D4C8A1511E66709800CD6DF1 /* si-32-sectrust-pinning-required.h */, DCC78DCD1D8085FC00865A7C /* si-33-keychain-backup.c */, + D4B6D57B2069D8450099FBEF /* si-34-cms-timestamp.m */, + D4B6D5822069D85B0099FBEF /* si-34-cms-timestamp.h */, + D48BD193206C47530075DDC9 /* si-35-cms-expiration-time.m */, + D48BD195206C476B0075DDC9 /* si-35-cms-expiration-time.h */, DCC78DCE1D8085FC00865A7C /* si-40-seckey-custom.c */, DCC78DCF1D8085FC00865A7C /* si-40-seckey.c */, DCC78DD01D8085FC00865A7C /* si-41-sececkey.c */, @@ -18614,6 +19599,7 @@ DCC78DD61D8085FC00865A7C /* si-44-seckey-ies.m */, 5E77936E1E5EFEB20074A2D1 /* si-44-seckey-aks.m */, 09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */, + 09A3B9DF1F8271A200C5C324 /* si-44-seckey-proxy.m */, DCC78DD71D8085FC00865A7C /* si-50-secrandom.c */, DCC78DD81D8085FC00865A7C /* si-60-cms.c */, DCC78DD91D8085FC00865A7C /* si-61-pkcs12.c */, @@ -18651,12 +19637,15 @@ DCC78E0A1D8085FC00865A7C /* si-87-sectrust-name-constraints.h */, BEB9E9E51FFF193D00676593 /* si-88-sectrust-valid.m */, DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */, - DCC78E0C1D8085FC00865A7C /* si-89-cms-hash-agility.h */, DCC78E0D1D8085FC00865A7C /* si-90-emcs.m */, DCC78E0E1D8085FC00865A7C /* si-95-cms-basic.c */, DCC78E0F1D8085FC00865A7C /* si-95-cms-basic.h */, DCC78E101D8085FC00865A7C /* si-97-sectrust-path-scoring.m */, DCC78E111D8085FC00865A7C /* si-97-sectrust-path-scoring.h */, + DCD45353209A5B260086CBFC /* si-cms-signing-identity-p12.h */, + DCD45354209A5B260086CBFC /* si-cms-signing-identity-p12.c */, + DCE2341520A3D4B8009766A3 /* si-cms-hash-agility-data.h */, + DCE2341620A3D4B8009766A3 /* si-cms-hash-agility-data.c */, ); name = secitem; path = Regressions/secitem; @@ -18952,6 +19941,8 @@ DCD067FB1D8CDF7E007602F1 /* quarantine++.cpp */, DCD067FC1D8CDF7E007602F1 /* dirscanner.h */, DCD067FD1D8CDF7E007602F1 /* dirscanner.cpp */, + A6B1BA78207BD9D400F1E099 /* notarization.cpp */, + A6B1BA79207BD9D400F1E099 /* notarization.h */, ); name = "Local Utilities"; sourceTree = ""; @@ -19425,8 +20416,6 @@ isa = PBXGroup; children = ( D4BEECE61E93093A00F76D1A /* trustd.c */, - D43DBED51E99D17100C04AEA /* asynchttp.c */, - D43DBED61E99D17100C04AEA /* asynchttp.h */, D43DBED71E99D17100C04AEA /* nameconstraints.c */, D43DBED81E99D17100C04AEA /* nameconstraints.h */, D43DBED91E99D17100C04AEA /* OTATrustUtilities.m */, @@ -19437,7 +20426,7 @@ D43DBEDE1E99D17200C04AEA /* policytree.h */, D43DBEDF1E99D17200C04AEA /* SecCAIssuerCache.c */, D43DBEE01E99D17200C04AEA /* SecCAIssuerCache.h */, - D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.c */, + D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.m */, D43DBEE21E99D17200C04AEA /* SecCAIssuerRequest.h */, D43DBEE31E99D17200C04AEA /* SecCertificateServer.c */, D43DBEE41E99D17200C04AEA /* SecCertificateServer.h */, @@ -19465,6 +20454,8 @@ D43DBEF81E99D17300C04AEA /* SecTrustServer.h */, D43DBEF91E99D17300C04AEA /* SecTrustStoreServer.c */, D43DBEFA1E99D17300C04AEA /* SecTrustStoreServer.h */, + D4961BBD2079423300F16DA7 /* TrustURLSessionDelegate.m */, + D4961BC52079426000F16DA7 /* TrustURLSessionDelegate.h */, D4ADA30E1E2B1E650031CEA3 /* trustd-Info.plist */, DCE4E85E1D7A585300AFB96E /* macOS */, DCE4E85D1D7A584D00AFB96E /* iOS */, @@ -20414,15 +21405,24 @@ E7FCBE401314471B000DE34E /* Frameworks */ = { isa = PBXGroup; children = ( + 0C9FB40120D8729A00864612 /* CoreCDP.framework */, + DC63D70920B3933000D088AD /* libOpenScriptingUtil.tbd */, + DC63D70220B3930700D088AD /* libxar.tbd */, + D4911167209558900066A1E4 /* CoreData.framework */, + 4771D9A1209B7C3900BA9772 /* Accounts.framework */, + 4771D99F209B7C2600BA9772 /* Security.framework */, + 4C47FA8D20A51DC700384CB6 /* AppleFSCompression.framework */, 5A94C6D4203CC2590066E391 /* AuthKit.framework */, 5A94C6D1203CC1C60066E391 /* AOSAccountsLite.framework */, + 091B396D2063B64A00ECAB6F /* RemoteServiceDiscovery.framework */, 477A1F4C20320E4900ACD81D /* Accounts.framework */, EB49B2DE202DF286003F34A0 /* CoreFollowUpUI.framework */, EB49B2DC202DF251003F34A0 /* libbsm.tbd */, EB49B2CE202DF111003F34A0 /* CoreFollowUp.framework */, D4119E72202BDF2B0048587B /* libz.tbd */, - 472339681FD7156700CB6A72 /* CoreCDP.framework */, 472339611FD7155C00CB6A72 /* libprequelite.dylib */, + 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */, + 3DD1FFA8201FC5C20086D049 /* libcoretls.tbd */, 47D1838B1FB3827700CFCD89 /* OCMock.framework */, 4727FBE81F9921D00003AE36 /* libACM.a */, 4727FBE61F9921890003AE36 /* ApplePushService.framework */, @@ -20491,7 +21491,6 @@ DCE4E8141D7A4E6F00AFB96E /* CFNetwork.framework */, 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */, DCE4E8FE1D7F3A2300AFB96E /* Cocoa.framework */, - DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */, 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */, DC1789241D7799CD00B50D50 /* CoreFoundation.framework */, E7FCBE451314471B000DE34E /* CoreGraphics.framework */, @@ -20540,6 +21539,32 @@ name = Frameworks; sourceTree = ""; }; + EB056E3F1FE5E390000A771E /* DeviceSimulator */ = { + isa = PBXGroup; + children = ( + EBCE165C1FE6F4CE002E7CCC /* DeviceSimulator-Entitlements.plist */, + EB056E411FE5E390000A771E /* DeviceSimulator.h */, + EB056E421FE5E390000A771E /* DeviceSimulator.m */, + EB056E441FE5E390000A771E /* DeviceSimulatorMain.m */, + EB056E401FE5E390000A771E /* DeviceSimulatorProtocol.h */, + EB056E461FE5E391000A771E /* Info.plist */, + ); + path = DeviceSimulator; + sourceTree = ""; + }; + EB05C4F21FE5E48B00D68712 /* MultiDeviceSimulatorTests */ = { + isa = PBXGroup; + children = ( + 4885DCAB207FF0780071FB7B /* ClientInfoByNotification.m */, + EB05C4F31FE5E48B00D68712 /* MultiDeviceSimulatorTests.m */, + EBCE165E1FE7313C002E7CCC /* MultiDeviceNetworking.h */, + EBCE165F1FE7313C002E7CCC /* MultiDeviceNetworking.m */, + EBCE16611FE73327002E7CCC /* MultiDeviceNetworkingProtocol.h */, + EB05C4F51FE5E48B00D68712 /* Info.plist */, + ); + path = MultiDeviceSimulatorTests; + sourceTree = ""; + }; EB0BC9641C3C792E00785842 /* secedumodetest */ = { isa = PBXGroup; children = ( @@ -20645,6 +21670,15 @@ name = Modules; sourceTree = ""; }; + EB81D0CB1FE5838B00FD7F16 /* MultiDeviceSimulator */ = { + isa = PBXGroup; + children = ( + EB05C4F21FE5E48B00D68712 /* MultiDeviceSimulatorTests */, + EB056E3F1FE5E390000A771E /* DeviceSimulator */, + ); + path = MultiDeviceSimulator; + sourceTree = ""; + }; EB9C1D7C1BDFD0E100F89272 /* secbackupntest */ = { isa = PBXGroup; children = ( @@ -20657,10 +21691,12 @@ isa = PBXGroup; children = ( EB9C1DAD1BDFD49400F89272 /* Security.plist */, + EBE202752092913500B48020 /* SecurityInduceLowDisk.plist */, EB3A8DD71BEEC4D6001A89AA /* Security_edumode.plist */, EB2D549F1F02A25700E46890 /* SecAtomicFile */, EB9C1D7C1BDFD0E100F89272 /* secbackupntest */, EB425CCC1C6584A9000ECE53 /* secbackuptest */, + DAE40BD620CF3F04002D5674 /* secitemcanarytest */, EB0BC9641C3C792E00785842 /* secedumodetest */, EBCF73CC1CE45F3F00BED7CA /* secitemfunctionality */, BED208E31EDF95BB00753952 /* manifeststresstest */, @@ -20682,6 +21718,14 @@ name = secitemnotifications; sourceTree = ""; }; + EBC73F44209A0BB200AE3350 /* xcscripts */ = { + isa = PBXGroup; + children = ( + EBC73F4A209A0BEF00AE3350 /* install-test-framework.sh */, + ); + name = xcscripts; + sourceTree = ""; + }; EBCF73CC1CE45F3F00BED7CA /* secitemfunctionality */ = { isa = PBXGroup; children = ( @@ -20746,6 +21790,75 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4718AE9D205B39C40068EC3F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4718AE9E205B39C40068EC3F /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */, + 4718AE9F205B39C40068EC3F /* CKKSCondition.h in Headers */, + 4718AEA0205B39C40068EC3F /* CKKSScanLocalItemsOperation.h in Headers */, + 4718AEA1205B39C40068EC3F /* CKKSNotifier.h in Headers */, + 4718AEA2205B39C40068EC3F /* CKKSGroupOperation.h in Headers */, + 4718AEA3205B39C40068EC3F /* CKKSRateLimiter.h in Headers */, + 4718AEA4205B39C40068EC3F /* SecDbKeychainSerializedItemV7.h in Headers */, + 4718AEA5205B39C40068EC3F /* OTCloudStore.h in Headers */, + 4718AEA6205B39C40068EC3F /* CKKSResultOperation.h in Headers */, + 4718AEA7205B39C40068EC3F /* CKKSUpdateDeviceStateOperation.h in Headers */, + 4718AEA8205B39C40068EC3F /* CKKSViewManager.h in Headers */, + 4718AEA9205B39C40068EC3F /* CKKSRecordHolder.h in Headers */, + 4718AEAA205B39C40068EC3F /* CKKSOutgoingQueueOperation.h in Headers */, + 4718AEAB205B39C40068EC3F /* CKKSSynchronizeOperation.h in Headers */, + 4718AEAC205B39C40068EC3F /* OTControl.h in Headers */, + 4718AEAD205B39C40068EC3F /* SOSChangeTracker.h in Headers */, + 4718AEAE205B39C40068EC3F /* CKKSAnalytics.h in Headers */, + 4718AEAF205B39C40068EC3F /* SOSEngine.h in Headers */, + 4718AEB0205B39C40068EC3F /* SecDbKeychainItem.h in Headers */, + 4718AEB1205B39C40068EC3F /* CKKSProcessReceivedKeysOperation.h in Headers */, + 4718AEB2205B39C40068EC3F /* SecDbQuery.h in Headers */, + 4718AEB3205B39C40068EC3F /* SecCDKeychain.h in Headers */, + 4718AEB4205B39C40068EC3F /* CKKSMirrorEntry.h in Headers */, + 4718AEB5205B39C40068EC3F /* CloudKitCategories.h in Headers */, + 4718AEB6205B39C40068EC3F /* CKKSDeviceStateEntry.h in Headers */, + 4718AEB7205B39C40068EC3F /* OTAuthenticatedCiphertext+SF.h in Headers */, + 4718AEB8205B39C40068EC3F /* CKKSCKAccountStateTracker.h in Headers */, + 4718AEB9205B39C40068EC3F /* CKKSZoneStateEntry.h in Headers */, + 4718AEBA205B39C40068EC3F /* CKKSTLKShare.h in Headers */, + 4718AEBB205B39C40068EC3F /* SecItemDataSource.h in Headers */, + 4718AEBC205B39C40068EC3F /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */, + 4718AEBD205B39C40068EC3F /* SecDbKeychainSerializedMetadata.h in Headers */, + 4718AEBE205B39C40068EC3F /* CKKSZoneChangeFetcher.h in Headers */, + 4718AEBF205B39C40068EC3F /* CKKSReencryptOutgoingItemsOperation.h in Headers */, + 4718AEC0205B39C40068EC3F /* SFPublicKey+SPKI.h in Headers */, + 4718AEC1205B39C40068EC3F /* CKKSIncomingQueueEntry.h in Headers */, + 4718AEC2205B39C40068EC3F /* SecItemDb.h in Headers */, + 4718AEC3205B39C40068EC3F /* CKKSFixups.h in Headers */, + 4718AEC4205B39C40068EC3F /* CKKSControl.h in Headers */, + 4718AEC5205B39C40068EC3F /* SecItemSchema.h in Headers */, + 4718AEC6205B39C40068EC3F /* CKKSLocalSynchronizeOperation.h in Headers */, + 4718AEC7205B39C40068EC3F /* SecKeybagSupport.h in Headers */, + 4718AEC8205B39C40068EC3F /* CKKSNewTLKOperation.h in Headers */, + 4718AEC9205B39C40068EC3F /* iCloudTrace.h in Headers */, + 4718AECA205B39C40068EC3F /* CKKSControlProtocol.h in Headers */, + 4718AECB205B39C40068EC3F /* SFKeychainServer.h in Headers */, + 4718AECC205B39C40068EC3F /* CKKSOutgoingQueueEntry.h in Headers */, + 4718AECD205B39C40068EC3F /* CKKSHealKeyHierarchyOperation.h in Headers */, + 4718AECE205B39C40068EC3F /* CKKSNearFutureScheduler.h in Headers */, + 4718AECF205B39C40068EC3F /* OTManager.h in Headers */, + 4718AED0205B39C40068EC3F /* CKKSHealTLKSharesOperation.h in Headers */, + 4718AED1205B39C40068EC3F /* CKKSUpdateCurrentItemPointerOperation.h in Headers */, + 4718AED2205B39C40068EC3F /* OTControlProtocol.h in Headers */, + 4718AED3205B39C40068EC3F /* CKKSAPSReceiver.h in Headers */, + 4718AED4205B39C40068EC3F /* NSOperationCategories.h in Headers */, + 4718AED5205B39C40068EC3F /* CKKSKey.h in Headers */, + 4718AED6205B39C40068EC3F /* CKKSCurrentItemPointer.h in Headers */, + 4718AED7205B39C40068EC3F /* CKKSControlServer.h in Headers */, + 4718AED8205B39C40068EC3F /* CKKSSIV.h in Headers */, + 4718AED9205B39C40068EC3F /* SFKeychainControlManager.h in Headers */, + 4718AEDA205B39C40068EC3F /* SecDbKeychainSerializedSecretData.h in Headers */, + 4718AEDB205B39C40068EC3F /* CKKSItem.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4C32C0AA0A4975F6002891BD /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -20760,16 +21873,19 @@ 4C999BA60AB5F0BB0010451D /* NtlmGenerator.h in Headers */, 4C999BA80AB5F0BB0010451D /* ntlmBlobPriv.h in Headers */, EB5E3BCC2003C67A00F1631B /* SecSignpost.h in Headers */, + 09A3B9D81F8267BB00C5C324 /* SecKeyProxy.h in Headers */, 4C7608B30AC34A8100980096 /* SecCertificatePriv.h in Headers */, EB10A3E520356E2000E84270 /* OTConstants.h in Headers */, 4CEF4CA80C5551FE00062475 /* SecCertificateInternal.h in Headers */, BE061FE11899ECEE00C739F6 /* SecSharedCredential.h in Headers */, 443381EE18A3D83A00215606 /* SecAccessControlPriv.h in Headers */, + 5A4E381B207529670047F40F /* SecProtocol.h in Headers */, 6CC952491FB4CB2D0051A823 /* SFAnalytics+Internal.h in Headers */, DC3C73541D837B1900F6A832 /* SOSCloudCircle.h in Headers */, 524492941AFD6D480043695A /* der_plist.h in Headers */, DC3C73531D837AF800F6A832 /* SOSPeerInfo.h in Headers */, 4C12828D0BB4957D00985BB0 /* SecTrustSettingsPriv.h in Headers */, + DCD45355209A5B260086CBFC /* si-cms-signing-identity-p12.h in Headers */, CDDE9BD11729ABFA0013B0E8 /* SecPasswordGenerate.h in Headers */, 4C7072860AC9EA4F007CC205 /* SecKey.h in Headers */, 476541651F339F6300413F65 /* SecdWatchdog.h in Headers */, @@ -20792,6 +21908,7 @@ 4CD3BA621106FF4D00BE8B75 /* SecECKey.h in Headers */, 4C6416F10BB357D5001C83FD /* SecInternal.h in Headers */, 443381ED18A3D83100215606 /* SecAccessControl.h in Headers */, + 5AFCF32E20746DA70010D4B5 /* SecProtocolObject.h in Headers */, 4723C9C61F152EC00082882F /* SFSQLite.h in Headers */, 4C1B442D0BB9CAF900461B82 /* SecTrustStore.h in Headers */, DC3C7AB81D838C6F00F6A832 /* oidsalg.h in Headers */, @@ -20799,21 +21916,25 @@ 4C2F81D50BF121D2003C4F77 /* SecRandom.h in Headers */, ACBAF6EE1E941AE00007BA2F /* transform_regressions.h in Headers */, 7940D4130C3ACF9000FDB5D8 /* SecDH.h in Headers */, + DCC5860320BF8A98005C7269 /* SecBase.h in Headers */, 790850F70CA88AE10083CC4D /* securityd_client.h in Headers */, 795CA9CE0D38435E00BAE6A2 /* p12pbegen.h in Headers */, 79EF5B730D3D6AFE009F5270 /* p12import.h in Headers */, 4723C9C21F152EB50082882F /* SFObjCType.h in Headers */, 4CE7EA791AEAF39C0067F5BD /* SecItemBackup.h in Headers */, 222F23A01DAC1603007ACB90 /* SecTaskPriv.h in Headers */, + 5AFCF32B20746BC80010D4B5 /* SecProtocolMetadata.h in Headers */, DC3C7AB51D838C1300F6A832 /* SecAsn1Templates.h in Headers */, 6CE365511FA100FE0012F6AB /* SFAnalyticsSampler.h in Headers */, 79EF5B6E0D3D6A31009F5270 /* SecImportExport.h in Headers */, 4723C9CA1F152ECE0082882F /* SFSQLiteStatement.h in Headers */, + 5AFCF32920746BC20010D4B5 /* SecProtocolOptions.h in Headers */, 4CCE0ADA0D41797400DDBB21 /* SecIdentityPriv.h in Headers */, 4CCE0ADE0D4179E500DDBB21 /* SecBasePriv.h in Headers */, DCD7EE991F4F4E03007D9804 /* ocspTemplates.h in Headers */, 4C87F3A80D611C26000E7104 /* SecTrustPriv.h in Headers */, 79BDD3C20D60DB84000D84D3 /* SecCMS.h in Headers */, + 5AC6BFAB2077CD310051737D /* SecProtocolTypes.h in Headers */, DC2C5F4B1F0D935200FEBDA7 /* CKKSControlProtocol.h in Headers */, 107226D30D91DB32003CF14F /* SecTask.h in Headers */, 4C7CE5700DC7DC6600AE53FC /* SecEntitlements.h in Headers */, @@ -20825,6 +21946,7 @@ DC3C7AB21D838B6D00F6A832 /* SecureTransport.h in Headers */, 6CBF65391FA147E500A68667 /* SFAnalyticsActivityTracker.h in Headers */, 4AF7FFFE15AFB73800B9D400 /* SecOTRDHKey.h in Headers */, + DCFE9C8920EC1F3B00EB6BAC /* SOSControlHelper.h in Headers */, 4AF7FFFF15AFB73800B9D400 /* SecOTRErrors.h in Headers */, 6C73F48F2006B910003D5D63 /* SOSAnalytics.h in Headers */, DCD7EE9A1F4F5156007D9804 /* oidsocsp.h in Headers */, @@ -20832,6 +21954,7 @@ 4AF7000115AFB73800B9D400 /* SecOTRMath.h in Headers */, 4AF7000315AFB73800B9D400 /* SecOTRPacketData.h in Headers */, DC3C7AB31D838BC300F6A832 /* CipherSuite.h in Headers */, + 6C814A4C2050B4B600CB391B /* LocalKeychainAnalytics.h in Headers */, 4AF7000415AFB73800B9D400 /* SecOTRPackets.h in Headers */, 6C8CE6C11FA248DA0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */, DC3C7ABA1D838C9F00F6A832 /* sslTypes.h in Headers */, @@ -20854,9 +21977,11 @@ 724340BA1ED3FEC800F8F566 /* SecSMIME.h in Headers */, 22A23B3E1E3AAC9800C41830 /* SecRequirement.h in Headers */, DC9C95BE1F79DC5F000D19E5 /* CKKSControl.h in Headers */, - 0CBFEACC200FCD33009A60E9 /* SFTransactionMetric.h in Headers */, + 0CBFEACC200FCD33009A60E9 /* SFSignInAnalytics.h in Headers */, DC3C7AB61D838C2D00F6A832 /* SecAsn1Types.h in Headers */, + D43D8B2D20AB8A54005BEEC4 /* Security.apinotes in Headers */, DC3C73551D837B2C00F6A832 /* SOSPeerInfoPriv.h in Headers */, + AA44E0DE2032519E001EA371 /* SecProtocolPriv.h in Headers */, D46246A31F9AE59E00D63882 /* oids.h in Headers */, DCD7EEA41F4F58D7007D9804 /* SecLogging.h in Headers */, 47A05B161FDB5D9E00D0816E /* SFKeychainControl.h in Headers */, @@ -21313,6 +22438,7 @@ EB7AE6F91E86DAD200B80B15 /* SecPLWrappers.h in Headers */, DC0BCD871D8C6A1E00070CB0 /* SecIOFormat.h in Headers */, DC0BCD8A1D8C6A1E00070CB0 /* array_size.h in Headers */, + DA5B871C2065A8440093F083 /* SecAutorelease.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -21359,6 +22485,7 @@ DC17877C1D77919500B50D50 /* SecBasePriv.h in Headers */, 0C8BBF231FCB4F1800580909 /* OTControlProtocol.h in Headers */, DC1787741D77915500B50D50 /* SecBreadcrumb.h in Headers */, + 6CB420AB2051FDE000FF2D44 /* LocalKeychainAnalytics.h in Headers */, DC1787761D77916600B50D50 /* SecCFAllocator.h in Headers */, DC1787111D778FA900B50D50 /* SecCMS.h in Headers */, DC17859F1D778C8D00B50D50 /* SecCertificate.h in Headers */, @@ -21376,13 +22503,14 @@ DC1787191D778FAA00B50D50 /* SecCmsEnvelopedData.h in Headers */, DC17871A1D778FAA00B50D50 /* SecCmsMessage.h in Headers */, DC17871B1D778FAA00B50D50 /* SecCmsRecipientInfo.h in Headers */, + DCFE9C8F20EC1F3C00EB6BAC /* SOSControlHelper.h in Headers */, DC17871C1D778FAA00B50D50 /* SecCmsSignedData.h in Headers */, DC17871D1D778FAA00B50D50 /* SecCmsSignerInfo.h in Headers */, DC1785891D778B8000B50D50 /* SecCode.h in Headers */, DC1787511D7790A500B50D50 /* SecCodePriv.h in Headers */, DC1787521D7790A500B50D50 /* SecCodeSigner.h in Headers */, DC1785301D778A0100B50D50 /* SecCustomTransform.h in Headers */, - 0CBFEACD200FCD33009A60E9 /* SFTransactionMetric.h in Headers */, + 0CBFEACD200FCD33009A60E9 /* SFSignInAnalytics.h in Headers */, DC1787771D77916A00B50D50 /* SecDH.h in Headers */, DC1785311D778A0100B50D50 /* SecDecodeTransform.h in Headers */, 6CE365561FA101740012F6AB /* SFAnalyticsSQLiteStore.h in Headers */, @@ -21414,6 +22542,7 @@ DC1787261D778FDE00B50D50 /* SecManifest.h in Headers */, DC1786F91D778F2500B50D50 /* SecNullTransform.h in Headers */, DC17873D1D77903700B50D50 /* SecPassword.h in Headers */, + 5AFCF32F20746DA70010D4B5 /* SecProtocolObject.h in Headers */, DC1787791D77917700B50D50 /* SecPasswordGenerate.h in Headers */, DC1785941D778BF400B50D50 /* SecPolicy.h in Headers */, DC17877D1D77919B00B50D50 /* SecPolicyPriv.h in Headers */, @@ -21425,6 +22554,7 @@ DC1785351D778A0100B50D50 /* SecReadTransform.h in Headers */, DC17873F1D77903700B50D50 /* SecRecoveryPassword.h in Headers */, 6CE3654C1FA100D10012F6AB /* SFAnalytics.h in Headers */, + 09A3B9D91F8267BB00C5C324 /* SecKeyProxy.h in Headers */, DC17858B1D778B8000B50D50 /* SecRequirement.h in Headers */, DC1787551D7790A500B50D50 /* SecRequirementPriv.h in Headers */, DC17871E1D778FAA00B50D50 /* SecSMIME.h in Headers */, @@ -21432,6 +22562,7 @@ DC1785361D778A0100B50D50 /* SecSignVerifyTransform.h in Headers */, DC17858C1D778B8000B50D50 /* SecStaticCode.h in Headers */, DC1787561D7790A500B50D50 /* SecStaticCodePriv.h in Headers */, + 5A4E381C207529680047F40F /* SecProtocol.h in Headers */, DC17859E1D778C8800B50D50 /* SecTask.h in Headers */, DC1785371D778A0100B50D50 /* SecTransform.h in Headers */, DC1786FA1D778F2500B50D50 /* SecTransformInternal.h in Headers */, @@ -21457,6 +22588,7 @@ DC17876B1D77911D00B50D50 /* certExtensionTemplates.h in Headers */, DC1785971D778C0800B50D50 /* certextensions.h in Headers */, DC17875C1D7790CE00B50D50 /* checkpw.h in Headers */, + AA44E0DF2032519F001EA371 /* SecProtocolPriv.h in Headers */, DC17876C1D77911D00B50D50 /* csrTemplates.h in Headers */, DC17856C1D778B4A00B50D50 /* cssm.h in Headers */, DC17856D1D778B4A00B50D50 /* cssmaci.h in Headers */, @@ -21464,11 +22596,14 @@ DC17856E1D778B4A00B50D50 /* cssmapi.h in Headers */, DC1785991D778C5300B50D50 /* cssmapple.h in Headers */, DC1787431D77906C00B50D50 /* cssmapplePriv.h in Headers */, + 5AFCF32C20746BC90010D4B5 /* SecProtocolMetadata.h in Headers */, DC17856F1D778B4A00B50D50 /* cssmcli.h in Headers */, DC1785701D778B4A00B50D50 /* cssmconfig.h in Headers */, DC1785711D778B4A00B50D50 /* cssmcspi.h in Headers */, 6C73F4902006B911003D5D63 /* SOSAnalytics.h in Headers */, DC1785721D778B4A00B50D50 /* cssmdli.h in Headers */, + 5AC6BFAC2077CD310051737D /* SecProtocolTypes.h in Headers */, + 47A91562201A43BA00FF8F46 /* SecSharedCredential.h in Headers */, DC337B1F1EA04E2100B3A1F0 /* SecBase64.h in Headers */, DC1785731D778B4A00B50D50 /* cssmerr.h in Headers */, DC1785741D778B4A00B50D50 /* cssmkrapi.h in Headers */, @@ -21476,6 +22611,7 @@ DC1785761D778B4A00B50D50 /* cssmspi.h in Headers */, DC1785771D778B4A00B50D50 /* cssmtpi.h in Headers */, DC1785781D778B4A00B50D50 /* cssmtype.h in Headers */, + 5AFCF32A20746BC30010D4B5 /* SecProtocolOptions.h in Headers */, DC17877B1D77918C00B50D50 /* der_plist.h in Headers */, DC1785791D778B4A00B50D50 /* eisl.h in Headers */, DC17857A1D778B4A00B50D50 /* emmspi.h in Headers */, @@ -21504,6 +22640,7 @@ 4723C9CB1F152ECF0082882F /* SFSQLiteStatement.h in Headers */, 6CE365501FA100F20012F6AB /* SFAnalyticsDefines.h in Headers */, 6CE365521FA100FF0012F6AB /* SFAnalyticsSampler.h in Headers */, + D43D8B2C20AB8A48005BEEC4 /* Security.apinotes in Headers */, 4723C9C31F152EB60082882F /* SFObjCType.h in Headers */, DCB3323C1F46833E00178C30 /* SecLogging.h in Headers */, DC9C95BD1F79DC5A000D19E5 /* CKKSControl.h in Headers */, @@ -21539,6 +22676,7 @@ DC222C681E034D1F00B09171 /* SecDbQuery.h in Headers */, DCEA5D561E2826DB0089CF55 /* CKKSSIV.h in Headers */, DC222C691E034D1F00B09171 /* CKKSMirrorEntry.h in Headers */, + 470D96721FCDE55B0065FE90 /* SecCDKeychain.h in Headers */, DC222C6A1E034D1F00B09171 /* CKKSZoneStateEntry.h in Headers */, DC94BCCB1F10448600E07CEB /* CloudKitCategories.h in Headers */, DCFE1C281F17E455007640C8 /* CKKSDeviceStateEntry.h in Headers */, @@ -21562,6 +22700,7 @@ DCEA5D861E2F14810089CF55 /* CKKSAPSReceiver.h in Headers */, DC222C711E034D1F00B09171 /* CKKSOutgoingQueueEntry.h in Headers */, DCF7A8A11F04502400CABE89 /* CKKSControlProtocol.h in Headers */, + 47FF17271FD60ACA00875565 /* SFKeychainServer.h in Headers */, DCCD88E91E42622200F5AA71 /* CKKSGroupOperation.h in Headers */, DC15F7671E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h in Headers */, DCD6C4B31EC5302500414FEE /* CKKSNearFutureScheduler.h in Headers */, @@ -21606,6 +22745,7 @@ DC52E7E41D80BE6E00B0A59C /* SecDbKeychainItem.h in Headers */, DC7A17ED1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h in Headers */, DC52E7E31D80BDA600B0A59C /* SecDbQuery.h in Headers */, + 470D96711FCDE55B0065FE90 /* SecCDKeychain.h in Headers */, DC378B2D1DEF9DF000A3DAFA /* CKKSMirrorEntry.h in Headers */, DC94BCCA1F10448600E07CEB /* CloudKitCategories.h in Headers */, DCFE1C271F17E455007640C8 /* CKKSDeviceStateEntry.h in Headers */, @@ -21629,6 +22769,7 @@ DCD662F51E329B6800188186 /* CKKSNewTLKOperation.h in Headers */, DC52E7EB1D80BE9B00B0A59C /* iCloudTrace.h in Headers */, DCF7A8A01F04502400CABE89 /* CKKSControlProtocol.h in Headers */, + 47FF17261FD60ACA00875565 /* SFKeychainServer.h in Headers */, DC6D2C931DD2836500BE372D /* CKKSOutgoingQueueEntry.h in Headers */, DC15F7661E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h in Headers */, DCD6C4B21EC5302500414FEE /* CKKSNearFutureScheduler.h in Headers */, @@ -21652,6 +22793,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 48FE669720E6E69D00FAEF17 /* SOSAuthKitHelpers.h in Headers */, DCB3325A1F478C4100178C30 /* SOSUserKeygen.h in Headers */, DC52E9071D80C3B300B0A59C /* SOSARCDefines.h in Headers */, 0C48990B1E0E0FF300C6CF70 /* SOSTransportCircleCK.h in Headers */, @@ -21677,7 +22819,6 @@ DC52E9231D80C47100B0A59C /* SOSTransportCircleKVS.h in Headers */, DC52E92C1D80C4AF00B0A59C /* SOSTransportKeyParameter.h in Headers */, DC52E9241D80C47900B0A59C /* SOSTransportMessage.h in Headers */, - DC52E9191D80C42F00B0A59C /* SOSTransportMessageIDS.h in Headers */, DC52E9321D80C4DF00B0A59C /* SOSTransportMessageKVS.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -21755,6 +22896,7 @@ buildActionMask = 2147483647; files = ( DC0B62281D90974300D43BCB /* si-25-cms-skid.h in Headers */, + DCE2341720A3D4B8009766A3 /* si-cms-hash-agility-data.h in Headers */, D487FBBA1DB835B500D4BB0B /* si-29-sectrust-sha1-deprecation.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -22155,6 +23297,7 @@ DCD068471D8CDF7E007602F1 /* reqparser.h in Headers */, DCD069061D8CDFFE007602F1 /* CommonASTWithHiddenTokens.hpp in Headers */, DCD068451D8CDF7E007602F1 /* reqinterp.h in Headers */, + A6B1BA82207BDCB200F1E099 /* notarization.h in Headers */, DCD069151D8CDFFF007602F1 /* RefCount.hpp in Headers */, DCD068431D8CDF7E007602F1 /* reqreader.h in Headers */, DCD069191D8CDFFF007602F1 /* TokenBuffer.hpp in Headers */, @@ -22368,7 +23511,6 @@ 0CE760541E13155100B4381E /* SOSAccountTrustClassic+Circle.h in Headers */, DCD8A15C1E09EE0F00E4FA0A /* SOSBackupSliceKeyBag.h in Headers */, DCD8A15D1E09EE0F00E4FA0A /* SOSCircle.h in Headers */, - 0C4899271E0F399B00C6CF70 /* SOSAccountTrustOctagon.h in Headers */, DCD8A15F1E09EE0F00E4FA0A /* SOSCirclePriv.h in Headers */, DCD8A1601E09EE0F00E4FA0A /* SOSCircleRings.h in Headers */, DCD8A1611E09EE0F00E4FA0A /* SOSCircleV2.h in Headers */, @@ -22379,7 +23521,6 @@ DCD8A1651E09EE0F00E4FA0A /* SOSCloudKeychainConstants.h in Headers */, DCD8A1661E09EE0F00E4FA0A /* SOSRingRecovery.h in Headers */, 0C4899231E0F386900C6CF70 /* SOSAccountTrustClassic.h in Headers */, - DCD8A1E11E09F76D00E4FA0A /* SOSPeerInfoSecurityProperties.h in Headers */, DCD8A16C1E09EE0F00E4FA0A /* SOSFullPeerInfo.h in Headers */, DCD8A1DD1E09F73F00E4FA0A /* SOSPeerInfoDER.h in Headers */, DCD8A16D1E09EE0F00E4FA0A /* SOSGenCount.h in Headers */, @@ -22604,6 +23745,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EBCE16631FE7366D002E7CCC /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + EBCE16681FE736AD002E7CCC /* DeviceSimulatorProtocol.h in Headers */, + EBCE16641FE73679002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EBCE16651FE7368C002E7CCC /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + EBCE16661FE736A1002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */, + EBCE16671FE736A5002E7CCC /* DeviceSimulatorProtocol.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXLegacyTarget section */ @@ -22895,6 +24054,43 @@ productReference = 0C8BBF081FCB446400580909 /* otctl */; productType = "com.apple.product-type.tool"; }; + 0C9AEEAB20783FBB00BF6237 /* SignInAnalyticsTests_osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0C9AEEB420783FBB00BF6237 /* Build configuration list for PBXNativeTarget "SignInAnalyticsTests_osx" */; + buildPhases = ( + 0C9AEEAE20783FBB00BF6237 /* Sources */, + 0C9AEEB020783FBB00BF6237 /* Frameworks */, + 0C9AEEB320783FBB00BF6237 /* Embed OCMock */, + ); + buildRules = ( + ); + dependencies = ( + 0C9AEEBA20783FE000BF6237 /* PBXTargetDependency */, + ); + name = SignInAnalyticsTests_osx; + productName = CKKSTests; + productReference = 0C9AEEB720783FBB00BF6237 /* SignInAnalyticsTests_osx.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 0CF406042072E3E3003D6A7F /* SignInAnalyticsTests_ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0CF4064D2072E3E3003D6A7F /* Build configuration list for PBXNativeTarget "SignInAnalyticsTests_ios" */; + buildPhases = ( + 0CF406112072E3E3003D6A7F /* Sources */, + 0CF406342072E3E3003D6A7F /* Frameworks */, + 0CF4064A2072E3E3003D6A7F /* Embed OCMock */, + ); + buildRules = ( + ); + dependencies = ( + 0C5663EE20BE2E1A0035F362 /* PBXTargetDependency */, + 0C3E2EA92073F5C400F5B95B /* PBXTargetDependency */, + ); + name = SignInAnalyticsTests_ios; + productName = CKKSTests; + productReference = 0CF406502072E3E3003D6A7F /* SignInAnalyticsTests_ios.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 225394AC1E3080A600D3CD9B /* security_codesigning_ios */ = { isa = PBXNativeTarget; buildConfigurationList = 225394B11E3080A600D3CD9B /* Build configuration list for PBXNativeTarget "security_codesigning_ios" */; @@ -22913,6 +24109,46 @@ productReference = 225394B41E3080A600D3CD9B /* libsecurity_codesigning_ios.a */; productType = "com.apple.product-type.library.static"; }; + 3DD1FEF5201C07F30086D049 /* SecureTransport_macos_tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3DD1FF4A201C07F30086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_macos_tests" */; + buildPhases = ( + 3DD1FF02201C07F30086D049 /* Sources */, + 3DD1FF2F201C07F30086D049 /* Frameworks */, + 3DD1FFD6201FF7930086D049 /* CopyFiles */, + 3DD1FF49201C07F30086D049 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 3DD1FF50201C09CD0086D049 /* PBXTargetDependency */, + 3DD1FEF8201C07F30086D049 /* PBXTargetDependency */, + ); + name = SecureTransport_macos_tests; + productName = CKKSTests; + productReference = 3DD1FF4D201C07F30086D049 /* SecureTransport_macos_tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 3DD1FFAC201FDB1D0086D049 /* SecureTransport_ios_tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3DD1FFCD201FDB1D0086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_ios_tests" */; + buildPhases = ( + 3DD1FFB3201FDB1D0086D049 /* Sources */, + 3DD1FFC3201FDB1D0086D049 /* Frameworks */, + 3DD1FFD3201FF72C0086D049 /* CopyFiles */, + 3DD1FFCC201FDB1D0086D049 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 3DD1FFAF201FDB1D0086D049 /* PBXTargetDependency */, + 3DD1FFB1201FDB1D0086D049 /* PBXTargetDependency */, + ); + name = SecureTransport_ios_tests; + productName = CKKSTests; + productReference = 3DD1FFD0201FDB1D0086D049 /* SecureTransport_ios_tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 4381690B1B4EDCBD00C54D58 /* SOSCCAuthPlugin */ = { isa = PBXNativeTarget; buildConfigurationList = 438169381B4EDCBD00C54D58 /* Build configuration list for PBXNativeTarget "SOSCCAuthPlugin" */; @@ -22947,20 +24183,62 @@ productReference = 470415CF1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; productType = "com.apple.product-type.tool"; }; + 4718AE02205B39620068EC3F /* securityd_bridge */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4718AE2A205B39620068EC3F /* Build configuration list for PBXNativeTarget "securityd_bridge" */; + buildPhases = ( + 4718AE0F205B39620068EC3F /* Sources */, + 4718AE17205B39620068EC3F /* Frameworks */, + 4718AE26205B39620068EC3F /* CopyFiles */, + 4718AE28205B39620068EC3F /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 4718AEE6205B3A350068EC3F /* PBXTargetDependency */, + 4718AE03205B39620068EC3F /* PBXTargetDependency */, + 4718AE05205B39620068EC3F /* PBXTargetDependency */, + 4718AE09205B39620068EC3F /* PBXTargetDependency */, + 4718AE0B205B39620068EC3F /* PBXTargetDependency */, + 4718AE0D205B39620068EC3F /* PBXTargetDependency */, + ); + name = securityd_bridge; + productName = securityd; + productReference = 4718AE2D205B39620068EC3F /* securityd */; + productType = "com.apple.product-type.tool"; + }; + 4718AE2E205B39C40068EC3F /* libsecurityd_bridge */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4718AEDF205B39C40068EC3F /* Build configuration list for PBXNativeTarget "libsecurityd_bridge" */; + buildPhases = ( + 4718AE2F205B39C40068EC3F /* Sources */, + 4718AE9C205B39C40068EC3F /* Frameworks */, + 4718AE9D205B39C40068EC3F /* Headers */, + ); + buildRules = ( + 4718AEDE205B39C40068EC3F /* PBXBuildRule */, + ); + dependencies = ( + ); + name = libsecurityd_bridge; + productName = libsecurity; + productReference = 4718AEE2205B39C40068EC3F /* libsecurityd_bridge.a */; + productType = "com.apple.product-type.library.static"; + }; 4727FBB61F9918580003AE36 /* secdxctests_ios */ = { isa = PBXNativeTarget; buildConfigurationList = 4727FBC31F9918590003AE36 /* Build configuration list for PBXNativeTarget "secdxctests_ios" */; buildPhases = ( 4727FBB31F9918580003AE36 /* Sources */, 4727FBB41F9918580003AE36 /* Frameworks */, - 4727FBB51F9918580003AE36 /* Resources */, + 090585D120AEF9FE00BB7490 /* Install OCMock framework */, ); buildRules = ( ); dependencies = ( + 47A6FC6A206B461700BD6C54 /* PBXTargetDependency */, 47DE88D91FA7ADBB00DD3254 /* PBXTargetDependency */, 47DE88D71FA7ADAC00DD3254 /* PBXTargetDependency */, - 47DE88D51FA7AD7000DD3254 /* PBXTargetDependency */, 47DE88CE1FA7AD6200DD3254 /* PBXTargetDependency */, ); name = secdxctests_ios; @@ -23002,23 +24280,40 @@ productReference = 47702B2E1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; productType = "com.apple.product-type.tool"; }; + 4771D971209A755800BA9772 /* KeychainDataclassOwner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4771D97D209A755900BA9772 /* Build configuration list for PBXNativeTarget "KeychainDataclassOwner" */; + buildPhases = ( + 4771D96E209A755800BA9772 /* Sources */, + 4771D96F209A755800BA9772 /* Frameworks */, + 4771D970209A755800BA9772 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = KeychainDataclassOwner; + productName = KeychainDataclassOwner; + productReference = 4771D972209A755800BA9772 /* KeychainDataclassOwner.bundle */; + productType = "com.apple.product-type.bundle"; + }; 478D426C1FD72A8100CAB645 /* secdxctests_mac */ = { isa = PBXNativeTarget; buildConfigurationList = 478D42991FD72A8100CAB645 /* Build configuration list for PBXNativeTarget "secdxctests_mac" */; buildPhases = ( 478D42751FD72A8100CAB645 /* Sources */, 478D427D1FD72A8100CAB645 /* Frameworks */, - 478D42981FD72A8100CAB645 /* Resources */, + 090585D020AEF9D300BB7490 /* Install OCMock framework */, ); buildRules = ( ); dependencies = ( + 47A6FC6C206B462400BD6C54 /* PBXTargetDependency */, DC34CD3620326C3B00302481 /* PBXTargetDependency */, DC34CD3420326C3100302481 /* PBXTargetDependency */, DC34CD2D20326C2C00302481 /* PBXTargetDependency */, 478D426D1FD72A8100CAB645 /* PBXTargetDependency */, 478D426F1FD72A8100CAB645 /* PBXTargetDependency */, - 478D42711FD72A8100CAB645 /* PBXTargetDependency */, 478D42731FD72A8100CAB645 /* PBXTargetDependency */, ); name = secdxctests_mac; @@ -23026,6 +24321,23 @@ productReference = 478D429C1FD72A8100CAB645 /* secdxctests_mac.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 47C2F1822059CB680062DE30 /* KeychainResources */ = { + isa = PBXNativeTarget; + buildConfigurationList = 47C2F1872059CB690062DE30 /* Build configuration list for PBXNativeTarget "KeychainResources" */; + buildPhases = ( + 47C2F17F2059CB680062DE30 /* Sources */, + 47C2F1802059CB680062DE30 /* Frameworks */, + 47C2F1812059CB680062DE30 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = KeychainResources; + productName = KeychainResources; + productReference = 47C2F1832059CB680062DE30 /* KeychainResources.bundle */; + productType = "com.apple.product-type.bundle"; + }; 47C51B831EEA657D0032D9E5 /* SecurityUnitTests */ = { isa = PBXNativeTarget; buildConfigurationList = 47C51B931EEA657D0032D9E5 /* Build configuration list for PBXNativeTarget "SecurityUnitTests" */; @@ -23265,6 +24577,7 @@ buildPhases = ( 6C46057A1F882B9B001421B6 /* Sources */, 6C46059B1F882B9B001421B6 /* Frameworks */, + 6C4F981E2075831300A3C5AB /* CopyFiles */, ); buildRules = ( ); @@ -23556,26 +24869,6 @@ productReference = BEF88C301EAFFC3F00357577 /* TrustedPeersTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - CD276C261A83F60C003226BC /* KeychainSyncingOverIDSProxy */ = { - isa = PBXNativeTarget; - buildConfigurationList = CD276C2C1A83F60C003226BC /* Build configuration list for PBXNativeTarget "KeychainSyncingOverIDSProxy" */; - buildPhases = ( - CD276C231A83F60C003226BC /* Sources */, - CD276C241A83F60C003226BC /* Frameworks */, - CDF91EA61AAE019800E88CF7 /* Install alloy plist */, - 8E64DAF81C17BA620076C9DF /* Install launchd plist */, - EB76B7561DCB0C6900C43FBC /* Install man8 page */, - ); - buildRules = ( - ); - dependencies = ( - DC65E7331D8CB34000152EF0 /* PBXTargetDependency */, - ); - name = KeychainSyncingOverIDSProxy; - productName = KeychainSyncingOverIDSProxy; - productReference = CD276C271A83F60C003226BC /* KeychainSyncingOverIDSProxy.bundle */; - productType = "com.apple.product-type.bundle"; - }; D41257CE1E9410A300781F23 /* trustd_ios */ = { isa = PBXNativeTarget; buildConfigurationList = D41257D61E9410A300781F23 /* Build configuration list for PBXNativeTarget "trustd_ios" */; @@ -23629,6 +24922,22 @@ productReference = DA30D6761DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater.bundle */; productType = "com.apple.product-type.bundle"; }; + DAE40BC520CF3E46002D5674 /* secitemcanarytest */ = { + isa = PBXNativeTarget; + buildConfigurationList = DAE40BCB20CF3E46002D5674 /* Build configuration list for PBXNativeTarget "secitemcanarytest" */; + buildPhases = ( + DAE40BC620CF3E46002D5674 /* Sources */, + DAE40BC820CF3E46002D5674 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = secitemcanarytest; + productName = secbackupntest; + productReference = DAE40BCE20CF3E47002D5674 /* secitemcanarytest */; + productType = "com.apple.product-type.tool"; + }; DC0067921D87876F005AF8DB /* securityd_server_macos */ = { isa = PBXNativeTarget; buildConfigurationList = DC0067BD1D87876F005AF8DB /* Build configuration list for PBXNativeTarget "securityd_server_macos" */; @@ -24173,7 +25482,6 @@ DC52E7741D80BC8000B0A59C /* Sources */, DC52E7AD1D80BC8000B0A59C /* Frameworks */, DC52E7AE1D80BC8000B0A59C /* Headers */, - 6C0B0C4A1E253840007F95E5 /* CopyFiles */, ); buildRules = ( DC9FD3201F85818000C8AAC8 /* PBXBuildRule */, @@ -24920,6 +26228,7 @@ DC65E7661D8CB4C200152EF0 /* PBXTargetDependency */, DC65E7681D8CB4CB00152EF0 /* PBXTargetDependency */, DCE4E7D81D7A4B3500AFB96E /* PBXTargetDependency */, + DC193C6020CB4C9D009C1A0F /* PBXTargetDependency */, DC65E76A1D8CB4D300152EF0 /* PBXTargetDependency */, ); name = sectests_macos; @@ -25252,6 +26561,43 @@ productReference = E7D847CE1C6BE9720025BB44 /* KeychainCircleTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + EB056E3D1FE5E390000A771E /* DeviceSimulator */ = { + isa = PBXNativeTarget; + buildConfigurationList = EB056E4E1FE5E391000A771E /* Build configuration list for PBXNativeTarget "DeviceSimulator" */; + buildPhases = ( + EBCE16631FE7366D002E7CCC /* Headers */, + EB056E3A1FE5E390000A771E /* Sources */, + EB056E3B1FE5E390000A771E /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DeviceSimulator; + productName = DeviceSimulator; + productReference = EB056E3E1FE5E390000A771E /* DeviceSimulator.xpc */; + productType = "com.apple.product-type.xpc-service"; + }; + EB05C4F01FE5E48A00D68712 /* MultiDeviceSimulatorTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = EB05C4FD1FE5E48B00D68712 /* Build configuration list for PBXNativeTarget "MultiDeviceSimulatorTests" */; + buildPhases = ( + EBCE16651FE7368C002E7CCC /* Headers */, + EB05C4ED1FE5E48A00D68712 /* Sources */, + EB05C4EE1FE5E48A00D68712 /* Frameworks */, + EB05C4EF1FE5E48A00D68712 /* Resources */, + EBCE150D1FE63880002E7CCC /* Embedded XPC service */, + ); + buildRules = ( + ); + dependencies = ( + EBCE15101FE638A2002E7CCC /* PBXTargetDependency */, + ); + name = MultiDeviceSimulatorTests; + productName = MultiDeviceSimulatorTests; + productReference = EB05C4F11FE5E48A00D68712 /* MultiDeviceSimulatorTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; EB0BC9361C3C791500785842 /* secedumodetest */ = { isa = PBXNativeTarget; buildConfigurationList = EB0BC93B1C3C791500785842 /* Build configuration list for PBXNativeTarget "secedumodetest" */; @@ -25380,7 +26726,7 @@ buildPhases = ( EB49B2AA202D877F003F34A0 /* Sources */, EB49B2AB202D877F003F34A0 /* Frameworks */, - EB49B30E202FF484003F34A0 /* Embedded OCMock */, + EBC73F4B209A0C3400AE3350 /* Install OCMock framework */, ); buildRules = ( ); @@ -25516,7 +26862,7 @@ 4C35DB69094F906D002917C4 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1000; TargetAttributes = { 4381690B1B4EDCBD00C54D58 = { CreatedOnToolsVersion = 7.0; @@ -25537,12 +26883,24 @@ CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; }; + 4771D971209A755800BA9772 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; 478D426C1FD72A8100CAB645 = { ProvisioningStyle = Automatic; }; + 47C2F1822059CB680062DE30 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; 47C51B831EEA657D0032D9E5 = { CreatedOnToolsVersion = 9.0; }; + 4809F7A42061B697003E72D0 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; 5EBE24791B00CCAE0007DB0E = { CreatedOnToolsVersion = 7.0; }; @@ -25580,9 +26938,6 @@ CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; }; - CD276C261A83F60C003226BC = { - CreatedOnToolsVersion = 7.0; - }; D41257CE1E9410A300781F23 = { CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; @@ -25723,6 +27078,14 @@ E7D847CD1C6BE9720025BB44 = { CreatedOnToolsVersion = 7.3; }; + EB056E3D1FE5E390000A771E = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; + EB05C4F01FE5E48A00D68712 = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; EB1055741E14DF430003C309 = { CreatedOnToolsVersion = 8.2.1; ProvisioningStyle = Automatic; @@ -25825,17 +27188,18 @@ DCE4E8931D7F34F600AFB96E /* authd */, DCE4E7F51D7A4DA800AFB96E /* secd */, 790851B50CA9859F0083CC4D /* securityd_ios */, + 4718AE02205B39620068EC3F /* securityd_bridge */, DC5AC04F1D8352D900CF422C /* securityd_macos */, 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */, D41257CE1E9410A300781F23 /* trustd_ios */, DCE4E82D1D7A57AE00AFB96E /* trustd_macos */, 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */, - CD276C261A83F60C003226BC /* KeychainSyncingOverIDSProxy */, DC0BC5501D8B6D2D00070CB0 /* XPCKeychainSandboxCheck */, DC0BC5631D8B6E3D00070CB0 /* XPCTimeStampingService */, DC8E04B11D7F6EC9006D80EB /* ======= Libraries ========= */, DCC78EA81D8088E200865A7C /* security */, DC52E7731D80BC8000B0A59C /* libsecurityd_ios */, + 4718AE2E205B39C40068EC3F /* libsecurityd_bridge */, DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */, D4ADA3181E2B41670031CEA3 /* libtrustd */, DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */, @@ -25919,6 +27283,8 @@ DCE4E7311D7A43B500AFB96E /* SecurityTestsOSX */, DC3502B41E0208BE00BC0587 /* CKKSTests */, 0C85DFD11FB38BB6000343A7 /* OTTests */, + 0CF406042072E3E3003D6A7F /* SignInAnalyticsTests_ios */, + 0C9AEEAB20783FBB00BF6237 /* SignInAnalyticsTests_osx */, DC610AAD1D7910C3002223DE /* gk_reset_check_macos */, DC610A551D78F9D2002223DE /* codesign_tests_macos */, DC610A461D78F48F002223DE /* SecTaskTest_macos */, @@ -25933,6 +27299,7 @@ BED208D41EDF950E00753952 /* manifeststresstest */, EB433A201CC3243600A7EACE /* secitemstresstest */, EBA9AA7D1CE30E58004E2B68 /* secitemnotifications */, + DAE40BC520CF3E46002D5674 /* secitemcanarytest */, DCE4E7CB1D7A4AED00AFB96E /* sectests_macos */, 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */, 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */, @@ -25951,6 +27318,15 @@ 6CF4A0DF1E4549F200ECD7B5 /* KeychainEntitledTestApp_ios */, 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */, 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */, + 47C51B831EEA657D0032D9E5 /* SecurityUnitTests */, + 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */, + EB05C4F01FE5E48A00D68712 /* MultiDeviceSimulatorTests */, + EB056E3D1FE5E390000A771E /* DeviceSimulator */, + 4727FBB61F9918580003AE36 /* secdxctests_ios */, + 478D426C1FD72A8100CAB645 /* secdxctests_mac */, + EB49B2AD202D877F003F34A0 /* secdmockaks */, + 3DD1FEF5201C07F30086D049 /* SecureTransport_macos_tests */, + 3DD1FFAC201FDB1D0086D049 /* SecureTransport_ios_tests */, DC5AC1351D835D9700CF422C /* ===== Source Gen ===== */, DC008B451D90CE53004002A3 /* securityd_macos_mig */, DC6BC26C1D90CFEF00DD57B3 /* securityd_macos_startup */, @@ -25987,10 +27363,8 @@ E79EEDE01CD4000C00C2FBFC /* Security_executables */, 05EF68B519491512007958C3 /* Security_frameworks */, F667EC561E96E9B100203D5C /* authdtest */, - 47C51B831EEA657D0032D9E5 /* SecurityUnitTests */, - 4727FBB61F9918580003AE36 /* secdxctests_ios */, - 478D426C1FD72A8100CAB645 /* secdxctests_mac */, - EB49B2AD202D877F003F34A0 /* secdmockaks */, + 47C2F1822059CB680062DE30 /* KeychainResources */, + 4771D971209A755800BA9772 /* KeychainDataclassOwner */, ); }; /* End PBXProject section */ @@ -26083,14 +27457,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4727FBB51F9918580003AE36 /* Resources */ = { + 4771D970209A755800BA9772 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 478D42981FD72A8100CAB645 /* Resources */ = { + 47C2F1812059CB680062DE30 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -26101,6 +27475,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + D465131A2097FF2E005D93FE /* Main.storyboard in Resources */, + D465131B2097FF2E005D93FE /* Assets.xcassets in Resources */, + D465131C2097FF2E005D93FE /* LaunchScreen.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -26110,7 +27487,6 @@ files = ( D4C263CF1F953019001317EA /* SecDebugErrorMessages.strings in Resources */, D4C263CE1F95300F001317EA /* SecErrorMessages.strings in Resources */, - BEB9EA2F1FFF1AF700676593 /* si-88-sectrust-valid-data in Resources */, 47922D4F1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto in Resources */, 53C0E1FF177FB48A00F8A018 /* CloudKeychain.strings in Resources */, BE4AC9BA18B8273600B84964 /* SharedWebCredentials.strings in Resources */, @@ -26174,8 +27550,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6CF4A0C01E45488B00ECD7B5 /* Assets.xcassets in Resources */, - 6CF4A0C31E45488B00ECD7B5 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -26183,9 +27557,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6CF4A0F21E4549F300ECD7B5 /* LaunchScreen.storyboard in Resources */, - 6CF4A0EF1E4549F300ECD7B5 /* Assets.xcassets in Resources */, - 6CF4A0ED1E4549F300ECD7B5 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -26310,7 +27681,6 @@ DCE4E9081D7F3A4800AFB96E /* Icon.icns in Resources */, DCE4E90A1D7F3A4800AFB96E /* Credits.rtf in Resources */, DCE4E9091D7F3A4800AFB96E /* InfoPlist.strings in Resources */, - DC0B62301D909C4600D43BCB /* MainMenu.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -26321,7 +27691,6 @@ DCE4E9491D7F3E8E00AFB96E /* Localizable.strings in Resources */, DCE4E94A1D7F3E8E00AFB96E /* com.apple.security.keychain-circle-notification.plist in Resources */, DCE4E94B1D7F3E8E00AFB96E /* InfoPlist.strings in Resources */, - DC0B622F1D909C4600D43BCB /* MainMenu.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -26370,6 +27739,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EB05C4EF1FE5E48A00D68712 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; EB108F3A1E6CE4D2003B0456 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -26380,49 +27756,61 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 0C85DFFF1FB38BB6000343A7 /* ShellScript */ = { + 090585D020AEF9D300BB7490 /* Install OCMock framework */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; files = ( ); inputPaths = ( ); + name = "Install OCMock framework"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "#Disable until this places a plist in this directory\n#chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + shellScript = "sh xcscripts/install-test-framework.sh OCMock.framework\n"; }; - 5EE098DE1CD21661009FCA27 /* Unifdef RC_HIDE_J79/J80 */ = { + 090585D120AEF9FE00BB7490 /* Install OCMock framework */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 8; files = ( ); inputPaths = ( ); - name = "Unifdef RC_HIDE_J79/J80"; + name = "Install OCMock framework"; outputPaths = ( ); - runOnlyForDeploymentPostprocessing = 0; + runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "if [ -d $DSTROOT ]; then\n RC_HIDE_J79_VAL=0\n RC_HIDE_J80_VAL=0\n SEC_HDRS_PATH=\"System/Library/Frameworks/Security.framework/Headers\"\n\n if [ ! -z $RC_HIDE_J79 ]; then\n RC_HIDE_J79_VAL=1\n fi\n\n if [ ! -z $RC_HIDE_J80 ]; then\n RC_HIDE_J80_VAL=1\n fi\n\n if [ -a $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h ]; then\n unifdef -B -DRC_HIDE_J79=$RC_HIDE_J79_VAL -DRC_HIDE_J80=$RC_HIDE_J80_VAL -o $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h\n if [$? eq 2]; then\n exit 2\n fi\n fi\n\n if [ -a $DSTROOT/$SEC_HDRS_PATH/SecItem.h ]; then\n unifdef -B -DRC_HIDE_J79=$RC_HIDE_J79_VAL -DRC_HIDE_J80=$RC_HIDE_J80_VAL -o $DSTROOT/$SEC_HDRS_PATH/SecItem.h $DSTROOT/$SEC_HDRS_PATH/SecItem.h\n if [$? eq 2]; then\n exit 2\n fi\n fi\n\n exit 0\nfi"; - showEnvVarsInLog = 0; + shellScript = "sh xcscripts/install-test-framework.sh OCMock.framework"; }; - 6CAA8D361F84317F007B6E03 /* Install launchd plist */ = { + 0C85DFFF1FB38BB6000343A7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; files = ( ); inputPaths = ( ); - name = "Install launchd plist"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "mkdir -p \"$LAUNCHD_PLIST_LOCATION\"\nplutil -convert binary1 -o \"$LAUNCHD_PLIST_LOCATION/com.apple.securityuploadd.plist\" \"$LAUNCHD_PLIST\""; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\n#Disable until this places a plist in this directory\n#chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; }; - 6CB5F4761E402D0000DBF3F0 /* ShellScript */ = { + 3DD1FF49201C07F30086D049 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + }; + 3DD1FFCC201FDB1D0086D049 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; files = ( @@ -26433,24 +27821,49 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + }; + 5EE098DE1CD21661009FCA27 /* Unifdef RC_HIDE_J79/J80 */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Unifdef RC_HIDE_J79/J80"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ -d $DSTROOT ]; then\n RC_HIDE_J79_VAL=0\n RC_HIDE_J80_VAL=0\n SEC_HDRS_PATH=\"System/Library/Frameworks/Security.framework/Headers\"\n\n if [ ! -z $RC_HIDE_J79 ]; then\n RC_HIDE_J79_VAL=1\n fi\n\n if [ ! -z $RC_HIDE_J80 ]; then\n RC_HIDE_J80_VAL=1\n fi\n\n if [ -a $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h ]; then\n unifdef -B -DRC_HIDE_J79=$RC_HIDE_J79_VAL -DRC_HIDE_J80=$RC_HIDE_J80_VAL -o $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h\n if [$? eq 2]; then\n exit 2\n fi\n fi\n\n if [ -a $DSTROOT/$SEC_HDRS_PATH/SecItem.h ]; then\n unifdef -B -DRC_HIDE_J79=$RC_HIDE_J79_VAL -DRC_HIDE_J80=$RC_HIDE_J80_VAL -o $DSTROOT/$SEC_HDRS_PATH/SecItem.h $DSTROOT/$SEC_HDRS_PATH/SecItem.h\n if [$? eq 2]; then\n exit 2\n fi\n fi\n\n exit 0\nfi"; + showEnvVarsInLog = 0; }; - 8E64DAF81C17BA620076C9DF /* Install launchd plist */ = { + 6CAA8D361F84317F007B6E03 /* Install launchd plist */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; files = ( ); inputPaths = ( - "$(PROJECT_DIR)/KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.ios.plist", - "$(PROJECT_DIR)/KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.osx.plist", ); name = "Install launchd plist"; outputPaths = ( - "$(INSTALL_ROOT)/$(INSTALL_DAEMON_AGENT_DIR)/com.apple.security.keychainsyncingoveridsproxy.plist", ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "PLIST_FILE_NAME=com.apple.security.keychainsyncingoveridsproxy\nFILE_TO_COPY=${PROJECT_DIR}/KeychainSyncingOverIDSProxy/${PLIST_FILE_NAME}.ios.plist\n\nif [ ${PLATFORM_NAME} = \"macosx\" ]\nthen\n FILE_TO_COPY=${PROJECT_DIR}/KeychainSyncingOverIDSProxy/${PLIST_FILE_NAME}.osx.plist\nfi\n\ncp ${FILE_TO_COPY} ${INSTALL_ROOT}/${INSTALL_DAEMON_AGENT_DIR}/${PLIST_FILE_NAME}.plist"; + shellScript = "mkdir -p \"$LAUNCHD_PLIST_LOCATION\"\nplutil -convert binary1 -o \"$LAUNCHD_PLIST_LOCATION/com.apple.securityuploadd.plist\" \"$LAUNCHD_PLIST\""; + }; + 6CB5F4761E402D0000DBF3F0 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; }; 8E64DB4E1C18A5B80076C9DF /* Install launchd plist */ = { isa = PBXShellScriptBuildPhase; @@ -26654,7 +28067,7 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; }; DC71D9FE1D95BB5B0065FB93 /* Why is this here? */ = { isa = PBXShellScriptBuildPhase; @@ -26820,7 +28233,7 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "chown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; showEnvVarsInLog = 0; }; EB108F3D1E6CE4D2003B0456 /* chmod BATS Tests */ = { @@ -26836,7 +28249,7 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "chown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; showEnvVarsInLog = 0; }; EBC15E801BE29A8C001C0C5B /* Chown BATS plist */ = { @@ -26851,9 +28264,23 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "chown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; showEnvVarsInLog = 0; }; + EBC73F4B209A0C3400AE3350 /* Install OCMock framework */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + name = "Install OCMock framework"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "sh xcscripts/install-test-framework.sh OCMock.framework\n"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -26861,6 +28288,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DCD504C220CB28BF00F37D26 /* SecFramework.c in Sources */, 476541A11F33EDA500413F65 /* SecdWatchdog.m in Sources */, DCCD33D21E3FF0D800AA4AD1 /* spi.c in Sources */, 0C0BDB32175685B000BC1A7E /* main.m in Sources */, @@ -26897,12 +28325,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0C7756CE209A694100268D2C /* SFSignInAnalytics.m in Sources */, 0CB9754F2023A8F5008D6B48 /* CloudKitMockXCTest.m in Sources */, 0CB9754E2023A8DD008D6B48 /* CloudKitKeychainSyncingMockXCTest.m in Sources */, 0C0DA5D01FE1F1F3003BD3BB /* CKKSControlProtocol.m in Sources */, 0CBDF64D1FFC951200433E0D /* OTBottledPeerTLK.m in Sources */, 0C16371C1FD116B300210823 /* MockCloudKit.m in Sources */, 0C8A034F1FDF60070042E8BE /* OTBottledPeerTests.m in Sources */, + 6C53A44D206AB1EF000FA611 /* LocalKeychainAnalytics.m in Sources */, 0C52C1FF20003BCA003F0733 /* OTTestsBase.m in Sources */, 0C1637211FD12F1500210823 /* OTCloudStoreTests.m in Sources */, 0CAEC9D81FD740CF00D1F2CA /* OTContextTests.m in Sources */, @@ -26912,6 +28342,7 @@ DCDB296C1FD8820400B5D242 /* SFAnalytics.m in Sources */, 6C73F48D2006B83E003D5D63 /* SOSAnalytics.m in Sources */, 0C46A57B2035019800F17112 /* OTLockStateNetworkingTests.m in Sources */, + DC5B391820C08B39005B09F6 /* SecFramework.c in Sources */, DCDB296E1FD8821400B5D242 /* SFAnalyticsActivityTracker.m in Sources */, DCDB29701FD8821800B5D242 /* SFAnalyticsMultiSampler.m in Sources */, DCDB29741FD8822200B5D242 /* SFAnalyticsSQLiteStore.m in Sources */, @@ -26940,10 +28371,28 @@ files = ( 0C8BBF1B1FCB4EC500580909 /* OTControlProtocol.m in Sources */, 0C8BBF091FCB447600580909 /* otctl.m in Sources */, + 4771DA2620A4C34800BA9772 /* OT.m in Sources */, 0C8BBEFF1FCB446400580909 /* SecArgParse.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 0C9AEEAE20783FBB00BF6237 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C9AEEAF20783FBB00BF6237 /* SFSignInAnalyticsTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0CF406112072E3E3003D6A7F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C5663EC20BE2DF30035F362 /* SFSignInAnalytics.m in Sources */, + 0CF406522072E422003D6A7F /* SFSignInAnalyticsTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 225394AD1E3080A600D3CD9B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -26951,6 +28400,7 @@ 220179EB1E3BF1F100EFB6F3 /* detachedrep.cpp in Sources */, 220179EA1E3BF16000EFB6F3 /* slcrep.cpp in Sources */, 220179E31E3BEB7100EFB6F3 /* dirscanner.cpp in Sources */, + A690B033208A75D1002FB775 /* notarization.cpp in Sources */, 225394B81E30820900D3CD9B /* Code.cpp in Sources */, 225394B91E30821400D3CD9B /* bundlediskrep.cpp in Sources */, 225394BA1E30821E00D3CD9B /* cdbuilder.cpp in Sources */, @@ -26982,6 +28432,51 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3DD1FF02201C07F30086D049 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3DD1FF99201FC50E0086D049 /* STLegacyTests+noconn.m in Sources */, + 3DD1FF98201FC5080086D049 /* STLegacyTests+falsestart.m in Sources */, + 3DD1FF96201FC4FE0086D049 /* STLegacyTests+crashes.m in Sources */, + 3DD1FF95201FC4F70086D049 /* STLegacyTests+clientauth.m in Sources */, + 3DD1FF92201FC4EA0086D049 /* SecureTransportTests.m in Sources */, + 3DD1FF93201FC4EF0086D049 /* STLegacyTests.m in Sources */, + 3DD1FF94201FC4F40086D049 /* STLegacyTests+ciphers.m in Sources */, + 3DD1FF97201FC5030086D049 /* STLegacyTests+dhe.m in Sources */, + 3DD1FF9A201FC5130086D049 /* STLegacyTests+renegotiate.m in Sources */, + 3DD1FF9B201FC5170086D049 /* STLegacyTests+sessioncache.m in Sources */, + 3DD1FF9C201FC51B0086D049 /* STLegacyTests+sessionstate.m in Sources */, + 3DD1FF9E201FC53A0086D049 /* STLegacyTests+split.m in Sources */, + 3DD1FF9F201FC5410086D049 /* STLegacyTests+sslciphers.m in Sources */, + 3DD1FFA0201FC5450086D049 /* STLegacyTests+tls12.m in Sources */, + 3DD1FFA1201FC5660086D049 /* ssl-utils.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3DD1FFB3201FDB1D0086D049 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3DD1FFB4201FDB1D0086D049 /* STLegacyTests+noconn.m in Sources */, + 3DD1FFB5201FDB1D0086D049 /* STLegacyTests+falsestart.m in Sources */, + 3DD1FFB6201FDB1D0086D049 /* STLegacyTests+crashes.m in Sources */, + 3DD1FFB7201FDB1D0086D049 /* STLegacyTests+clientauth.m in Sources */, + 3DD1FFB8201FDB1D0086D049 /* SecureTransportTests.m in Sources */, + 3DD1FFB9201FDB1D0086D049 /* STLegacyTests.m in Sources */, + 3DD1FFBA201FDB1D0086D049 /* STLegacyTests+ciphers.m in Sources */, + 3DD1FFBB201FDB1D0086D049 /* STLegacyTests+dhe.m in Sources */, + 3DD1FFBC201FDB1D0086D049 /* STLegacyTests+renegotiate.m in Sources */, + 3DD1FFBD201FDB1D0086D049 /* STLegacyTests+sessioncache.m in Sources */, + 3DD1FFBE201FDB1D0086D049 /* STLegacyTests+sessionstate.m in Sources */, + 3DD1FFBF201FDB1D0086D049 /* STLegacyTests+split.m in Sources */, + 3DD1FFC0201FDB1D0086D049 /* STLegacyTests+sslciphers.m in Sources */, + 3DD1FFC1201FDB1D0086D049 /* STLegacyTests+tls12.m in Sources */, + 3DD1FFD1201FDC460086D049 /* STLegacyTests+clientauth41.m in Sources */, + 3DD1FFC2201FDB1D0086D049 /* ssl-utils.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 438169081B4EDCBD00C54D58 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -26998,6 +28493,131 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4718AE0F205B39620068EC3F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4718AE10205B39620068EC3F /* spi.c in Sources */, + 4718AE11205B39620068EC3F /* SecdWatchdog.m in Sources */, + 4718AE12205B39620068EC3F /* server.c in Sources */, + 4718AE13205B39620068EC3F /* server_entitlement_helpers.c in Sources */, + 4718AE14205B39620068EC3F /* server_security_helpers.c in Sources */, + 4718AE15205B39620068EC3F /* server_xpc.m in Sources */, + 4718AE16205B39620068EC3F /* server_endpoint.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4718AE2F205B39C40068EC3F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4718AE30205B39C40068EC3F /* OTAuthenticatedCiphertext.proto in Sources */, + 4718AE31205B39C40068EC3F /* OTPrivateKey.proto in Sources */, + 4718AE32205B39C40068EC3F /* OTBottle.proto in Sources */, + 4718AE33205B39C40068EC3F /* OTBottleContents.proto in Sources */, + 4718AE34205B39C40068EC3F /* CKKSSerializedKey.proto in Sources */, + 4718AE35205B39C40068EC3F /* CKKSSQLDatabaseObject.m in Sources */, + 4718AE36205B39C40068EC3F /* CKKSRateLimiter.m in Sources */, + 4718AE37205B39C40068EC3F /* CKKSCKAccountStateTracker.m in Sources */, + 4718AE38205B39C40068EC3F /* SecCDKeychain.m in Sources */, + 4718AE39205B39C40068EC3F /* CKKSPowerCollection.m in Sources */, + 4718AE3A205B39C40068EC3F /* CKKSGroupOperation.m in Sources */, + 4718AE3B205B39C40068EC3F /* OTContextRecord.m in Sources */, + 4718AE3C205B39C40068EC3F /* OTPrivateKey+SF.m in Sources */, + 4718AE3D205B39C40068EC3F /* CKKSManifestLeafRecord.m in Sources */, + 4718AE3E205B39C40068EC3F /* CKKSItem.m in Sources */, + 4718AE3F205B39C40068EC3F /* CKKSItemEncrypter.m in Sources */, + 4718AE40205B39C40068EC3F /* CKKSOutgoingQueueEntry.m in Sources */, + 4718AE42205B39C40068EC3F /* CKKSIncomingQueueEntry.m in Sources */, + 4718AE43205B39C40068EC3F /* OTLocalStore.m in Sources */, + 4718AE44205B39C40068EC3F /* SFKeychainControlManager.m in Sources */, + 4718AE45205B39C40068EC3F /* OTBottledPeerSigned.m in Sources */, + 4718AE46205B39C40068EC3F /* CKKSIncomingQueueOperation.m in Sources */, + 4718AE47205B39C40068EC3F /* CKKSOutgoingQueueOperation.m in Sources */, + 4718AE48205B39C40068EC3F /* CKKSZoneStateEntry.m in Sources */, + 4718AE49205B39C40068EC3F /* AsymKeybagBackup.m in Sources */, + 4718AE4A205B39C40068EC3F /* RateLimiter.m in Sources */, + 4718AE4B205B39C40068EC3F /* CKKSHealKeyHierarchyOperation.m in Sources */, + 4718AE4C205B39C40068EC3F /* CKKSCurrentItemPointer.m in Sources */, + 4718AE4D205B39C40068EC3F /* CKKSLocalSynchronizeOperation.m in Sources */, + 4718AE4E205B39C40068EC3F /* OTManager.m in Sources */, + 4718AE4F205B39C40068EC3F /* OTEscrowKeys.m in Sources */, + 4718AE50205B39C40068EC3F /* CKKSCurrentKeyPointer.m in Sources */, + 4718AE51205B39C40068EC3F /* CKKSControlServer.m in Sources */, + 4718AE52205B39C40068EC3F /* CKKSUpdateDeviceStateOperation.m in Sources */, + 4718AE53205B39C40068EC3F /* SecDbKeychainSerializedMetadata.m in Sources */, + 4718AE54205B39C40068EC3F /* CKKSNearFutureScheduler.m in Sources */, + 4718AE55205B39C40068EC3F /* CKKSMirrorEntry.m in Sources */, + 4718AE56205B39C40068EC3F /* CloudKitCategories.m in Sources */, + 4718AE57205B39C40068EC3F /* CKKSPeer.m in Sources */, + 4718AE58205B39C40068EC3F /* CKKS.m in Sources */, + 4718AE59205B39C40068EC3F /* CKKSSynchronizeOperation.m in Sources */, + 4718AE5A205B39C40068EC3F /* CKKSRecordHolder.m in Sources */, + 4718AE5B205B39C40068EC3F /* SOSChangeTracker.c in Sources */, + 4718AE5C205B39C40068EC3F /* CKKSScanLocalItemsOperation.m in Sources */, + 4718AE5D205B39C40068EC3F /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */, + 4718AE5E205B39C40068EC3F /* CKKSNotifier.m in Sources */, + 4718AE5F205B39C40068EC3F /* SOSEngine.c in Sources */, + 4718AE60205B39C40068EC3F /* CKKSKey.m in Sources */, + 4718AE61205B39C40068EC3F /* CKKSViewManager.m in Sources */, + 4718AE62205B39C40068EC3F /* SecDbKeychainItemV7.m in Sources */, + 4718AE63205B39C40068EC3F /* OTControlProtocol.m in Sources */, + 4718AE64205B39C40068EC3F /* CKKSReachabilityTracker.m in Sources */, + 4718AE65205B39C40068EC3F /* SecDbItem.c in Sources */, + 4718AE66205B39C40068EC3F /* SecDbKeychainItem.m in Sources */, + 4718AE67205B39C40068EC3F /* SecDbQuery.c in Sources */, + 4718AE68205B39C40068EC3F /* CKKSResultOperation.m in Sources */, + 4718AE69205B39C40068EC3F /* CKKSManifest.m in Sources */, + 4718AE6A205B39C40068EC3F /* SecItemBackupServer.c in Sources */, + 4718AE6B205B39C40068EC3F /* SecItemDataSource.c in Sources */, + 4718AE6C205B39C40068EC3F /* OctagonControlServer.m in Sources */, + 4718AE6D205B39C40068EC3F /* SecItemDb.c in Sources */, + 4718AE6E205B39C40068EC3F /* SecItemSchema.c in Sources */, + 4718AE6F205B39C40068EC3F /* OTConstants.m in Sources */, + 4718AE70205B39C40068EC3F /* OTRamping.m in Sources */, + 4718AE71205B39C40068EC3F /* SecItemServer.c in Sources */, + 4718AE72205B39C40068EC3F /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */, + D491112D209515400066A1E4 /* CKKSAnalytics.m in Sources */, + 4718AE74205B39C40068EC3F /* OTContext.m in Sources */, + 4718AE75205B39C40068EC3F /* NSOperationCategories.m in Sources */, + 4718AE76205B39C40068EC3F /* SecKeybagSupport.c in Sources */, + 4718AE77205B39C40068EC3F /* SecLogSettingsServer.m in Sources */, + 4718AE78205B39C40068EC3F /* CKKSDeviceStateEntry.m in Sources */, + 4718AE79205B39C40068EC3F /* CKKSFixups.m in Sources */, + 4718AE7A205B39C40068EC3F /* OTIdentity.m in Sources */, + 4718AE7C205B39C40068EC3F /* SecOTRRemote.m in Sources */, + 4718AE7D205B39C40068EC3F /* CKKSUpdateCurrentItemPointerOperation.m in Sources */, + 4718AE7E205B39C40068EC3F /* CKKSNewTLKOperation.m in Sources */, + 4718AE7F205B39C40068EC3F /* CKKSLockStateTracker.m in Sources */, + 4718AE80205B39C40068EC3F /* OTCloudStoreState.m in Sources */, + 4718AE81205B39C40068EC3F /* SecDbKeychainSerializedSecretData.m in Sources */, + 4718AE82205B39C40068EC3F /* CKKSKeychainView.m in Sources */, + 4718AE83205B39C40068EC3F /* SecuritydXPC.c in Sources */, + 4718AE84205B39C40068EC3F /* SecDbKeychainSerializedItemV7.m in Sources */, + 4718AE85205B39C40068EC3F /* OT.m in Sources */, + 4718AE86205B39C40068EC3F /* CKKSProcessReceivedKeysOperation.m in Sources */, + 4718AE87205B39C40068EC3F /* CKKSTLKShare.m in Sources */, + 4718AE88205B39C40068EC3F /* CKKSHealTLKSharesOperation.m in Sources */, + 4718AE89205B39C40068EC3F /* CKKSReencryptOutgoingItemsOperation.m in Sources */, + 4718AE8A205B39C40068EC3F /* SecBackupKeybagEntry.m in Sources */, + 4718AE8B205B39C40068EC3F /* iCloudTrace.c in Sources */, + 4718AE8C205B39C40068EC3F /* CKKSAPSReceiver.m in Sources */, + 4718AE8D205B39C40068EC3F /* OTBottledPeer.m in Sources */, + 4718AE8F205B39C40068EC3F /* SOSEnsureBackup.m in Sources */, + 4718AE90205B39C40068EC3F /* OTBottledPeerRecord.m in Sources */, + 4718AE91205B39C40068EC3F /* OTCloudStore.m in Sources */, + 4718AE92205B39C40068EC3F /* CKKSSIV.m in Sources */, + 4718AE93205B39C40068EC3F /* OTPreflightInfo.m in Sources */, + 4718AE95205B39C40068EC3F /* OTAuthenticatedCiphertext+SF.m in Sources */, + 4718AE96205B39C40068EC3F /* CKKSZoneChangeFetcher.m in Sources */, + 4718AE97205B39C40068EC3F /* CKKSCondition.m in Sources */, + 4718AE98205B39C40068EC3F /* CKKSZone.m in Sources */, + 4718AE99205B39C40068EC3F /* SFKeychainServer.m in Sources */, + 4718AE9A205B39C40068EC3F /* SFECPublicKey+SPKI.m in Sources */, + 4718AE9B205B39C40068EC3F /* swcagent_client.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4727FBB31F9918580003AE36 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -27008,9 +28628,11 @@ 477A1FED2037A0E000ACD81D /* KeychainXCTest.m in Sources */, 4727FBEB1F99227F0003AE36 /* spi.c in Sources */, 4727FBEC1F99235B0003AE36 /* SecdWatchdog.m in Sources */, + 4764E9272059D866005497C9 /* KeychainModel.xcdatamodeld in Sources */, 4727FBBA1F9918590003AE36 /* KeychainCryptoTests.m in Sources */, 477A1FE4203763A500ACD81D /* KeychainAPITests.m in Sources */, 4727FBED1F99249A0003AE36 /* server_endpoint.m in Sources */, + 096C647020AB1BC700D7B7D5 /* KeychainEntitlementsTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -27030,14 +28652,26 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4771D96E209A755800BA9772 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 47D13759209CD1A200CAD493 /* NSError+UsefulConstructors.m in Sources */, + 4771DA2520A4C33A00BA9772 /* OT.m in Sources */, + 4771D980209A75FE00BA9772 /* KeychainDataclassOwner.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 478D42751FD72A8100CAB645 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 478D42761FD72A8100CAB645 /* server_xpc.m in Sources */, + 4764E92D2059D8BF005497C9 /* KeychainModel.xcdatamodeld in Sources */, 478D42771FD72A8100CAB645 /* server_security_helpers.c in Sources */, 478D42781FD72A8100CAB645 /* server_entitlement_helpers.c in Sources */, 477A1FEE2037A0E000ACD81D /* KeychainXCTest.m in Sources */, + 09BFE35C20A32E0E008511E9 /* KeychainEntitlementsTest.m in Sources */, 478D42791FD72A8100CAB645 /* spi.c in Sources */, 478D427A1FD72A8100CAB645 /* SecdWatchdog.m in Sources */, 478D427B1FD72A8100CAB645 /* KeychainCryptoTests.m in Sources */, @@ -27046,6 +28680,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 47C2F17F2059CB680062DE30 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 47C2F18A2059CB820062DE30 /* KeychainModel.xcdatamodeld in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 47C51B801EEA657D0032D9E5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -27061,11 +28703,13 @@ 6CAA8CFF1F83E800007B6E03 /* SFSQLite.m in Sources */, 6CDB5FF61FA78D1B00410924 /* SFAnalyticsMultiSampler.m in Sources */, D46246A61F9AE61000D63882 /* oids.c in Sources */, - 0CBFEACB200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */, + 0CBFEACB200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */, 0CBD55B31FE883F200A8CE21 /* SFBehavior.m in Sources */, + 6C814A4D2050B4B600CB391B /* LocalKeychainAnalytics.m in Sources */, 220179E91E3BF03200EFB6F3 /* dummy.cpp in Sources */, DC926F091F33FA8D0012A315 /* CKKSControlProtocol.m in Sources */, 4723C9CC1F152ED30082882F /* SFSQLiteStatement.m in Sources */, + DCC5860020BF8A7E005C7269 /* SecFramework.c in Sources */, DCA85B931E8D97E400BA7241 /* client.c in Sources */, 6CBF653A1FA147E500A68667 /* SFAnalyticsActivityTracker.m in Sources */, DC9C95BF1F79DC88000D19E5 /* CKKSControl.m in Sources */, @@ -27081,7 +28725,9 @@ 0C8BBF121FCB4AAB00580909 /* OTControl.m in Sources */, EB48C1A51E573EE400EC5E57 /* whoami.m in Sources */, B61F67571F1FCFCB00E2FDBB /* SecPaddingConfigurations.c in Sources */, + AA44E0D72032515C001EA371 /* SecProtocolTypes.m in Sources */, 6CE365531FA101080012F6AB /* SFAnalyticsSampler.m in Sources */, + AA44E0D520325150001EA371 /* SecProtocol.c in Sources */, 6C73F48A2006B839003D5D63 /* SOSAnalytics.m in Sources */, 6CE365571FA1017D0012F6AB /* SFAnalyticsSQLiteStore.m in Sources */, ); @@ -27163,6 +28809,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4771DA2720A4C37D00BA9772 /* OT.m in Sources */, 5346481E173322BD00FE9172 /* KeychainSyncAccountNotification.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -27292,6 +28939,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D49111322095154B0066A1E4 /* Assets.xcassets in Sources */, + D49111312095154B0066A1E4 /* Main.storyboard in Sources */, 6CF4A0BE1E45488B00ECD7B5 /* ViewController.m in Sources */, 6CF4A0BB1E45488B00ECD7B5 /* main.m in Sources */, 6CF4A0B81E45488B00ECD7B5 /* AppDelegate.m in Sources */, @@ -27408,20 +29057,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - CD276C231A83F60C003226BC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CD23B49E1DA06EB40047EDE9 /* IDSPersistentState.m in Sources */, - CD23B4A01DA06EB40047EDE9 /* IDSProxy.m in Sources */, - 0C5D62F11E81E74800AA4D02 /* SOSInternal.m in Sources */, - CD23B4A11DA06EB40047EDE9 /* keychainsyncingoveridsproxy.m in Sources */, - CD23B4A31DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m in Sources */, - CD23B4A51DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m in Sources */, - E7A5F5591C0D052600F3BEBB /* SOSCloudKeychainConstants.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; D41257CB1E9410A300781F23 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -27435,13 +29070,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D43DBEFB1E99D1CA00C04AEA /* asynchttp.c in Sources */, D43DBEFC1E99D1CA00C04AEA /* nameconstraints.c in Sources */, D43DBEFD1E99D1CA00C04AEA /* OTATrustUtilities.m in Sources */, D43DBEFE1E99D1CA00C04AEA /* personalization.c in Sources */, D43DBEFF1E99D1CA00C04AEA /* policytree.c in Sources */, D43DBF001E99D1CA00C04AEA /* SecCAIssuerCache.c in Sources */, - D43DBF011E99D1CA00C04AEA /* SecCAIssuerRequest.c in Sources */, + D43DBF011E99D1CA00C04AEA /* SecCAIssuerRequest.m in Sources */, D43DBF021E99D1CA00C04AEA /* SecCertificateServer.c in Sources */, D43DBF031E99D1CA00C04AEA /* SecCertificateSource.c in Sources */, D43DBF041E99D1CA00C04AEA /* SecOCSPCache.c in Sources */, @@ -27453,6 +29087,7 @@ D43DBF091E99D1CA00C04AEA /* SecRevocationDb.c in Sources */, D43DBF0A1E99D1CA00C04AEA /* SecRevocationServer.c in Sources */, D43DBF0B1E99D1CA00C04AEA /* SecTrustLoggingServer.m in Sources */, + D4961BC42079424200F16DA7 /* TrustURLSessionDelegate.m in Sources */, D43DBF0C1E99D1CA00C04AEA /* SecTrustServer.c in Sources */, D43DBF0D1E99D1CA00C04AEA /* SecTrustStoreServer.c in Sources */, D40B6A9B1E2B690E00CD6EE5 /* SecuritydXPC.c in Sources */, @@ -27467,6 +29102,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DAE40BC620CF3E46002D5674 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DAE40BD920CF3F0F002D5674 /* secitemcanarytest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DC0067A81D87876F005AF8DB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -27845,6 +29488,7 @@ DC0BCDAB1D8C6A1F00070CB0 /* SecXPCError.c in Sources */, DC0BCDB51D8C6A5B00070CB0 /* not_on_this_platorm.c in Sources */, DC65E7C01D8CBB1500152EF0 /* readline.c in Sources */, + DA5B871D2065A8440093F083 /* SecAutorelease.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -27874,20 +29518,24 @@ files = ( 0CBD55B91FE883F300A8CE21 /* SFBehavior.m in Sources */, D46246A71F9AE62000D63882 /* oids.c in Sources */, + DCC585FF20BF8A7E005C7269 /* SecFramework.c in Sources */, DCA85B991E8D980B00BA7241 /* client_endpoint.m in Sources */, DC926F0A1F33FA8E0012A315 /* CKKSControlProtocol.m in Sources */, 6CE365541FA101090012F6AB /* SFAnalyticsSampler.m in Sources */, 6CE365581FA1017E0012F6AB /* SFAnalyticsSQLiteStore.m in Sources */, 6CDB5FF51FA78D1A00410924 /* SFAnalyticsMultiSampler.m in Sources */, + AA44E0D82032515C001EA371 /* SecProtocolTypes.m in Sources */, DCA85B941E8D97E400BA7241 /* client.c in Sources */, DCDF0A4F1D81D76F007AF174 /* Security.exp-in in Sources */, - 0CBFEACA200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */, + 0CBFEACA200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */, + AA44E0D620325150001EA371 /* SecProtocol.c in Sources */, DC1789A51D779E3B00B50D50 /* dummy.cpp in Sources */, 0C8BBF111FCB4AAA00580909 /* OTControl.m in Sources */, 4723C9CD1F152ED40082882F /* SFSQLiteStatement.m in Sources */, EB10A3E920356E7A00E84270 /* OTConstants.m in Sources */, 6CAA8CFE1F83E800007B6E03 /* SFSQLite.m in Sources */, DC9C95C01F79DC89000D19E5 /* CKKSControl.m in Sources */, + 6CB420A52051FDD500FF2D44 /* LocalKeychainAnalytics.m in Sources */, 0C8BBF141FCB4AFB00580909 /* OTControlProtocol.m in Sources */, B61577E81F20151C004A3930 /* SecPaddingConfigurations.c in Sources */, 6C73F48B2006B83A003D5D63 /* SOSAnalytics.m in Sources */, @@ -27902,6 +29550,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DCAE1DDE2073FDCD00B4F687 /* NSError+UsefulConstructors.m in Sources */, BEE4B18D1FFD588000777D39 /* OTAuthenticatedCiphertext.proto in Sources */, BEB0B0D81FFC3DD3007E6A83 /* OTPrivateKey.proto in Sources */, BE3405AE1FD725EC00933DAC /* OTBottle.proto in Sources */, @@ -27916,7 +29565,6 @@ BEB0B0DE1FFC45D8007E6A83 /* OTPrivateKey+SF.m in Sources */, DC222C3B1E034D1F00B09171 /* SOSChangeTracker.c in Sources */, DC222C3D1E034D1F00B09171 /* SOSEngine.c in Sources */, - 6C8CC3B31E2F913D009025C5 /* AWDKeychainCKKSRateLimiterAggregatedScores.m in Sources */, DC222C401E034D1F00B09171 /* SecDbItem.c in Sources */, DCCD88EB1E42622200F5AA71 /* CKKSGroupOperation.m in Sources */, DC222C411E034D1F00B09171 /* SecDbKeychainItem.m in Sources */, @@ -27955,9 +29603,9 @@ 0C8BBF181FCB4E5000580909 /* OTControlProtocol.m in Sources */, EB4E0CDC1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */, DC1DA6691E4555D80094CE7F /* CKKSScanLocalItemsOperation.m in Sources */, - 6C8CC3B41E2F913D009025C5 /* AWDKeychainCKKSRateLimiterOverload.m in Sources */, 0C8BBEA21FC9DBAA00580909 /* OTContext.m in Sources */, DC222C4A1E034D1F00B09171 /* SecLogSettingsServer.m in Sources */, + 470D96741FCDE55B0065FE90 /* SecCDKeychain.m in Sources */, DC14478D1F5764C600236DB4 /* CKKSResultOperation.m in Sources */, 479DA1781EBBA8D30065C98F /* CKKSManifest.m in Sources */, DCD662F81E329B6800188186 /* CKKSNewTLKOperation.m in Sources */, @@ -27968,10 +29616,10 @@ 0C5CFB392019610000913B9C /* OTRamping.m in Sources */, DC222C4E1E034D1F00B09171 /* CKKS.m in Sources */, DC762AA11E57A86A00B03A2C /* CKKSRecordHolder.m in Sources */, + 4718AEE4205B3A060068EC3F /* KeychainModel.xcdatamodeld in Sources */, DC222C501E034D1F00B09171 /* SecOTRRemote.m in Sources */, 47922D451FAA7C2E0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */, - 479108BA1EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */, - 479108BA1EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */, + D491112E209515400066A1E4 /* CKKSAnalytics.m in Sources */, DC1447991F5766D200236DB4 /* NSOperationCategories.m in Sources */, DC222C511E034D1F00B09171 /* CKKSItem.m in Sources */, DCBDB3BE1E57CA7A00B61300 /* CKKSViewManager.m in Sources */, @@ -27990,13 +29638,12 @@ 0CCCC7CA20261D310024405E /* OT.m in Sources */, 47922D571FAA7E0E0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */, DC222C571E034D1F00B09171 /* SecuritydXPC.c in Sources */, + 47FF17291FD60ACA00875565 /* SFKeychainServer.m in Sources */, DC7341F61F8447AB00AB9BDF /* CKKSTLKShare.m in Sources */, - 6C8CC3B51E2F913D009025C5 /* AWDKeychainCKKSRateLimiterTopWriters.m in Sources */, DCBDB3B81E57C82300B61300 /* CKKSKeychainView.m in Sources */, DC222C5A1E034D1F00B09171 /* iCloudTrace.c in Sources */, DC5BB5011E0C98320010F836 /* CKKSOutgoingQueueOperation.m in Sources */, 0C8BBEA01FC9DBA400580909 /* OTBottledPeer.m in Sources */, - 6C869A7A1F54C37A00957298 /* AWDKeychainSOSKeychainBackupFailed.m in Sources */, 6C869A761F50CAF500957298 /* SOSEnsureBackup.m in Sources */, BE2AD2BB1FDA080900739F96 /* OTBottledPeerRecord.m in Sources */, 0C770EC51FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */, @@ -28016,6 +29663,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6C53A447206AB1A6000FA611 /* LocalKeychainAnalytics.m in Sources */, 476541A61F33EE2700413F65 /* SecdWatchdog.m in Sources */, 6CAA8CF41F83E799007B6E03 /* SFSQLite.m in Sources */, 4771ECCD1F17CD0E00840998 /* SFSQLiteStatement.m in Sources */, @@ -28049,11 +29697,14 @@ 6CDF8DF11F96498300140B54 /* SFAnalyticsSampler.m in Sources */, DC222CA81E08A7D900B09171 /* CloudKitMockXCTest.m in Sources */, DC9C75161E4BCE1800F1CA0D /* CKKSOperationTests.m in Sources */, + DC8D238D2064649400E163C8 /* CKKSAPSHandlingTests.m in Sources */, DCB221561E8B08BF001598BC /* server_xpc.m in Sources */, DC42690F1E82FD9C002B7110 /* server_security_helpers.c in Sources */, DC4268FE1E820371002B7110 /* server_endpoint.m in Sources */, DCFE1C3D1F17EFB5007640C8 /* CKKSConditionTests.m in Sources */, DCCD33C91E3FE95900AA4AD1 /* spi.c in Sources */, + 0C7756CD209A664800268D2C /* SFSignInAnalytics.m in Sources */, + DC5B391720C08B38005B09F6 /* SecFramework.c in Sources */, 6CFDC4551F907D2600646DBB /* SFObjCType.m in Sources */, DC9C95971F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m in Sources */, DC7341FE1F84642C00AB9BDF /* CKKSTLKSharingEncryptionTests.m in Sources */, @@ -28076,6 +29727,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DCAE1DDD2073FDCC00B4F687 /* NSError+UsefulConstructors.m in Sources */, BEE4B18C1FFD585800777D39 /* OTAuthenticatedCiphertext.proto in Sources */, BEB0B0D71FFC3D9A007E6A83 /* OTPrivateKey.proto in Sources */, BE3405AC1FD7258900933DAC /* OTBottle.proto in Sources */, @@ -28084,6 +29736,7 @@ DC797E1A1DD3F9A400CC9E42 /* CKKSSQLDatabaseObject.m in Sources */, 6CC1859F1E24E8EB009657D8 /* CKKSRateLimiter.m in Sources */, DCFB12C71E95A4C000510F5F /* CKKSCKAccountStateTracker.m in Sources */, + 470D96731FCDE55B0065FE90 /* SecCDKeychain.m in Sources */, EBB407B31EBA46B200A541A5 /* CKKSPowerCollection.m in Sources */, DCCD88EA1E42622200F5AA71 /* CKKSGroupOperation.m in Sources */, 0CD9E8001FE05B6600F66C38 /* OTContextRecord.m in Sources */, @@ -28092,7 +29745,6 @@ DCDCCB901DF7B8D4006E840E /* CKKSItem.m in Sources */, DC1ED8C11DD5197E002BDCFA /* CKKSItemEncrypter.m in Sources */, DC6D2C921DD2835A00BE372D /* CKKSOutgoingQueueEntry.m in Sources */, - 6C8CC3AD1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterTopWriters.m in Sources */, DC378B3D1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m in Sources */, 0C8BBEA91FC9DBBF00580909 /* OTLocalStore.m in Sources */, 4733377B1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */, @@ -28142,8 +29794,8 @@ 0C5CFB382019610000913B9C /* OTRamping.m in Sources */, DC52E7D71D80BD2D00B0A59C /* SecItemServer.c in Sources */, 47922D441FAA7C2C0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */, - 479108B91EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */, - 479108B91EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */, + 4718AEE3205B3A050068EC3F /* KeychainModel.xcdatamodeld in Sources */, + D491112C209515400066A1E4 /* CKKSAnalytics.m in Sources */, 0C8BBEE61FCA6E0500580909 /* OTContext.m in Sources */, DC1447981F5766D200236DB4 /* NSOperationCategories.m in Sources */, DCD8A0CF1E09EA1800E4FA0A /* SecKeybagSupport.c in Sources */, @@ -28151,7 +29803,6 @@ DCFE1C291F17E455007640C8 /* CKKSDeviceStateEntry.m in Sources */, DCAD9B461F8D939C00C5E2AE /* CKKSFixups.m in Sources */, 0C8BBEA71FC9DBB500580909 /* OTIdentity.m in Sources */, - 6C8CC3AC1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterOverload.m in Sources */, DC52E7DC1D80BD4F00B0A59C /* SecOTRRemote.m in Sources */, DCE278EA1ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m in Sources */, DCD662F71E329B6800188186 /* CKKSNewTLKOperation.m in Sources */, @@ -28170,17 +29821,16 @@ DC52E7D41D80BD1D00B0A59C /* iCloudTrace.c in Sources */, DCEA5D871E2F14810089CF55 /* CKKSAPSReceiver.m in Sources */, 0C8BBE9F1FC9DBA400580909 /* OTBottledPeer.m in Sources */, - 6C869A791F54C37900957298 /* AWDKeychainSOSKeychainBackupFailed.m in Sources */, 6C869A751F50CAF400957298 /* SOSEnsureBackup.m in Sources */, BE2AD2BA1FDA080800739F96 /* OTBottledPeerRecord.m in Sources */, 0C770EC41FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */, DCEA5D571E2826DB0089CF55 /* CKKSSIV.m in Sources */, 0C36B3212007F2550029F7A2 /* OTPreflightInfo.m in Sources */, - 6C8CC3AB1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterAggregatedScores.m in Sources */, BEE4B1941FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m in Sources */, DC9082C41EA0277600D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */, DCFE1C361F17ECE5007640C8 /* CKKSCondition.m in Sources */, DCEA5D971E3015830089CF55 /* CKKSZone.m in Sources */, + 47FF17281FD60ACA00875565 /* SFKeychainServer.m in Sources */, BEE4B19A1FFDAFE600777D39 /* SFECPublicKey+SPKI.m in Sources */, DC52E7C51D80BCB300B0A59C /* swcagent_client.c in Sources */, ); @@ -28209,6 +29859,7 @@ DC52E8F21D80C34000B0A59C /* SOSAccountTransaction.m in Sources */, DC52E8FD1D80C34000B0A59C /* SOSAccountUpdate.m in Sources */, DC52E9001D80C34000B0A59C /* SOSAccountViewSync.m in Sources */, + 0CB50A0D20AA486800FE4675 /* SOSAccountTrustClassic+Expansion.m in Sources */, DC52E9011D80C34000B0A59C /* SOSBackupEvent.c in Sources */, DC2670F71F3E721800816EED /* SOSAccountTrustClassic.m in Sources */, 7281E0871DFD01800021E1B7 /* SOSAccountGetSet.m in Sources */, @@ -28221,14 +29872,15 @@ DC52E8E31D80C31F00B0A59C /* SOSPeerCoder.m in Sources */, DCFAEDCF1D999859005187E4 /* SOSAccountGhost.m in Sources */, EB6928F91D9ED5BA00062A18 /* SecRecoveryKey.m in Sources */, + 48FE669620E6E69D00FAEF17 /* SOSAuthKitHelpers.m in Sources */, 48776C811DA5BC0E00CC09B9 /* SOSAccountRecovery.m in Sources */, DC52E8C91D80C2FD00B0A59C /* SOSTransportBackupPeer.m in Sources */, + 0CB50A0E20AA4C2F00FE4675 /* SOSAccountTrustClassic+Circle.m in Sources */, DC52E8CA1D80C2FD00B0A59C /* SOSTransportCircle.m in Sources */, DC52E8CB1D80C2FD00B0A59C /* SOSTransportCircleKVS.m in Sources */, DC52E8CC1D80C2FD00B0A59C /* SOSTransportKeyParameter.m in Sources */, DC52E8CE1D80C2FD00B0A59C /* SOSTransportMessage.m in Sources */, 0CAD1E1C1E032ADB00537693 /* SOSCloudCircleServer.m in Sources */, - DC52E8CF1D80C2FD00B0A59C /* SOSTransportMessageIDS.m in Sources */, 0CAC5DBF1EB3DA4C00AD884B /* SOSPeerRateLimiter.m in Sources */, DAB27AE11FA29EE300DEBBDE /* SOSControlServer.m in Sources */, DC52E8D01D80C2FD00B0A59C /* SOSTransportMessageKVS.m in Sources */, @@ -28367,7 +30019,6 @@ DC52ECD51D80D22600B0A59C /* si-78-query-attrs.c in Sources */, DC52ECD61D80D22600B0A59C /* si-80-empty-data.c in Sources */, DC52ECD91D80D22600B0A59C /* si-82-token-ag.c in Sources */, - DC52ECDD1D80D22600B0A59C /* si-89-cms-hash-agility.m in Sources */, DC52ECDE1D80D22600B0A59C /* si-90-emcs.m in Sources */, DC52ECDF1D80D22600B0A59C /* si-95-cms-basic.c in Sources */, DC52EC981D80D1D100B0A59C /* vmdh-40.c in Sources */, @@ -28422,7 +30073,6 @@ 0CCDE7171EEB08220021A946 /* secd-156-timers.m in Sources */, DC52EDC21D80D5C500B0A59C /* secd-32-restore-bad-backup.m in Sources */, DC52EDC31D80D5C500B0A59C /* secd-33-keychain-ctk.m in Sources */, - 0CAD1E5C1E1C5CEB00537693 /* secd_77_ids_messaging.m in Sources */, DC0B622C1D90982C00D43BCB /* secd-201-coders.m in Sources */, 0CAD1E5A1E1C5CD100537693 /* secd-71-engine-save.m in Sources */, DC52EDC41D80D5C500B0A59C /* secd-34-backup-der-parse.m in Sources */, @@ -28443,7 +30093,6 @@ DC52EDD31D80D5C500B0A59C /* secd-59-account-cleanup.m in Sources */, DC52EDD41D80D5C500B0A59C /* secd-60-account-cloud-identity.m in Sources */, DC52EDD51D80D5C500B0A59C /* secd60-account-cloud-exposure.m in Sources */, - 0CAD1E5B1E1C5CE100537693 /* secd-76-idstransport.m in Sources */, DC52EDD61D80D5C500B0A59C /* secd-61-account-leave-not-in-kansas-anymore.m in Sources */, DC52EDD71D80D5C500B0A59C /* secd-62-account-backup.m in Sources */, DC52EDD91D80D5C500B0A59C /* secd-63-account-resurrection.m in Sources */, @@ -28456,14 +30105,12 @@ 0CAD1E591E1C5CBD00537693 /* secd-52-offering-gencount-reset.m in Sources */, DC52EDDD1D80D5C500B0A59C /* secd-70-engine-corrupt.m in Sources */, DC52EDDE1D80D5C500B0A59C /* secd-70-engine-smash.m in Sources */, - 0C5F4FD81F952FEA00AF1616 /* secd-700-sftm.m in Sources */, 522B280E1E64B4BF002B5638 /* secd-230-keybagtable.m in Sources */, DC52EDDF1D80D5C500B0A59C /* secd-70-otr-remote.m in Sources */, DC52EDE21D80D5C500B0A59C /* secd-74-engine-beer-servers.m in Sources */, 7281E0901DFD0E0A0021E1B7 /* CKDKVSProxy.m in Sources */, DC52EDE31D80D5C500B0A59C /* secd-75-engine-views.m in Sources */, DC52EDE61D80D5C500B0A59C /* secd-80-views-basic.m in Sources */, - DC52EDE71D80D5C500B0A59C /* secd-82-secproperties-basic.m in Sources */, DC52EDE81D80D5C500B0A59C /* secd-81-item-acl-stress.m in Sources */, DC52EDE91D80D5C500B0A59C /* secd-81-item-acl.m in Sources */, DC52EDEA1D80D5C500B0A59C /* secd-82-persistent-ref.m in Sources */, @@ -28494,9 +30141,11 @@ 09CB49701F2F64E300C8E4DE /* si-44-seckey-fv.m in Sources */, DC52EE5C1D80D76300B0A59C /* si-20-sectrust-policies.m in Sources */, DC52EE511D80D73800B0A59C /* si-15-certificate.c in Sources */, + D48BD18D206C45F00075DDC9 /* si-89-cms-hash-agility.m in Sources */, BE6215BE1DB6E69100961E15 /* si-84-sectrust-allowlist.m in Sources */, DC52EE521D80D73800B0A59C /* si-16-ec-certificate.c in Sources */, DC52EE421D80D71900B0A59C /* si-20-sectrust.c in Sources */, + D4B6D57C2069D8450099FBEF /* si-34-cms-timestamp.m in Sources */, D4096E031ED5F21C000AC459 /* si-65-cms-cert-policy.c in Sources */, DC52EE441D80D71900B0A59C /* si-21-sectrust-asr.c in Sources */, DC52EE451D80D71900B0A59C /* si-22-sectrust-iap.c in Sources */, @@ -28505,6 +30154,7 @@ DC52EE481D80D71900B0A59C /* si-24-sectrust-digicert-malaysia.c in Sources */, DC52EE491D80D71900B0A59C /* si-24-sectrust-diginotar.c in Sources */, DC52EE4A1D80D71900B0A59C /* si-24-sectrust-itms.c in Sources */, + DCE2341820A3D4B8009766A3 /* si-cms-hash-agility-data.c in Sources */, DC52EE4B1D80D71900B0A59C /* si-24-sectrust-nist.c in Sources */, DC52EE4C1D80D71900B0A59C /* si-24-sectrust-passbook.c in Sources */, DC52EE4D1D80D71900B0A59C /* si-26-sectrust-copyproperties.c in Sources */, @@ -28516,10 +30166,13 @@ DC52EE551D80D73800B0A59C /* si-44-seckey-ec.m in Sources */, D4096E011ED5F0B5000AC459 /* si-60-cms.c in Sources */, D4CFAA7E1E660BB3004746AA /* si-32-sectrust-pinning-required.m in Sources */, + D48BD194206C47530075DDC9 /* si-35-cms-expiration-time.m in Sources */, D487FBB81DB8357300D4BB0B /* si-29-sectrust-sha1-deprecation.m in Sources */, DC52EE561D80D73800B0A59C /* si-44-seckey-ies.m in Sources */, DC52EE571D80D73800B0A59C /* si-67-sectrust-blocklist.c in Sources */, D4096E021ED5F207000AC459 /* si-64-ossl-cms.c in Sources */, + 09A3B9E11F82734400C5C324 /* si-44-seckey-proxy.m in Sources */, + DCD45357209A5BA10086CBFC /* si-cms-signing-identity-p12.c in Sources */, DC52EE581D80D73800B0A59C /* si-70-sectrust-unified.c in Sources */, DC52EE591D80D73800B0A59C /* si-82-seccertificate-ct.c in Sources */, DC52EE5A1D80D73800B0A59C /* si-83-seccertificate-sighashalg.c in Sources */, @@ -28537,16 +30190,17 @@ DC52EE7C1D80D89E00B0A59C /* SecItemBackup.c in Sources */, DC4269051E82EDC4002B7110 /* SecItem.m in Sources */, EBEEEE3E1EA31DB100E15F5C /* SOSControlHelper.m in Sources */, - DC52EE7B1D80D89900B0A59C /* SecKeyAdaptors.c in Sources */, + DC52EE7B1D80D89900B0A59C /* SecKeyAdaptors.m in Sources */, DC52EE7A1D80D89400B0A59C /* SecCFAllocator.c in Sources */, DC52EE791D80D88D00B0A59C /* SecItem.c in Sources */, DC52EE781D80D88800B0A59C /* SecRSAKey.c in Sources */, + 09A3B9E21F838A3400C5C324 /* SecKeyProxy.m in Sources */, DC52EE771D80D88300B0A59C /* SecDH.c in Sources */, - DC52EE761D80D87F00B0A59C /* SecCTKKey.c in Sources */, + DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */, DC52EE741D80D86F00B0A59C /* SecAccessControl.c in Sources */, DC52EE731D80D86800B0A59C /* SecKey.c in Sources */, DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */, - DC52EE711D80D85F00B0A59C /* SecECKey.c in Sources */, + DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */, DC52EE701D80D84700B0A59C /* SecItemConstants.c in Sources */, DC52EE6F1D80D83F00B0A59C /* SecPasswordGenerate.c in Sources */, ); @@ -28653,6 +30307,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DCD504BC20CB28BE00F37D26 /* SecFramework.c in Sources */, 476541A21F33EDAD00413F65 /* SecdWatchdog.m in Sources */, DCCD33D31E3FF0D800AA4AD1 /* spi.c in Sources */, DC610A181D78F129002223DE /* main.m in Sources */, @@ -28970,6 +30625,7 @@ DCB3447A1D8A35270054D16E /* kc-01-keychain-creation.c in Sources */, DCB3447B1D8A35270054D16E /* kc-02-unlock-noui.c in Sources */, 24CBF8751E9D4E6100F09F0E /* kc-44-secrecoverypassword.c in Sources */, + DCD4535A209A60DD0086CBFC /* kc-keychain-file-helpers.c in Sources */, DCB3447D1D8A35270054D16E /* kc-03-keychain-list.c in Sources */, DCB3447C1D8A35270054D16E /* kc-03-status.c in Sources */, DCB3447E1D8A35270054D16E /* kc-04-is-valid.c in Sources */, @@ -29018,33 +30674,34 @@ buildActionMask = 2147483647; files = ( 0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */, + DC5B391A20C08B70005B09F6 /* SecBase.c in Sources */, DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */, DCC78EE61D808B2A00865A7C /* SecAccessControl.c in Sources */, DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */, DCC78EE41D808B1B00865A7C /* SecCFAllocator.c in Sources */, DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */, BEEB47D91EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */, - DCC78EE21D808B0E00865A7C /* SecCTKKey.c in Sources */, + DCC78EE21D808B0E00865A7C /* SecCTKKey.m in Sources */, DCC78EE11D808B0900865A7C /* SecCertificate.c in Sources */, DC4269041E82EDAC002B7110 /* SecItem.m in Sources */, EBEEEE3D1EA31DB000E15F5C /* SOSControlHelper.m in Sources */, DCC78EDF1D808AF800865A7C /* SecCertificateRequest.c in Sources */, DCC78EDE1D808AF100865A7C /* SecDH.c in Sources */, DCC78EDD1D808AEC00865A7C /* SecDigest.c in Sources */, - DCC78EDC1D808AE500865A7C /* SecECKey.c in Sources */, + DCC78EDC1D808AE500865A7C /* SecECKey.m in Sources */, DCC78EDB1D808ADF00865A7C /* SecEMCS.m in Sources */, - DCC78EDA1D808AD100865A7C /* SecFramework.c in Sources */, DCC78ED91D808ACB00865A7C /* SecIdentity.c in Sources */, DCC78ED81D808AC600865A7C /* SecImportExport.c in Sources */, DCC78ED71D808AC000865A7C /* SecItem.c in Sources */, DCC78ED61D808ABA00865A7C /* SecItemBackup.c in Sources */, DCC78ED51D808AAE00865A7C /* SecItemConstants.c in Sources */, DCC78ED41D808AA800865A7C /* SecKey.c in Sources */, - DCC78ED31D808AA000865A7C /* SecKeyAdaptors.c in Sources */, + DCC78ED31D808AA000865A7C /* SecKeyAdaptors.m in Sources */, DCC78ED21D808A9500865A7C /* SecOTRDHKey.c in Sources */, DCC78ED11D808A8E00865A7C /* SecOTRFullIdentity.c in Sources */, B61577ED1F202049004A3930 /* SecPaddingConfigurations.c in Sources */, DCC78ED01D808A8800865A7C /* SecOTRMath.c in Sources */, + 0927FEBC1F81338600864E07 /* SecKeyProxy.m in Sources */, DCC78ECF1D808A8200865A7C /* SecOTRPacketData.c in Sources */, DCC78ECE1D808A7B00865A7C /* SecOTRPackets.c in Sources */, DCC78ECD1D808A7300865A7C /* SecOTRPublicIdentity.c in Sources */, @@ -29121,6 +30778,7 @@ DCD068581D8CDF7E007602F1 /* bundlediskrep.cpp in Sources */, DCD068381D8CDF7E007602F1 /* cdbuilder.cpp in Sources */, DCD068361D8CDF7E007602F1 /* codedirectory.cpp in Sources */, + A6B1BA81207BD9EC00F1E099 /* notarization.cpp in Sources */, DCD068281D8CDF7E007602F1 /* cs.cpp in Sources */, DCD0686F1D8CDF7E007602F1 /* csdatabase.cpp in Sources */, DCD068711D8CDF7E007602F1 /* cserror.cpp in Sources */, @@ -29245,14 +30903,13 @@ DCD66DBF1D82053E00DB1393 /* SecDigest.c in Sources */, BEEB47DA1EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */, DCD66DBE1D82053700DB1393 /* SecBase64.c in Sources */, - BE1F74D31F609D460068FA64 /* SecFramework.c in Sources */, DCD66DB61D82050900DB1393 /* SecKey.c in Sources */, - DCD66DBC1D82052B00DB1393 /* SecKeyAdaptors.c in Sources */, + DCD66DBC1D82052B00DB1393 /* SecKeyAdaptors.m in Sources */, DCD66DBB1D82052700DB1393 /* SecPolicy.c in Sources */, DCD66DBA1D82052000DB1393 /* SecPolicyLeafCallbacks.c in Sources */, DCD66DB91D82051900DB1393 /* SecTrust.c in Sources */, DCD66DB71D82050E00DB1393 /* SecTrustStore.c in Sources */, - DCD66DB51D82050500DB1393 /* SecECKey.c in Sources */, + DCD66DB51D82050500DB1393 /* SecECKey.m in Sources */, DCD66DB41D82050000DB1393 /* SecRSAKey.c in Sources */, DCD66DB31D8204FB00DB1393 /* SecServerEncryptionSupport.c in Sources */, D425EC231DD3FFF200DE5DEC /* SecInternalRelease.c in Sources */, @@ -29290,7 +30947,6 @@ DCD8A1DB1E09F5D100E4FA0A /* SOSAccountTrust.m in Sources */, DCD8A1A11E09EF5C00E4FA0A /* SOSCloudKeychainConstants.c in Sources */, DCD8A1A91E09F04700E4FA0A /* SOSECWrapUnwrap.c in Sources */, - 0C4899251E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m in Sources */, DCD8A1BD1E09F1D600E4FA0A /* SOSFullPeerInfo.m in Sources */, DCD8A1B51E09F15400E4FA0A /* SOSGenCount.c in Sources */, DCD8A19F1E09EF0F00E4FA0A /* SOSInternal.m in Sources */, @@ -29302,10 +30958,8 @@ DCD8A1B11E09F11900E4FA0A /* SOSPeerInfoDER.m in Sources */, 0CE7604C1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m in Sources */, DCD8A1B21E09F11900E4FA0A /* SOSPeerInfoRingState.m in Sources */, - DCD8A1A71E09F01300E4FA0A /* SOSPeerInfoSecurityProperties.m in Sources */, 0CE7604E1E12F5BA00B4381E /* SOSAccountTrustClassic+Retirement.m in Sources */, DCD8A1A51E09EFAE00E4FA0A /* SOSPeerInfoV2.m in Sources */, - 0CE760481E12F2F300B4381E /* SOSAccountTrustClassic+Expansion.m in Sources */, DCD8A1C21E09F23B00E4FA0A /* SOSRecoveryKeyBag.m in Sources */, DCD8A1B81E09F1BB00E4FA0A /* SOSRingBackup.m in Sources */, DCD8A1B91E09F1BB00E4FA0A /* SOSRingBasic.m in Sources */, @@ -29319,7 +30973,6 @@ DCD8A1C71E09F2B400E4FA0A /* SOSTransport.m in Sources */, DCD8A1511E09EE0F00E4FA0A /* SOSViews.m in Sources */, DCD8A19E1E09EEDA00E4FA0A /* SecRecoveryKey.m in Sources */, - 0CE7604A1E12F30200B4381E /* SOSAccountTrustClassic+Circle.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -29401,6 +31054,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D49111302095154B0066A1E4 /* MainMenu.xib in Sources */, DCE4E8F71D7F3A1100AFB96E /* KDCirclePeer.m in Sources */, DCE4E8F91D7F3A1100AFB96E /* KDAppDelegate.m in Sources */, DCE4E8F81D7F3A1100AFB96E /* main.m in Sources */, @@ -29414,6 +31068,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D491112F2095154B0066A1E4 /* MainMenu.xib in Sources */, DCE4E92B1D7F3D7C00AFB96E /* KDSecCircle.m in Sources */, DCE4E92C1D7F3D7C00AFB96E /* KNPersistentState.m in Sources */, DCE4E9311D7F3D7C00AFB96E /* KDCirclePeer.m in Sources */, @@ -29703,6 +31358,50 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EB056E3A1FE5E390000A771E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0CC3775020ACA0DF00B58D2D /* SFSignInAnalytics.m in Sources */, + EBDD732C20A6A61E003A103A /* SOSAnalytics.m in Sources */, + EB056E451FE5E390000A771E /* DeviceSimulatorMain.m in Sources */, + EB056E431FE5E390000A771E /* DeviceSimulator.m in Sources */, + EBCE16171FE6DE5A002E7CCC /* SecdWatchdog.m in Sources */, + EBCE16181FE6DE5A002E7CCC /* SFSQLite.m in Sources */, + EBCE16191FE6DE5A002E7CCC /* SFSQLiteStatement.m in Sources */, + EBCE16201FE6DE5A002E7CCC /* SFAnalytics.m in Sources */, + EBCE16221FE6DE5A002E7CCC /* SFAnalyticsActivityTracker.m in Sources */, + EBCE16231FE6DE5A002E7CCC /* client_endpoint.m in Sources */, + EBCE162C1FE6DE5A002E7CCC /* client.c in Sources */, + EBCE162D1FE6DE5A002E7CCC /* SFAnalyticsSQLiteStore.m in Sources */, + EBCE162F1FE6DE5A002E7CCC /* SecTask.c in Sources */, + EBCE16311FE6DE5A002E7CCC /* SFAnalyticsMultiSampler.m in Sources */, + DC5B391C20C08BF1005B09F6 /* SecFramework.c in Sources */, + EBCE16321FE6DE5A002E7CCC /* SFAnalyticsSampler.m in Sources */, + EBCE16351FE6DE5A002E7CCC /* server_xpc.m in Sources */, + EBCE16361FE6DE5A002E7CCC /* server_security_helpers.c in Sources */, + 6C32BB9A20EAE6B80042DF59 /* LocalKeychainAnalytics.m in Sources */, + EBCE16371FE6DE5A002E7CCC /* server_endpoint.m in Sources */, + EBCE16391FE6DE5A002E7CCC /* spi.c in Sources */, + EBCE163A1FE6DE5A002E7CCC /* SFObjCType.m in Sources */, + EBCE163D1FE6DE5A002E7CCC /* server_entitlement_helpers.c in Sources */, + EBCE163E1FE6DE5A002E7CCC /* AutoreleaseTest.c in Sources */, + EBCE163F1FE6DE5A002E7CCC /* CKKSControl.m in Sources */, + EBCE16401FE6DE5A002E7CCC /* CKKSControlProtocol.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EB05C4ED1FE5E48A00D68712 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EBCE166C1FE746A5002E7CCC /* SecItemConstants.c in Sources */, + EB05C4F41FE5E48B00D68712 /* MultiDeviceSimulatorTests.m in Sources */, + 4885DCAD207FF0780071FB7B /* ClientInfoByNotification.m in Sources */, + EBCE16601FE732AA002E7CCC /* MultiDeviceNetworking.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EB0BC9371C3C791500785842 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -29764,19 +31463,29 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6C32BB9920EAE6B00042DF59 /* LocalKeychainAnalytics.m in Sources */, + 0CC3771320A222BC00B58D2D /* SFSignInAnalytics.m in Sources */, EB49B2E5202DFEB3003F34A0 /* mockaks.m in Sources */, EB49B2DB202DF20F003F34A0 /* spi.c in Sources */, EB49B2D7202DF1F7003F34A0 /* server_endpoint.m in Sources */, + EBC73F2020993F8600AE3350 /* SFAnalyticsSQLiteStore.m in Sources */, + EBC73F2720993FC900AE3350 /* SFAnalyticsMultiSampler.m in Sources */, EB49B2D8202DF1F7003F34A0 /* server_xpc.m in Sources */, + EBC73F2620993FA800AE3350 /* client_endpoint.m in Sources */, EB49B2D9202DF1F7003F34A0 /* server_security_helpers.c in Sources */, + EBC73F2B2099785900AE3350 /* SFObjCType.m in Sources */, EB49B2E0202DF5D7003F34A0 /* server_entitlement_helpers.c in Sources */, + EBC73F2A20996AD400AE3350 /* SFSQLiteStatement.m in Sources */, EB6667C7204CD69F000B404F /* testPlistDER.m in Sources */, + EBC73F29209966AF00AE3350 /* SFSQLite.m in Sources */, EB49B2D5202DF1D8003F34A0 /* SecTask.c in Sources */, EB49B2D4202DF1C1003F34A0 /* client.c in Sources */, EB49B2D3202DF1AC003F34A0 /* SecdWatchdog.m in Sources */, EB49B2B1202D8780003F34A0 /* secdmockaks.m in Sources */, + DC5B391B20C08BDC005B09F6 /* SecFramework.c in Sources */, EB49B2D1202DF15F003F34A0 /* SFAnalyticsActivityTracker.m in Sources */, EB49B2D0202DF14D003F34A0 /* SFAnalytics.m in Sources */, + EBC73F2820993FDA00AE3350 /* SFAnalyticsSampler.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -29860,6 +31569,16 @@ target = 0C2BCBBD1D0648D100ED7A2F /* dtlsEchoServer */; targetProxy = 0C2BCBD01D0648FA00ED7A2F /* PBXContainerItemProxy */; }; + 0C3E2EA92073F5C400F5B95B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C32C0AE0A4975F6002891BD /* Security_ios */; + targetProxy = 0C3E2EA82073F5C400F5B95B /* PBXContainerItemProxy */; + }; + 0C5663EE20BE2E1A0035F362 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 0C5663ED20BE2E1A0035F362 /* PBXContainerItemProxy */; + }; 0C664AB41759270C0092D3D9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 0C0BDB2E175685B000BC1A7E /* secdtests_ios */; @@ -29910,6 +31629,11 @@ target = 0C6799F912F7C37C00712919 /* dtlsTests */; targetProxy = 0C99B73F131C984900584CF4 /* PBXContainerItemProxy */; }; + 0C9AEEBA20783FE000BF6237 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC1789031D77980500B50D50 /* Security_osx */; + targetProxy = 0C9AEEB920783FE000BF6237 /* PBXContainerItemProxy */; + }; 0CC827F2138712B100BD99B7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E710C7411331946400F85568 /* SecurityTests */; @@ -29930,11 +31654,71 @@ target = DCD06AA91D8E0D53007602F1 /* security_utilities */; targetProxy = 226A8B441DEF58EE004C35E3 /* PBXContainerItemProxy */; }; + 3DD1FEF8201C07F30086D049 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 3DD1FEF9201C07F30086D049 /* PBXContainerItemProxy */; + }; + 3DD1FF50201C09CD0086D049 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BC9C81D8B824700070CB0 /* security_ssl */; + targetProxy = 3DD1FF4F201C09CD0086D049 /* PBXContainerItemProxy */; + }; + 3DD1FFAF201FDB1D0086D049 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BC9C81D8B824700070CB0 /* security_ssl */; + targetProxy = 3DD1FFB0201FDB1D0086D049 /* PBXContainerItemProxy */; + }; + 3DD1FFB1201FDB1D0086D049 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 3DD1FFB2201FDB1D0086D049 /* PBXContainerItemProxy */; + }; 438169E71B4EE4B300C54D58 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4381690B1B4EDCBD00C54D58 /* SOSCCAuthPlugin */; targetProxy = 438169E61B4EE4B300C54D58 /* PBXContainerItemProxy */; }; + 4718AE03205B39620068EC3F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 4718AE04205B39620068EC3F /* PBXContainerItemProxy */; + }; + 4718AE05205B39620068EC3F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = 4718AE06205B39620068EC3F /* PBXContainerItemProxy */; + }; + 4718AE09205B39620068EC3F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = 4718AE0A205B39620068EC3F /* PBXContainerItemProxy */; + }; + 4718AE0B205B39620068EC3F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = 4718AE0C205B39620068EC3F /* PBXContainerItemProxy */; + }; + 4718AE0D205B39620068EC3F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52EC3E1D80D00800B0A59C /* libSWCAgent */; + targetProxy = 4718AE0E205B39620068EC3F /* PBXContainerItemProxy */; + }; + 4718AEE6205B3A350068EC3F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4718AE2E205B39C40068EC3F /* libsecurityd_bridge */; + targetProxy = 4718AEE5205B3A350068EC3F /* PBXContainerItemProxy */; + }; + 47455B24205B3E2F008FE980 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4718AE02205B39620068EC3F /* securityd_bridge */; + targetProxy = 47455B23205B3E2F008FE980 /* PBXContainerItemProxy */; + }; + 4771D982209A76B100BA9772 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4771D971209A755800BA9772 /* KeychainDataclassOwner */; + targetProxy = 4771D981209A76B100BA9772 /* PBXContainerItemProxy */; + }; 478D426D1FD72A8100CAB645 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC52EDA61D80D58400B0A59C /* secdRegressions */; @@ -29945,31 +31729,61 @@ target = DC0BCBD91D8C648C00070CB0 /* regressionBase */; targetProxy = 478D42701FD72A8100CAB645 /* PBXContainerItemProxy */; }; - 478D42711FD72A8100CAB645 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; - targetProxy = 478D42721FD72A8100CAB645 /* PBXContainerItemProxy */; - }; 478D42731FD72A8100CAB645 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCC78EA81D8088E200865A7C /* security */; targetProxy = 478D42741FD72A8100CAB645 /* PBXContainerItemProxy */; }; + 47A6FC6A206B461700BD6C54 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = 47A6FC69206B461700BD6C54 /* PBXContainerItemProxy */; + }; + 47A6FC6C206B462400BD6C54 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = 47A6FC6B206B462400BD6C54 /* PBXContainerItemProxy */; + }; + 47C2F18C2059CBEA0062DE30 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 47C2F1822059CB680062DE30 /* KeychainResources */; + targetProxy = 47C2F18B2059CBEA0062DE30 /* PBXContainerItemProxy */; + }; + 47C2F18E2059CBF40062DE30 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 47C2F1822059CB680062DE30 /* KeychainResources */; + targetProxy = 47C2F18D2059CBF40062DE30 /* PBXContainerItemProxy */; + }; + 47C2F1902059CBFC0062DE30 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 47C2F1822059CB680062DE30 /* KeychainResources */; + targetProxy = 47C2F18F2059CBFC0062DE30 /* PBXContainerItemProxy */; + }; + 47C2F1922059CC040062DE30 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 47C2F1822059CB680062DE30 /* KeychainResources */; + targetProxy = 47C2F1912059CC040062DE30 /* PBXContainerItemProxy */; + }; 47C51B8B1EEA657D0032D9E5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC1789031D77980500B50D50 /* Security_osx */; targetProxy = 47C51B8A1EEA657D0032D9E5 /* PBXContainerItemProxy */; }; + 47D991D020407F7E0078CAE2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4727FBB61F9918580003AE36 /* secdxctests_ios */; + targetProxy = 47D991CF20407F7E0078CAE2 /* PBXContainerItemProxy */; + }; + 47D991D720407F890078CAE2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 478D426C1FD72A8100CAB645 /* secdxctests_mac */; + targetProxy = 47D991D620407F890078CAE2 /* PBXContainerItemProxy */; + }; 47DE88CE1FA7AD6200DD3254 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCC78EA81D8088E200865A7C /* security */; targetProxy = 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */; }; - 47DE88D51FA7AD7000DD3254 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; - targetProxy = 47DE88D41FA7AD7000DD3254 /* PBXContainerItemProxy */; - }; 47DE88D71FA7ADAC00DD3254 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC0BCBD91D8C648C00070CB0 /* regressionBase */; @@ -29980,6 +31794,16 @@ target = DC52EDA61D80D58400B0A59C /* secdRegressions */; targetProxy = 47DE88D81FA7ADBB00DD3254 /* PBXContainerItemProxy */; }; + 4809F7AE2061B6AA003E72D0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB056E3D1FE5E390000A771E /* DeviceSimulator */; + targetProxy = 4809F7AD2061B6AA003E72D0 /* PBXContainerItemProxy */; + }; + 4809F7B02061B6B0003E72D0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB05C4F01FE5E48A00D68712 /* MultiDeviceSimulatorTests */; + targetProxy = 4809F7AF2061B6B0003E72D0 /* PBXContainerItemProxy */; + }; 4C52D0EE16EFCD720079966E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4C52D0B316EFC61E0079966E /* CircleJoinRequested */; @@ -30210,11 +32034,6 @@ target = BEF88C271EAFFC3F00357577 /* TrustedPeers */; targetProxy = BEF88C321EAFFC3F00357577 /* PBXContainerItemProxy */; }; - CD0637811A840C6400C81E74 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = CD276C261A83F60C003226BC /* KeychainSyncingOverIDSProxy */; - targetProxy = CD6130ED1DA1C0CC00E1E42F /* PBXContainerItemProxy */; - }; D40B6A7F1E2B5F3D00CD6EE5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = D4ADA3181E2B41670031CEA3 /* libtrustd */; @@ -30385,6 +32204,11 @@ target = DA30D6751DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */; targetProxy = DA30D6811DF8C93500EC6B43 /* PBXContainerItemProxy */; }; + DAE40BD520CF3ED5002D5674 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DAE40BC520CF3E46002D5674 /* secitemcanarytest */; + targetProxy = DAE40BD420CF3ED5002D5674 /* PBXContainerItemProxy */; + }; DC0067901D878132005AF8DB /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC6A82911D87749900418608 /* securityd_client_macos */; @@ -30690,6 +32514,11 @@ target = DC1789031D77980500B50D50 /* Security_osx */; targetProxy = DC178BF21D77ABE300B50D50 /* PBXContainerItemProxy */; }; + DC193C6020CB4C9D009C1A0F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = libsecurity_cms_regressions; + targetProxy = DC193C5F20CB4C9D009C1A0F /* PBXContainerItemProxy */; + }; DC222C791E034EE700B09171 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */; @@ -30930,11 +32759,6 @@ target = DC0BCC211D8C684F00070CB0 /* utilities */; targetProxy = DC65E72E1D8CB32400152EF0 /* PBXContainerItemProxy */; }; - DC65E7331D8CB34000152EF0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = DC65E7321D8CB34000152EF0 /* PBXContainerItemProxy */; - }; DC65E7391D8CB38300152EF0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCB3417B1D8A2B860054D16E /* security_cdsa_utilities */; @@ -31560,11 +33384,6 @@ target = E7D847C41C6BE9710025BB44 /* KeychainCircle */; targetProxy = E7D847D01C6BE9720025BB44 /* PBXContainerItemProxy */; }; - E7E7B24B1BFC0CD900B1E66B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = CD276C261A83F60C003226BC /* KeychainSyncingOverIDSProxy */; - targetProxy = CD6130EC1DA1C0CC00E1E42F /* PBXContainerItemProxy */; - }; EB0D30FA1EF12BFB00C3C17D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E79EEDD21CD3F8AB00C2FBFC /* Security_tests_ios */; @@ -31585,6 +33404,21 @@ target = DC0BCC211D8C684F00070CB0 /* utilities */; targetProxy = EB108F201E6CE4D2003B0456 /* PBXContainerItemProxy */; }; + EB11965A20A6300600BFDA1B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */; + targetProxy = EB11965920A6300600BFDA1B /* PBXContainerItemProxy */; + }; + EB11965C20A6301100BFDA1B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */; + targetProxy = EB11965B20A6301100BFDA1B /* PBXContainerItemProxy */; + }; + EB11965E20A6302100BFDA1B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */; + targetProxy = EB11965D20A6302100BFDA1B /* PBXContainerItemProxy */; + }; EB1C4CA71E85883900404981 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; @@ -31665,6 +33499,26 @@ target = EBB839A41E29665D00853BAC /* secfuzzer */; targetProxy = EB58A0611E74C8E4009C10D7 /* PBXContainerItemProxy */; }; + EB636BCA20992D8900C1E21A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB49B2AD202D877F003F34A0 /* secdmockaks */; + targetProxy = EB636BC920992D8900C1E21A /* PBXContainerItemProxy */; + }; + EB636BD120992DA300C1E21A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB49B2AD202D877F003F34A0 /* secdmockaks */; + targetProxy = EB636BD020992DA300C1E21A /* PBXContainerItemProxy */; + }; + EB636BD320992DB400C1E21A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB49B2AD202D877F003F34A0 /* secdmockaks */; + targetProxy = EB636BD220992DB400C1E21A /* PBXContainerItemProxy */; + }; + EB636BD520992DC000C1E21A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB49B2AD202D877F003F34A0 /* secdmockaks */; + targetProxy = EB636BD420992DC000C1E21A /* PBXContainerItemProxy */; + }; EB63ADE11C3E74F900C45A69 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EB0BC9361C3C791500785842 /* secedumodetest */; @@ -31675,11 +33529,6 @@ target = 0C7CFA2E14E1BA4800DF9D95 /* Security_frameworks_ios */; targetProxy = EB6A6FAC1B90F84D0045DC68 /* PBXContainerItemProxy */; }; - EB6A6FB31B90F89F0045DC68 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 790851B50CA9859F0083CC4D /* securityd_ios */; - targetProxy = EB6A6FB21B90F89F0045DC68 /* PBXContainerItemProxy */; - }; EB6A6FB91B90F8D70045DC68 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4C541F840F250BF500E508AE /* Security_executables_ios */; @@ -31695,6 +33544,36 @@ target = 4C32C0AE0A4975F6002891BD /* Security_ios */; targetProxy = EB6A6FBC1B90F9170045DC68 /* PBXContainerItemProxy */; }; + EB8910F120E0287600DE533F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4727FBB61F9918580003AE36 /* secdxctests_ios */; + targetProxy = EB8910F020E0287600DE533F /* PBXContainerItemProxy */; + }; + EB8910F820E0287E00DE533F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4727FBB61F9918580003AE36 /* secdxctests_ios */; + targetProxy = EB8910F720E0287E00DE533F /* PBXContainerItemProxy */; + }; + EB8910FE20E06DF500DE533F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; + targetProxy = EB8910FD20E06DF500DE533F /* PBXContainerItemProxy */; + }; + EB89FAFE20DBDAA800085498 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; + targetProxy = EB89FAFD20DBDAA800085498 /* PBXContainerItemProxy */; + }; + EB89FB0020DBDAA800085498 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */; + targetProxy = EB89FAFF20DBDAA800085498 /* PBXContainerItemProxy */; + }; + EB89FB0220DBDAA800085498 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; + targetProxy = EB89FB0120DBDAA800085498 /* PBXContainerItemProxy */; + }; EB9C1DB71BDFD51800F89272 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; @@ -31735,6 +33614,31 @@ target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; targetProxy = EBC15EA81BE29AC3001C0C5B /* PBXContainerItemProxy */; }; + EBC73F52209A705A00AE3350 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; + targetProxy = EBC73F51209A705A00AE3350 /* PBXContainerItemProxy */; + }; + EBC73F5D209A739600AE3350 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; + targetProxy = EBC73F5C209A739600AE3350 /* PBXContainerItemProxy */; + }; + EBC73F64209A73A100AE3350 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */; + targetProxy = EBC73F63209A73A100AE3350 /* PBXContainerItemProxy */; + }; + EBC73F66209A73A100AE3350 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; + targetProxy = EBC73F65209A73A100AE3350 /* PBXContainerItemProxy */; + }; + EBCE15101FE638A2002E7CCC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB056E3D1FE5E390000A771E /* DeviceSimulator */; + targetProxy = EBCE150F1FE638A2002E7CCC /* PBXContainerItemProxy */; + }; EBCF743F1CE593A700BED7CA /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EBCF73F31CE45F9C00BED7CA /* secitemfunctionality */; @@ -31905,14 +33809,6 @@ name = SharedWebCredentials.strings; sourceTree = ""; }; - CD6130D61DA06FC600E1E42F /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - CD6130D71DA06FC600E1E42F /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; D479F6DF1F980F8F00388D28 /* Trust.strings */ = { isa = PBXVariantGroup; children = ( @@ -32075,10 +33971,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "secdtests/secdtests-entitlements.plist"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "LIBTRUSTD=1", "$(inherited)", @@ -32092,7 +33984,6 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_MOBILEASSET)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -32108,7 +33999,6 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -32122,10 +34012,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "secdtests/secdtests-entitlements.plist"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "LIBTRUSTD=1", "$(inherited)", @@ -32139,7 +34025,6 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_MOBILEASSET)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -32243,15 +34128,72 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", "$(inherited)", - "$(SDKROOT)/../../AppleInternal/Library/Frameworks", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "keychain/ot/tests/OTTests-Info.plist"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "-framework", + CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OTTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + USE_XCTRUNNER = YES; + }; + name = Debug; + }; + 0C85E0021FB38BB6000343A7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "$(inherited)", @@ -32263,6 +34205,112 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "-framework", + CrashReporterSupport, + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OTTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + USE_XCTRUNNER = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 0C8BBF061FCB446400580909 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "keychain/otctl/otctl-Entitlements.plist"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/local/bin; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 0C8BBF071FCB446400580909 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "keychain/otctl/otctl-Entitlements.plist"; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/local/bin; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 0C9AEEB520783FBB00BF6237 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "keychain/Signin Metrics/Resources/SFTMTests-Info.plist"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ( "$(APPLE_AKS_LIBRARY)", @@ -32300,13 +34348,13 @@ "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); - PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OTTests; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SFTMTests; PRODUCT_NAME = "$(TARGET_NAME)"; USE_XCTRUNNER = YES; }; name = Debug; }; - 0C85E0021FB38BB6000343A7 /* Release */ = { + 0C9AEEB620783FBB00BF6237 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -32316,18 +34364,13 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/../../AppleInternal/Library/Frameworks", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "$(inherited)", ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; - INFOPLIST_FILE = "keychain/ot/tests/OTTests-Info.plist"; + INFOPLIST_FILE = "keychain/Signin Metrics/Resources/SFTMTests-Info.plist"; INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; @@ -32369,51 +34412,137 @@ "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); - PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OTTests; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SFTMTests; PRODUCT_NAME = "$(TARGET_NAME)"; USE_XCTRUNNER = YES; VALIDATE_PRODUCT = YES; }; name = Release; }; - 0C8BBF061FCB446400580909 /* Debug */ = { + 0CF4064E2072E3E3003D6A7F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - CODE_SIGN_ENTITLEMENTS = "keychain/otctl/otctl-Entitlements.plist"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; + CODE_SIGN_IDENTITY = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - INSTALL_PATH = /usr/local/bin; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "keychain/Signin Metrics/Resources/SFTMTests-Info.plist"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "-framework", + CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SFTMTests; PRODUCT_NAME = "$(TARGET_NAME)"; + USE_XCTRUNNER = YES; }; name = Debug; }; - 0C8BBF071FCB446400580909 /* Release */ = { + 0CF4064F2072E3E3003D6A7F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - CODE_SIGN_ENTITLEMENTS = "keychain/otctl/otctl-Entitlements.plist"; - COPY_PHASE_STRIP = NO; - ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; + CODE_SIGN_IDENTITY = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - INSTALL_PATH = /usr/local/bin; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "keychain/Signin Metrics/Resources/SFTMTests-Info.plist"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "-framework", + CrashReporterSupport, + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SFTMTests; PRODUCT_NAME = "$(TARGET_NAME)"; + USE_XCTRUNNER = YES; + VALIDATE_PRODUCT = YES; }; name = Release; }; @@ -32515,6 +34644,148 @@ }; name = Release; }; + 3DD1FF4B201C07F30086D049 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)", + "$(HEADER_SYMLINKS)", + "$(SDKROOT)/usr/local/include/security_libDER", + "$(PROJECT_DIR)/OSX/libsecurity_asn1", + "$(inherited)", + ); + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework", + ); + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecureTransportTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 3DD1FF4C201C07F30086D049 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)", + "$(HEADER_SYMLINKS)", + "$(SDKROOT)/usr/local/include/security_libDER", + "$(PROJECT_DIR)/OSX/libsecurity_asn1", + "$(inherited)", + ); + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework", + ); + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecureTransportTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 3DD1FFCE201FDB1D0086D049 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)", + "$(HEADER_SYMLINKS)", + "$(SDKROOT)/usr/local/include/security_libDER", + "$(PROJECT_DIR)/OSX/libsecurity_asn1", + "$(inherited)", + ); + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework", + ); + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecureTransportTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 3DD1FFCF201FDB1D0086D049 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)", + "$(HEADER_SYMLINKS)", + "$(SDKROOT)/usr/local/include/security_libDER", + "$(PROJECT_DIR)/OSX/libsecurity_asn1", + "$(inherited)", + ); + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework", + ); + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecureTransportTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; 438169101B4EDCBD00C54D58 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -32583,6 +34854,174 @@ }; name = Release; }; + 4718AE2B205B39620068EC3F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = NO; + CLANG_ENABLE_OBJC_ARC = YES; + CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist; + GCC_PREPROCESSOR_DEFINITIONS = ( + "SECD_SERVER=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; + INSTALL_PATH = /usr/libexec; + LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=embedded][arch=*]" = ( + "$(OTHER_LDFLAGS)", + "-framework", + MobileKeyBag, + "-laks", + "-lACM", + "-ObjC", + "-lSystem", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "-framework", + CrashReporterSupport, + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( + "$(inherited)", + "-ObjC", + ); + PRODUCT_NAME = securityd; + STRIP_STYLE = debugging; + USE_HEADERMAP = NO; + WARNING_CFLAGS = ( + "$(inherited)", + "-Wno-error=modules-ambiguous-internal-linkage", + ); + }; + name = Debug; + }; + 4718AE2C205B39620068EC3F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = NO; + CLANG_ENABLE_OBJC_ARC = YES; + CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist; + GCC_PREPROCESSOR_DEFINITIONS = ( + "SECD_SERVER=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; + INSTALL_PATH = /usr/libexec; + LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=embedded][arch=*]" = ( + "$(OTHER_LDFLAGS)", + "-framework", + MobileKeyBag, + "-laks", + "-lACM", + "-lSystem", + "-ObjC", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "-framework", + CrashReporterSupport, + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( + "$(inherited)", + "-ObjC", + ); + PRODUCT_NAME = securityd; + STRIP_STYLE = debugging; + USE_HEADERMAP = NO; + WARNING_CFLAGS = ( + "$(inherited)", + "-Wno-error=modules-ambiguous-internal-linkage", + ); + }; + name = Release; + }; + 4718AEE0205B39C40068EC3F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + EXECUTABLE_PREFIX = ""; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 4718AEE1205B39C40068EC3F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + EXECUTABLE_PREFIX = ""; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 4727FBBC1F9918590003AE36 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -32594,6 +35033,7 @@ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = NO; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; @@ -32604,21 +35044,27 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_DYNAMIC_NO_PIC = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = secdxctests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "-L$(SDKROOT)/usr/local/lib", + "-laks", + "-laks_acl", + "-framework", + MobileKeyBag, + ); + "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( + "-L$(SDKROOT)/usr/local/lib", + "-laks_acl", + ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos.internal; - TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -32633,6 +35079,7 @@ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = NO; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; @@ -32644,20 +35091,26 @@ CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = secdxctests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "-L$(SDKROOT)/usr/local/lib", + "-laks", + "-laks_acl", + "-framework", + MobileKeyBag, + ); + "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( + "-L$(SDKROOT)/usr/local/lib", + "-laks_acl", + ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos.internal; - TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -32750,6 +35203,78 @@ }; name = Release; }; + 4771D976209A755800BA9772 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = NO; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/KeychainDataclassOwner/Info.plist; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Accounts/DataclassOwners"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainDataclassOwner; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos.internal; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 4771D977209A755800BA9772 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = NO; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_STYLE = Automatic; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/KeychainDataclassOwner/Info.plist; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Accounts/DataclassOwners"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainDataclassOwner; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos.internal; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; 478D429A1FD72A8100CAB645 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -32761,6 +35286,7 @@ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = NO; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; @@ -32771,20 +35297,15 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_DYNAMIC_NO_PIC = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = secdxctests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -32800,6 +35321,7 @@ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = NO; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; @@ -32811,24 +35333,85 @@ CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = secdxctests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; + 47C2F1882059CB690062DE30 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = NO; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/KeychainResources/Info.plist; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Keychain"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainResources; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 47C2F1892059CB690062DE30 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = NO; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_STYLE = Automatic; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/KeychainResources/Info.plist; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Keychain"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainResources; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; 47C51B8C1EEA657D0032D9E5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -32836,7 +35419,6 @@ CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_MODULES = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; @@ -32864,7 +35446,6 @@ CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_MODULES = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; @@ -32885,6 +35466,22 @@ }; name = Release; }; + 4809F7A52061B697003E72D0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 4809F7A62061B697003E72D0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 4C52D0BE16EFC61E0079966E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -32936,6 +35533,7 @@ "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); PRODUCT_NAME = "$(TARGET_NAME)"; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Debug; }; @@ -32978,6 +35576,7 @@ "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); PRODUCT_NAME = "$(TARGET_NAME)"; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -33016,10 +35615,6 @@ CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist"; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "LIBTRUSTD=1", "$(inherited)", @@ -33037,7 +35632,6 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33057,7 +35651,6 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33073,10 +35666,6 @@ CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist"; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "LIBTRUSTD=1", "$(inherited)", @@ -33094,7 +35683,6 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33114,7 +35702,6 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33411,10 +35998,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "secacltests/secacltests-entitlements.plist"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); INSTALL_PATH = /usr/local/bin; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -33456,10 +36039,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "secacltests/secacltests-entitlements.plist"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); INSTALL_PATH = /usr/local/bin; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -33501,19 +36080,14 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/../../AppleInternal/Library/Frameworks", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = "$(SRCROOT)/supd/Tests/Info.plist"; INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ( "-ObjC", @@ -33532,19 +36106,14 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/../../AppleInternal/Library/Frameworks", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = "$(SRCROOT)/supd/Tests/Info.plist"; INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( "-ObjC", @@ -33564,14 +36133,9 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "NO_LIBTRUSTD=1", @@ -33595,7 +36159,6 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33613,7 +36176,6 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33629,14 +36191,9 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "NO_LIBTRUSTD=1", @@ -33660,7 +36217,6 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33678,7 +36234,6 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33695,14 +36250,9 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "NO_LIBTRUSTD=1", @@ -33726,7 +36276,6 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33744,7 +36293,6 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33760,14 +36308,9 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "NO_LIBTRUSTD=1", @@ -33791,7 +36334,6 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33809,7 +36351,6 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -33833,7 +36374,6 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/supdctl/supdctl-Entitlements.plist"; @@ -33859,7 +36399,6 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/supdctl/supdctl-Entitlements.plist"; @@ -33886,15 +36425,10 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/supd/securityuploadd-Entitlements.plist"; CODE_SIGN_STYLE = Automatic; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_DYNAMIC_NO_PIC = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; INSTALL_PATH = /usr/libexec; @@ -33927,17 +36461,12 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/supd/securityuploadd-Entitlements.plist"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; INSTALL_PATH = /usr/libexec; "LAUNCHD_PLIST[sdk=iphoneos*]" = "$(SRCROOT)/supd/securityuploadd-ios.plist"; @@ -33970,8 +36499,8 @@ DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(SDKROOT)/../../Library/Frameworks", - "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + "$(PLATFORM_DIR)/Developer/AppleInternal/Library/Frameworks", ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; @@ -33999,8 +36528,8 @@ ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(SDKROOT)/../../Library/Frameworks", - "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + "$(PLATFORM_DIR)/Developer/AppleInternal/Library/Frameworks", ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -34188,6 +36717,7 @@ INFOPLIST_FILE = "Security-Info.plist"; INSTALLHDRS_SCRIPT_PHASE = YES; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks"; + IS_ZIPPERED = YES; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/local/lib/security_libDER", @@ -34222,6 +36752,7 @@ INFOPLIST_FILE = "Security-Info.plist"; INSTALLHDRS_SCRIPT_PHASE = YES; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks"; + IS_ZIPPERED = YES; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/local/lib/security_libDER", @@ -34261,7 +36792,6 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -34282,12 +36812,12 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = security; STRIP_STYLE = debugging; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Debug; }; @@ -34316,7 +36846,6 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -34330,12 +36859,12 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = security; STRIP_STYLE = debugging; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Release; }; @@ -34376,10 +36905,6 @@ CLANG_ENABLE_MODULES = NO; CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "SECD_SERVER=1", "$(inherited)", @@ -34395,7 +36920,6 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -34416,7 +36940,6 @@ "-framework", CrashReporterSupport, "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -34441,10 +36964,6 @@ CLANG_ENABLE_MODULES = NO; CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "SECD_SERVER=1", "$(inherited)", @@ -34460,7 +36979,6 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -34481,7 +36999,6 @@ "-framework", CrashReporterSupport, "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -34523,16 +37040,22 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_STATIC_ANALYZER_MODE = shallow; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = NO; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE; CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; @@ -34543,6 +37066,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS = "$(SRCROOT)/sslViewer/ecc-secp256r1-client.pfx"; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -34573,6 +37097,7 @@ HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = NO; INSTALL_DAEMON_AGENT_DIR = "$(SYSTEM_LIBRARY_DIR)/LaunchDaemons"; "INSTALL_DAEMON_AGENT_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/LaunchAgents"; + LLVM_LTO = YES_THIN; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; RUN_CLANG_STATIC_ANALYZER = YES; @@ -34599,16 +37124,22 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_STATIC_ANALYZER_MODE = shallow; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = NO; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE; CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; @@ -34618,6 +37149,7 @@ DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; + EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS = "$(SRCROOT)/sslViewer/ecc-secp256r1-client.pfx"; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = s; @@ -34648,6 +37180,7 @@ HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = NO; INSTALL_DAEMON_AGENT_DIR = "$(SYSTEM_LIBRARY_DIR)/LaunchDaemons"; "INSTALL_DAEMON_AGENT_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/LaunchAgents"; + LLVM_LTO = YES; OTHER_LDFLAGS = ""; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = macosx.internal; @@ -34963,90 +37496,6 @@ }; name = Release; }; - CD276C2D1A83F60C003226BC /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_ENTITLEMENTS = KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - "DEBUG_INFORMATION_FORMAT[sdk=macosx*]" = "dwarf-with-dsym"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/OSX/sec/SOSCircle/CKBridge", - ); - INFOPLIST_FILE = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist"; - INSTALL_PATH = "$(SECURITY_FRAMEWORK_RESOURCES_DIR)"; - MACH_O_TYPE = mh_execute; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = ( - "-laks", - "-ObjC", - ); - "OTHER_LDFLAGS[sdk=embeddedsimulator*]" = "-ObjC"; - PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.keychainsyncingoveridsproxy; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = NO; - STRIP_INSTALLED_PRODUCT = NO; - STRIP_STYLE = all; - WRAPPER_EXTENSION = bundle; - }; - name = Debug; - }; - CD276C2E1A83F60C003226BC /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_ENTITLEMENTS = KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - "DEBUG_INFORMATION_FORMAT[sdk=macosx*]" = "dwarf-with-dsym"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/OSX/sec/SOSCircle/CKBridge", - ); - INFOPLIST_FILE = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist"; - INSTALL_PATH = "$(SECURITY_FRAMEWORK_RESOURCES_DIR)"; - MACH_O_TYPE = mh_execute; - OTHER_LDFLAGS = ( - "-laks", - "-ObjC", - ); - "OTHER_LDFLAGS[sdk=embeddedsimulator*]" = "-ObjC"; - PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.keychainsyncingoveridsproxy; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = NO; - STRIP_STYLE = all; - VALIDATE_PRODUCT = YES; - WRAPPER_EXTENSION = bundle; - }; - name = Release; - }; D41257D71E9410A300781F23 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -35190,6 +37639,78 @@ }; name = Release; }; + DAE40BCC20CF3E46002D5674 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = RegressionTests/secitemcanarytest/secitemcanarytest.entitlements; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + }; + name = Debug; + }; + DAE40BCD20CF3E46002D5674 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = RegressionTests/secitemcanarytest/secitemcanarytest.entitlements; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; DC0067BE1D87876F005AF8DB /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */; @@ -35328,6 +37849,7 @@ "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)"; CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = NO; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; @@ -35357,6 +37879,7 @@ "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)"; CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = NO; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; @@ -35768,7 +38291,6 @@ baseConfigurationReference = D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_ENUM_CONVERSION = NO; CLANG_WARN_SUSPICIOUS_MOVES = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -35794,7 +38316,6 @@ baseConfigurationReference = D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_ENUM_CONVERSION = NO; CLANG_WARN_SUSPICIOUS_MOVES = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -35819,7 +38340,6 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -35839,7 +38359,6 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -35927,7 +38446,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -35952,7 +38470,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -35978,7 +38495,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36012,7 +38528,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36045,7 +38560,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36075,7 +38589,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36115,16 +38628,18 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); GCC_DYNAMIC_NO_PIC = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ( - "-laks", - "-lCrashReporterClient", - "-Wl,-upward_framework,Foundation", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(inherited)", ); SUPPORTS_TEXT_BASED_API = YES; TAPI_VERIFY_MODE = ErrorsAndWarnings; @@ -36151,15 +38666,17 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( - "-laks", - "-lCrashReporterClient", - "-Wl,-upward_framework,Foundation", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(inherited)", ); SUPPORTS_TEXT_BASED_API = YES; TAPI_VERIFY_MODE = ErrorsAndWarnings; @@ -36176,7 +38693,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36206,7 +38722,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36233,15 +38748,9 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/../../AppleInternal/Library/Frameworks", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "$(inherited)", @@ -36299,15 +38808,9 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/../../AppleInternal/Library/Frameworks", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "$(inherited)", @@ -36425,7 +38928,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36450,7 +38952,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36475,7 +38976,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36499,7 +38999,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36521,7 +39020,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36543,7 +39041,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36565,7 +39062,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36587,7 +39083,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36609,7 +39104,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36620,6 +39114,7 @@ GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; MTL_ENABLE_DEBUG_INFO = YES; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Debug; }; @@ -36631,7 +39126,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36642,6 +39136,7 @@ GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; MTL_ENABLE_DEBUG_INFO = NO; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Release; }; @@ -36653,7 +39148,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36676,7 +39170,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36700,7 +39193,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36723,7 +39215,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36745,7 +39236,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36767,7 +39257,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36789,7 +39278,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36811,7 +39299,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36833,7 +39320,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36855,7 +39341,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36878,7 +39363,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36901,7 +39385,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36924,7 +39407,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36947,7 +39429,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36969,7 +39450,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -36991,7 +39471,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -37170,6 +39649,10 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -37210,6 +39693,10 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -37318,10 +39805,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "LIBTRUSTD=1", "$(inherited)", @@ -37349,10 +39832,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "LIBTRUSTD=1", "$(inherited)", @@ -37659,7 +40138,6 @@ buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = NO; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -37680,7 +40158,6 @@ buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = NO; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -37733,7 +40210,6 @@ buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = NO; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -37755,7 +40231,6 @@ buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = NO; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -38654,7 +41129,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -38678,7 +41152,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -39014,7 +41487,6 @@ buildSettings = { "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_SYMBOLS_PRIVATE_EXTERN = YES; @@ -39047,7 +41519,6 @@ buildSettings = { "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_SYMBOLS_PRIVATE_EXTERN = YES; @@ -39082,7 +41553,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -39104,7 +41574,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -39126,7 +41595,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -39148,7 +41616,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -39171,7 +41638,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -39196,7 +41662,6 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -39221,12 +41686,12 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = security2; SUPPORTED_PLATFORMS = macosx; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Debug; }; @@ -39240,12 +41705,12 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = security2; SUPPORTED_PLATFORMS = macosx; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Release; }; @@ -39388,10 +41853,6 @@ CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist; CREATE_INFOPLIST_SECTION_IN_BINARY = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -39445,10 +41906,6 @@ CREATE_INFOPLIST_SECTION_IN_BINARY = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "SECD_SERVER=1", @@ -39757,6 +42214,7 @@ MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Debug; }; @@ -39798,6 +42256,7 @@ MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Release; }; @@ -39886,6 +42345,7 @@ APPLY_RULES_IN_COPY_FILES = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_STRICT_PROTOTYPES = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", @@ -39909,6 +42369,7 @@ APPLY_RULES_IN_COPY_FILES = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_STRICT_PROTOTYPES = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", @@ -40148,10 +42609,6 @@ CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist"; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "LIBTRUSTD=1", "$(inherited)", @@ -40167,7 +42624,6 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -40189,7 +42645,6 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "-framework", CrashReporterSupport, - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -40205,10 +42660,6 @@ CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist"; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "LIBTRUSTD=1", "$(inherited)", @@ -40224,7 +42675,6 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -40246,7 +42696,6 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "-framework", CrashReporterSupport, - "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -40472,6 +42921,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = KeychainCircle/Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; + IS_ZIPPERED = YES; MODULEMAP_FILE = Modules/KeychainCircle.modulemap; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -40516,6 +42966,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = KeychainCircle/Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; + IS_ZIPPERED = YES; MODULEMAP_FILE = Modules/KeychainCircle.modulemap; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "$(OTHER_LDFLAGS_MOBILEGESTALT)"; @@ -40681,6 +43132,228 @@ }; name = Release; }; + EB056E471FE5E391000A771E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_DYNAMIC_NO_PIC = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = MultiDeviceSimulator/DeviceSimulator/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "-ObjC", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "-ObjC", + "-framework", + CrashReporterSupport, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.DeviceSimulator; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + EB056E481FE5E391000A771E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = MultiDeviceSimulator/DeviceSimulator/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "-ObjC", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "-ObjC", + "-framework", + CrashReporterSupport, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.DeviceSimulator; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; + EB05C4F61FE5E48B00D68712 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.MultiDeviceSimulatorTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; + }; + name = Debug; + }; + EB05C4F71FE5E48B00D68712 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.MultiDeviceSimulatorTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; + }; + name = Release; + }; EB0BC93C1C3C791500785842 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; @@ -41457,21 +44130,17 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = dwarf; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_DYNAMIC_NO_PIC = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = tests/secdmockaks/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", @@ -41488,6 +44157,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.secdmockaks; PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; }; name = Debug; }; @@ -41506,21 +44176,17 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = tests/secdmockaks/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", @@ -41537,6 +44203,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.secdmockaks; PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; }; name = Release; }; @@ -42366,6 +45033,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 0C9AEEB420783FBB00BF6237 /* Build configuration list for PBXNativeTarget "SignInAnalyticsTests_osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0C9AEEB520783FBB00BF6237 /* Debug */, + 0C9AEEB620783FBB00BF6237 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0CF4064D2072E3E3003D6A7F /* Build configuration list for PBXNativeTarget "SignInAnalyticsTests_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0CF4064E2072E3E3003D6A7F /* Debug */, + 0CF4064F2072E3E3003D6A7F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 225394B11E3080A600D3CD9B /* Build configuration list for PBXNativeTarget "security_codesigning_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -42375,6 +45060,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 3DD1FF4A201C07F30086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_macos_tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3DD1FF4B201C07F30086D049 /* Debug */, + 3DD1FF4C201C07F30086D049 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3DD1FFCD201FDB1D0086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_ios_tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3DD1FFCE201FDB1D0086D049 /* Debug */, + 3DD1FFCF201FDB1D0086D049 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 438169381B4EDCBD00C54D58 /* Build configuration list for PBXNativeTarget "SOSCCAuthPlugin" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -42393,6 +45096,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4718AE2A205B39620068EC3F /* Build configuration list for PBXNativeTarget "securityd_bridge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4718AE2B205B39620068EC3F /* Debug */, + 4718AE2C205B39620068EC3F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4718AEDF205B39C40068EC3F /* Build configuration list for PBXNativeTarget "libsecurityd_bridge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4718AEE0205B39C40068EC3F /* Debug */, + 4718AEE1205B39C40068EC3F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 4727FBC31F9918590003AE36 /* Build configuration list for PBXNativeTarget "secdxctests_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -42420,6 +45141,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4771D97D209A755900BA9772 /* Build configuration list for PBXNativeTarget "KeychainDataclassOwner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4771D976209A755800BA9772 /* Debug */, + 4771D977209A755800BA9772 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 478D42991FD72A8100CAB645 /* Build configuration list for PBXNativeTarget "secdxctests_mac" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -42429,6 +45159,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 47C2F1872059CB690062DE30 /* Build configuration list for PBXNativeTarget "KeychainResources" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 47C2F1882059CB690062DE30 /* Debug */, + 47C2F1892059CB690062DE30 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 47C51B931EEA657D0032D9E5 /* Build configuration list for PBXNativeTarget "SecurityUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -42438,6 +45177,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4809F7AC2061B697003E72D0 /* Build configuration list for PBXAggregateTarget "MultiPeerSimulatorTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4809F7A52061B697003E72D0 /* Debug */, + 4809F7A62061B697003E72D0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 4C32C0B10A4975F7002891BD /* Build configuration list for PBXNativeTarget "Security_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -42708,15 +45456,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - CD276C2C1A83F60C003226BC /* Build configuration list for PBXNativeTarget "KeychainSyncingOverIDSProxy" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - CD276C2D1A83F60C003226BC /* Debug */, - CD276C2E1A83F60C003226BC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; D41257D61E9410A300781F23 /* Build configuration list for PBXNativeTarget "trustd_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -42762,6 +45501,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DAE40BCB20CF3E46002D5674 /* Build configuration list for PBXNativeTarget "secitemcanarytest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DAE40BCC20CF3E46002D5674 /* Debug */, + DAE40BCD20CF3E46002D5674 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DC0067BD1D87876F005AF8DB /* Build configuration list for PBXNativeTarget "securityd_server_macos" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -43788,6 +46536,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + EB056E4E1FE5E391000A771E /* Build configuration list for PBXNativeTarget "DeviceSimulator" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EB056E471FE5E391000A771E /* Debug */, + EB056E481FE5E391000A771E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EB05C4FD1FE5E48B00D68712 /* Build configuration list for PBXNativeTarget "MultiDeviceSimulatorTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EB05C4F61FE5E48B00D68712 /* Debug */, + EB05C4F71FE5E48B00D68712 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; EB0BC93B1C3C791500785842 /* Build configuration list for PBXNativeTarget "secedumodetest" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -43989,6 +46755,19 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCVersionGroup section */ + 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + 470D966C1FCDE4BA0065FE90 /* KeychainModel.xcdatamodel */, + ); + currentVersion = 470D966C1FCDE4BA0065FE90 /* KeychainModel.xcdatamodel */; + path = KeychainModel.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ }; rootObject = 4C35DB69094F906D002917C4 /* Project object */; } diff --git a/Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/B3656633-AB83-4153-B404-DE14DBDC5ED6.plist b/Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/B3656633-AB83-4153-B404-DE14DBDC5ED6.plist new file mode 100644 index 00000000..38f32efc --- /dev/null +++ b/Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/B3656633-AB83-4153-B404-DE14DBDC5ED6.plist @@ -0,0 +1,52 @@ + + + + + classNames + + ClientInfoByNotification + + testMaster2 + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 1.2728 + baselineIntegrationDisplayName + Local Baseline + + + testSOSIsThisDeviceInCircle + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.33445 + baselineIntegrationDisplayName + Local Baseline + + + testSOSMultiView + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 1.2679 + baselineIntegrationDisplayName + Local Baseline + + + testSOSViews2 + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.319 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/Info.plist b/Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/Info.plist new file mode 100644 index 00000000..50ad5a85 --- /dev/null +++ b/Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/Info.plist @@ -0,0 +1,33 @@ + + + + + runDestinationsByUUID + + B3656633-AB83-4153-B404-DE14DBDC5ED6 + + localComputer + + busSpeedInMHz + 100 + cpuCount + 1 + cpuKind + Intel Core i7 + cpuSpeedInMHz + 2600 + logicalCPUCoresPerPackage + 8 + modelCode + MacBookPro13,3 + physicalCPUCoresPerPackage + 4 + platformIdentifier + com.apple.platform.macosx + + targetArchitecture + x86_64 + + + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme index 822094ed..24511e3a 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme @@ -1,6 +1,6 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -57,7 +56,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Security.xcodeproj/xcshareddata/xcschemes/ios - Debug.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/ios - Debug.xcscheme index 87b2f010..890b62b0 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/ios - Debug.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/ios - Debug.xcscheme @@ -1,6 +1,6 @@ + + + + @@ -355,7 +363,11 @@ isEnabled = "NO"> + + + + + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/ios - secdtests.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/ios - secdtests.xcscheme index 92c639d2..eac30f4f 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/ios - secdtests.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/ios - secdtests.xcscheme @@ -1,6 +1,6 @@ + + + + + + + + - - @@ -321,6 +337,14 @@ argument = "si_32_sectrust_pinning_required" isEnabled = "NO"> + + + + @@ -341,6 +365,10 @@ argument = "si_44_seckey_aks" isEnabled = "NO"> + + @@ -413,6 +441,14 @@ argument = "si_88_sectrust_valid" isEnabled = "NO"> + + + + - - @@ -138,6 +134,10 @@ argument = "secd_62_account_backup" isEnabled = "NO"> + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/osx - sectests.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/osx - sectests.xcscheme index 0dbd5337..67510aa4 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/osx - sectests.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/osx - sectests.xcscheme @@ -1,6 +1,6 @@ @@ -60,7 +59,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/SecurityTests/si-88-sectrust-valid-data/ca-ki.pem b/SecurityTests/si-88-sectrust-valid-data/ca-ki.pem new file mode 100644 index 00000000..0c9b5858 --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/ca-ki.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEUDCCAzigAwIBAgIEGThNuTANBgkqhkiG9w0BAQsFADCBhzEeMBwGA1UEAwwV +VmFsaWQgVGVzdCBDQSBSb290IFYyMSIwIAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRl +c3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBsZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRp +bm8xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzAgFw0xNzA1MDEyMzE4MzBaGA8y +MTE3MDQwNzIzMTgzMFowgZ8xNjA0BgNVBAMMLUNBIHNlcmlhbCBpbnZhbGlkIGtu +b3duaW50ZXJtZWRpYXRlcyBjb21wbGV0ZTEiMCAGA1UECwwZVmFsaWQgUHJvamVj +dCBUZXN0IENBcyBWMjETMBEGA1UECgwKQXBwbGUgSW5jLjESMBAGA1UEBwwJQ3Vw +ZXJ0aW5vMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDJIAUwIWx3drEgTsVk2S8oLyB/Hg6TkFW8A2HlxnsO +RSrPaWLKsoU3jVWhwO2qZ8H98fknl32GJ71/zyWfJkNu3Rs7Nu2SpyG3nvdWCMOF +bLe5Zx2DOiYtjSC7LEAHLE4jL6GZcN9kGf8Rl4IjZnOTm/bEzQwLSuIlRPe6Dni5 +LkUj8Nk4EiN6QcJKZtFX2UUrYS3wvj+YOv3VzkaghhOiqpoFCnm3RuZnBo5+4wHV +lpG6NgHl4rnFmvwi3Vb6w1qevkf9uY2Q6SpXeTKz2J8l0hxaJ+Nti6wsaLXzag4h +fSpBf1BHXURHuuiI9UkaHQRO4eftsWxyhjgjLPDjCkqvAgMBAAGjgacwgaQwDgYD +VR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFBwLKWM0 +c67hVQOiXKrmAHltFX5VMB8GA1UdIwQYMBaAFLpW2Fdmvfxb4hDyObOvsnLtVQ8c +MD4GA1UdHwQ3MDUwM6AxoC+GLWh0dHA6Ly92YWxpZHRlc3QuYXBwbGUuZ2VvZmZr +Lm5ldC92Mi1yb290LmNybDANBgkqhkiG9w0BAQsFAAOCAQEAmOE9d6b0sU/y9mtM +NQF45CFyz1JXBMZTJ3ZxUW6LgG2L9DJFq684BmqcG0TAHFX9qOx3v45QZxWcGLZ5 +Ft8UeNqjDfTb2OM8weTY06d1TYY9XLK2utEnejxG0vp+UrKn7dsg/yPmoj/ffX5Z +qXSZUBxkhKwm0SVbtFSM2LM5VGmTcuOKYyJ/dNcx8/t/ccj2DhRR4K/2TKPjWUQH +sgh4jGZtXYVcjIsRBAbX8ZsdyvVQnLSB0bLdEH883OmFCo52wr9J53HMxQr6SdBE +RqUhDED847/nRqIRVLKLrfdZ6sBuXtpy1yIodbIfuYo7Ho0qgLyd/NruZebLRCPU +Sd4/DQ== +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/ca-unknown.pem b/SecurityTests/si-88-sectrust-valid-data/ca-unknown.pem new file mode 100644 index 00000000..c3af4792 --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/ca-unknown.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID1DCCArygAwIBAgIDEtaHMA0GCSqGSIb3DQEBCwUAMIGfMTYwNAYDVQQDDC1D +QSBzZXJpYWwgaW52YWxpZCBrbm93bmludGVybWVkaWF0ZXMgY29tcGxldGUxIjAg +BgNVBAsMGVZhbGlkIFByb2plY3QgVGVzdCBDQXMgVjIxEzARBgNVBAoMCkFwcGxl +IEluYy4xEjAQBgNVBAcMCUN1cGVydGlubzELMAkGA1UECAwCQ0ExCzAJBgNVBAYT +AlVTMB4XDTE4MDMwOTIwNTc1OVoXDTM2MDYwODIwNTc1OVowfTEXMBUGA1UEAwwO +VW5rbm93biBTdWIgQ0ExEzARBgNVBAoMCkFwcGxlIEluYy4xHzAdBgNVBAsMFlZh +bGlkIFByb2plY3QgVGVzdCBDQXMxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzES +MBAGA1UEBwwJQ3VwZXJ0aW5vMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAxnuV6JsM+4D8ScDqgtfG2wDA3QTyAC9uc222LNo72Qgn4QbGiuGSVCAUbL9v +pbms80InEPDwdOlBak645fPui9F7mtOqtyfhXZEdi7gpQ2UABusYfLf6jGwBhNY5 +uytGuE68RrIwUgAiOeNbCouM8+49vFCKby6O6VC6Cd6eKDVBDC3NQ84pWrCrc/tk +xDPEkZKmveRSKRoVFbl4auZ6sIFDI9sCPtZoUDIFBKtu3ViuP8HqL4BIRtaxeSZc +hm2ot46YkETdCkpCBWbpgZId9dNV85AzO7kasqnSDmCy7xWO2OOnlHRoCAYGbMZs +0RXEwsb0VOW/6TjF093isg6WowIDAQABozowODASBgNVHRMBAf8ECDAGAQH/AgEB +MA4GA1UdDwEB/wQEAwIBhjASBgNVHSUBAf8ECDAGBgRVHSUAMA0GCSqGSIb3DQEB +CwUAA4IBAQBga32SiOdPlLHJ2DyDX6MSJ9rW4Rak+xFyQFRbNdBqZNw16mAzifnD +W2HiLdZeXTUvHTNiJ9nXjtvdYzKcKlmYHxroF8P5E+MxrobNvrc+5ZEg+IDFnGEP +S3EwyfQp3Z3/Dkwy7gE/GTSo/G33vYydJY7jf9uSegoAViwRammXRLgr06Zp8/Jb +JJcrk806isUJcHkR/hUHMKUQehRWjMQ2/gdhlqf5/CsHU1DgQCQWent9Auo7WnRK +uOnptpx6cxSbBSmOoJz4242PvhH4rPNKV3+8crcZmz0IHE64Iv2qUc0ahe6I1Lg3 +t8Y/sPm9Hj3vzWQDgrAOTdaiKQIAGs8l +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/leaf-ki-ok1.pem b/SecurityTests/si-88-sectrust-valid-data/leaf-ki-ok1.pem new file mode 100644 index 00000000..ab627a3e --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/leaf-ki-ok1.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIEVFmpmjANBgkqhkiG9w0BAQsFADCBnzE2MDQGA1UEAwwt +Q0Egc2VyaWFsIGludmFsaWQga25vd25pbnRlcm1lZGlhdGVzIGNvbXBsZXRlMSIw +IAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBs +ZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNBMQswCQYDVQQG +EwJVUzAgFw0xNzA1MDEyMzE4MzFaGA8yMTE3MDQwNzIzMTgzMVowgaUxPDA6BgNV +BAMMM0xlYWYgc2VyaWFsIGludmFsaWQga25vd25pbnRlcm1lZGlhdGVzIGNvbXBs +ZXRlIG9rMTEiMCAGA1UECwwZVmFsaWQgUHJvamVjdCBUZXN0IENBcyBWMjETMBEG +A1UECgwKQXBwbGUgSW5jLjESMBAGA1UEBwwJQ3VwZXJ0aW5vMQswCQYDVQQIDAJD +QTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCu +cW/2bddC4ZOKKgn65zNufVK/wCM/ebnprHdB9tgEsu5Z8BEGO8ixWMr/5EdRp9TW +3tWUm93ckntuVBoOsHESyBEker3RnBWpAyHJkxwrgBCuBOep/idABD3Aqn0dzsh2 +UXQWwZS2ZL1Azs3BYijbxspRx5SLVg8kwfOSPVrfAWdv3VZUNJkBcKvQBchAdqCb +MK2K1UeRsAcsNJHqUHrCcGNoJNsi99JumHoUd0r39PdiI2LSFlxfQn8nkRFI6Z0v +L+b37KvvPlRqQgIaYtjHfUP8N0PSBMm+dJyOXYWBTO0a4WRYsedjq6GoKRCutfgK +KPGAZdObZTjXH8NMhK7jAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgeAMAwGA1Ud +EwEB/wQCMAAwHwYDVR0jBBgwFoAUHAspYzRzruFVA6JcquYAeW0VflUwZAYDVR0f +BF0wWzBZoFegVYZTaHR0cDovL3ZhbGlkdGVzdC5hcHBsZS5nZW9mZmsubmV0L3Yy +LXNlcmlhbC1pbnZhbGlkLWtub3duaW50ZXJtZWRpYXRlcy1jb21wbGV0ZS5jcmww +OQYIKwYBBQUHAQEELTArMCkGCCsGAQUFBzABhh1odHRwOi8va25vd24tYW5zd2Vy +LW9jc3Avb2NzcDANBgkqhkiG9w0BAQsFAAOCAQEAt/3xiKm+WlVXOuD/N9Tq/P0S +Q56j+pKki0w8RgPSgihRjgyxxAAIcWURvRejCVkP6VkX0eS0dv3UQc8Wy3kYu8lt +IZgpnZNwptlGSd0sweyjN20d4tpt969aSPUIYLlgSby9fQ7TI/sadYfsFrlWyQth +xXg5pTqnqQpUGlDDHYmihTepqx0gk0Az+0z+vXPozbfO9x7whfUUTNC4jvFyUEuP +82/M7KbjicwvDVu6Jyc8ZfLTw1laE4+w3KOrn5Ynm8sDh7gj66gV0L1IgSl3IO8h +7EhzaUJxXDpm21iPNTh21EbC1KmCa4oYUMENyp/Ec3x6m2qayMAmg7sEcoTX/A== +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/leaf-ki-revoked1.pem b/SecurityTests/si-88-sectrust-valid-data/leaf-ki-revoked1.pem new file mode 100644 index 00000000..91353031 --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/leaf-ki-revoked1.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIErzCCA5egAwIBAgIESpPvUDANBgkqhkiG9w0BAQsFADCBnzE2MDQGA1UEAwwt +Q0Egc2VyaWFsIGludmFsaWQga25vd25pbnRlcm1lZGlhdGVzIGNvbXBsZXRlMSIw +IAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBs +ZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNBMQswCQYDVQQG +EwJVUzAgFw0xNzA1MDEyMzE4MzFaGA8yMTE3MDQwNzIzMTgzMVowgaoxQTA/BgNV +BAMMOExlYWYgc2VyaWFsIGludmFsaWQga25vd25pbnRlcm1lZGlhdGVzIGNvbXBs +ZXRlIHJldm9rZWQxMSIwIAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYy +MRMwEQYDVQQKDApBcHBsZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNV +BAgMAkNBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAKayI84lr4zpbmuAf0URoM7QMRWjPF5eTtXbdz20yiWyQwYV6YWh7A9IEy5H +5pMwdZUoYcZhmFToP9EAZe67VHP/qIxB3IwRGy4OCsc/o+q0nIOkNSvXpgDtDuPD +u+mlVIE0wsxJ1VH9kP8RiX15KNG+yINVSypTAq2lelGub/gG+2Kx3HtprFnBBtU9 +ND9uAd2CaXJrzOnstc7gp78lJIvgPbhvGEydsToULCn0q3f05ix2zPCE1Eb+McuW +qaSdJvZUExIyVLy23wUlfAg+RMvdjZQk1KXqhAt5YsgYAd1jk6IMs4elN1RGPjfL +u5Hvixu4UmcGMXkxS5Wg+tSpxU8CAwEAAaOB4zCB4DAOBgNVHQ8BAf8EBAMCB4Aw +DAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBQcCyljNHOu4VUDolyq5gB5bRV+VTBk +BgNVHR8EXTBbMFmgV6BVhlNodHRwOi8vdmFsaWR0ZXN0LmFwcGxlLmdlb2Zmay5u +ZXQvdjItc2VyaWFsLWludmFsaWQta25vd25pbnRlcm1lZGlhdGVzLWNvbXBsZXRl +LmNybDA5BggrBgEFBQcBAQQtMCswKQYIKwYBBQUHMAGGHWh0dHA6Ly9rbm93bi1h +bnN3ZXItb2NzcC9vY3NwMA0GCSqGSIb3DQEBCwUAA4IBAQAT4czdt+80U/vnc1YT +66FDELYBfSCcJPtOHeBUWnpgHj0HEL4qpwC4rZeYi2SwnvfZuIIRMOnsH+HlhsHI +CXboHIj4kgay3AH5SohpdrdB5UOSiuBFW/Be0/6hvTI9pPz8k/SPFTGuFu9CWcaA +BDJy3+NyZi/FWbkVi+GbmZ+T9o/2Gf1ttzuiAbocvP8qC80VsSK1KcN5hgbj24bC +OUZ6ntHWoNtpW3rH9QtVa6DsMRJyhsotuAu3jLwwjqKp7DmBOIDmh24k+ZX0J/N+ +8TB3QLT0VMKxP8oBBl+H6DlcsrOV9xMNqxARHtt7mVmqDhqqUiY7USBpNA9SXy2n +HjA+ +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/leaf-unknown.pem b/SecurityTests/si-88-sectrust-valid-data/leaf-unknown.pem new file mode 100644 index 00000000..2e0c5de5 --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/leaf-unknown.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIDAbIHMA0GCSqGSIb3DQEBCwUAMH0xFzAVBgNVBAMMDlVu +a25vd24gU3ViIENBMRMwEQYDVQQKDApBcHBsZSBJbmMuMR8wHQYDVQQLDBZWYWxp +ZCBQcm9qZWN0IFRlc3QgQ0FzMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMxEjAQ +BgNVBAcMCUN1cGVydGlubzAeFw0xODAzMDkyMTAwMjBaFw0zNjA2MDYyMTAwMjBa +MIGHMSEwHwYDVQQDDBhMZWFmIGZyb20gVW5rbm93biBTdWIgQ0ExEzARBgNVBAoM +CkFwcGxlIEluYy4xHzAdBgNVBAsMFlZhbGlkIFByb2plY3QgVGVzdCBDQXMxCzAJ +BgNVBAgMAkNBMQswCQYDVQQGEwJVUzESMBAGA1UEBwwJQ3VwZXJ0aW5vMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxDNtFGlFe98xSVT+9RRYeOWp2ppi +yBloDCrxKegtm/jE8TrK3tCr0Bc2eTUn7uWHDuPlTSChdQ9Ty7ieYujx+7RIdPdp +BLCfSPxjyxKeqTnoUzYj7fZYKO9HGwS/VcTib/H6ucdTsF1qBdEKuXgPS21XH6HM +P50bfkyEhP7rWd479GIfzB3vVC36q5qk60oVadntOmFw2rNm8Oxw3XfI6rYhbIJv +Mz9M+buXKS0wA5TCHBPYHZkF2W2IWzPPppE7Kg+skKUD+tz990dCt1/yU4iyFWlc +1F79VFx+SAa8pMMpMPKmJjEArtH5Vndgf/9+G95XJpcqhuaPz0PrlGhXKQIDAQAB +oyYwJDAOBgNVHQ8BAf8EBAMCB4AwEgYDVR0lAQH/BAgwBgYEVR0lADANBgkqhkiG +9w0BAQsFAAOCAQEAsaWTLZo0Xm4xa0zdRshyuYAT/NiRFnmxcRjcGlPIPfaqAmPE +faz42DhIBOWQu/yC17VommNm8SSLNRmlCKSw0kuJLWvxyw1nYKJnAmJNboiQH5V4 +Rg6qMMm/uCfx1kkZBG5NyF589JMpJ/p1Fd7uI9BDBvolG5wDzRHmCe509F/La2Lw +Kw9xBHCe2yFn4QnZt/S3ZWB8ObHK2/jyFNlMhSsdXr9KmhNxnI0SZqE7guQ6CeEa +FBd6KbEqLXiUyQyZifKIiGOiDyinDNEJ6bHRuhdE4JNw3R7YF/dBcZgcgHoBJ4JC +U7/3SY9cxAXc4p6Y/pSs7eISTcXKivgbn4Arow== +-----END CERTIFICATE----- diff --git a/SecurityTool/authz.c b/SecurityTool/authz.c index fa88c365..00208dd4 100644 --- a/SecurityTool/authz.c +++ b/SecurityTool/authz.c @@ -510,6 +510,7 @@ int authorize(int argc, char * const *argv) { int ch; + int retval = 1; OSStatus status; Boolean user_interaction_allowed = FALSE, extend_rights = TRUE; @@ -582,7 +583,12 @@ authorize(int argc, char * const *argv) (least_privileged ? kAuthorizationFlagLeastPrivileged : 0); // set up AuthorizationRightSet - AuthorizationItem rights[argc]; + AuthorizationItem *rights = malloc(argc * sizeof(AuthorizationItem)); + if (!rights) { + fprintf(stderr, "Out of memory\n"); + retval = 1; + goto bail; + } memset(rights, '\0', argc * sizeof(AuthorizationItem)); AuthorizationItemSet rightset = { argc, rights }; while (argc > 0) @@ -594,14 +600,18 @@ authorize(int argc, char * const *argv) if (internalize) { auth_ref = read_auth_ref_from_stdin(); - if (!auth_ref) - return 1; + if (!auth_ref) { + retval = 1; + goto bail; + } } if (!auth_ref && AuthorizationCreate(NULL, NULL, (least_privileged ? kAuthorizationFlagLeastPrivileged : 0), - &auth_ref)) - return -1; + &auth_ref)) { + retval = -1; + goto bail; + } // prepare environment if needed AuthorizationEnvironment *envp = NULL; @@ -609,8 +619,10 @@ authorize(int argc, char * const *argv) if (!login) login = getlogin(); char *pass = getpass("Password:"); - if (!(login && pass)) - return 1; + if (!(login && pass)) { + retval = 1; + goto bail; + } static AuthorizationItem authenv[] = { { kAuthorizationEnvironmentUsername }, { kAuthorizationEnvironmentPassword }, @@ -664,7 +676,12 @@ authorize(int argc, char * const *argv) if (auth_ref) AuthorizationFree(auth_ref, destroy_rights ? kAuthorizationFlagDestroyRights : 0); - return (status ? -1 : 0); + retval = (status ? -1 : 0); +bail: + if (rights) + free(rights); + + return retval; } diff --git a/SecurityTool/keychain_find.c b/SecurityTool/keychain_find.c index c1ac19c6..a4cfeb57 100644 --- a/SecurityTool/keychain_find.c +++ b/SecurityTool/keychain_find.c @@ -492,6 +492,10 @@ do_keychain_delete_generic_password(CFTypeRef keychainOrArray, SecKeychainItemRef itemRef = NULL; void *passwordData = NULL; + if (!itemCreator && !itemType && !kind && !value && !comment && !label && !serviceName && !accountName) { + return SHOW_USAGE_MESSAGE; + } + itemRef = find_first_generic_password(keychainOrArray, itemCreator, itemType, @@ -584,6 +588,10 @@ do_keychain_delete_internet_password(CFTypeRef keychainOrArray, SecKeychainItemRef itemRef = NULL; void *passwordData = NULL; + if (!itemCreator && !itemType && !kind && !comment && !label && !serverName && !securityDomain && !accountName && !path && !port && !protocol && !authenticationType) { + return SHOW_USAGE_MESSAGE; + } + itemRef = find_first_internet_password(keychainOrArray, itemCreator, itemType, diff --git a/SecurityTool/srCdsaUtils.cpp b/SecurityTool/srCdsaUtils.cpp index 94b16769..59a98ae1 100644 --- a/SecurityTool/srCdsaUtils.cpp +++ b/SecurityTool/srCdsaUtils.cpp @@ -373,7 +373,7 @@ CSSM_RETURN srCspGenKeyPair(CSSM_CSP_HANDLE cspHand, CSSM_CC_HANDLE ccHand; CSSM_DATA keyLabelData; - keyLabelData.Data = (uint8 *)keyLabel, + keyLabelData.Data = (uint8 *)keyLabel; keyLabelData.Length = keyLabelLen; memset(pubKey, 0, sizeof(CSSM_KEY)); memset(privKey, 0, sizeof(CSSM_KEY)); diff --git a/SecurityTool/srCdsaUtils.h b/SecurityTool/srCdsaUtils.h index 770c9c8c..83e6ae26 100644 --- a/SecurityTool/srCdsaUtils.h +++ b/SecurityTool/srCdsaUtils.h @@ -55,18 +55,18 @@ extern CSSM_BOOL srCompareCssmData( void srPrintError(const char *op, CSSM_RETURN err); /* Init CSSM; returns CSSM_FALSE on error. Reusable. */ -extern CSSM_BOOL srCssmStartup(); +extern CSSM_BOOL srCssmStartup(void); /* Attach to CSP. Returns zero on error. */ extern CSSM_CSP_HANDLE srCspStartup( CSSM_BOOL bareCsp); // true ==> CSP, false ==> CSP/DL /* Attach to DL side of CSPDL. */ -extern CSSM_DL_HANDLE srDlStartup(); +extern CSSM_DL_HANDLE srDlStartup(void); /* Attach to CL, TP */ -extern CSSM_CL_HANDLE srClStartup(); -extern CSSM_TP_HANDLE srTpStartup(); +extern CSSM_CL_HANDLE srClStartup(void); +extern CSSM_TP_HANDLE srTpStartup(void); /* * Derive symmetric key using PBE. diff --git a/base/SecBase.h b/base/SecBase.h index f8808db6..f23881ec 100644 --- a/base/SecBase.h +++ b/base/SecBase.h @@ -30,28 +30,32 @@ // Truth table for following declarations: // -// TARGET_OS_OSX TARGET_OS_OSX TARGET_OS_IPHONE TARGET_OS_IPHONE -// SEC_IOS_ON_OSX SEC_IOS_ON_OSX -// =================================================================================================== -// SEC_OS_IPHONE 0 1 1 1 -// SEC_OS_IPHONE_INCLUDES 0 0 1 1 -// SEC_OS_OSX 1 0 0 0 -// SEC_OS_OSX_INCLUDES 1 1 0 0 +// TARGET_OS_OSX TARGET_OS_OSX TARGET_OS_IPHONE TARGET_OS_IPHONE TARGET_OS_IOSMAC +// SEC_IOS_ON_OSX SEC_IOS_ON_OSX +// ================================================================================================================= +// SEC_OS_IPHONE 0 1 1 1 1 +// SEC_OS_OSX 1 0 0 0 0 +// SEC_OS_OSX_INCLUDES 1 1 0 0 0 #if TARGET_OS_OSX #ifdef SEC_IOS_ON_OSX #define SEC_OS_IPHONE 1 - #define SEC_OS_IPHONE_INCLUDES 0 #define SEC_OS_OSX 0 #define SEC_OS_OSX_INCLUDES 1 #endif // SEC_IOS_ON_OSX #endif // TARGET_OS_OSX +#if TARGET_OS_IOSMAC + #define SEC_OS_IPHONE 1 + + #define SEC_OS_OSX 0 + #define SEC_OS_OSX_INCLUDES 0 +#endif // TARGET_OS_IOSMAC + #ifndef SEC_OS_IPHONE // block above did not fire; set flags to current platform #define SEC_OS_IPHONE TARGET_OS_IPHONE - #define SEC_OS_IPHONE_INCLUDES TARGET_OS_IPHONE #define SEC_OS_OSX TARGET_OS_OSX #define SEC_OS_OSX_INCLUDES TARGET_OS_OSX @@ -115,31 +119,30 @@ typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecPolicy) *SecPolicyRef; */ typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecAccessControl) *SecAccessControlRef; -#if SEC_OS_OSX_INCLUDES - /*! @typedef SecKeychainRef @abstract Contains information about a keychain. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychain) *SecKeychainRef; +typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychain) *SecKeychainRef + API_AVAILABLE(macos(10.0)) SPI_AVAILABLE(ios(1.0), tvos(9.0), watchos(1.0)); /*! @typedef SecKeychainItemRef @abstract Contains information about a keychain item. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychainItem) *SecKeychainItemRef; +typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychainItem) *SecKeychainItemRef API_UNAVAILABLE(ios); /*! @typedef SecKeychainSearchRef @abstract Contains information about a keychain search. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychainSearch) *SecKeychainSearchRef; +typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychainSearch) *SecKeychainSearchRef API_UNAVAILABLE(ios); /*! @typedef SecKeychainAttrType @abstract Represents a keychain attribute type. */ -typedef OSType SecKeychainAttrType; +typedef OSType SecKeychainAttrType API_UNAVAILABLE(ios); /*! @struct SecKeychainAttribute @@ -148,19 +151,19 @@ typedef OSType SecKeychainAttrType; @field length The length of the buffer pointed to by data. @field data A pointer to the attribute data. */ -struct SecKeychainAttribute +struct API_UNAVAILABLE(ios) SecKeychainAttribute { SecKeychainAttrType tag; UInt32 length; void * __nullable data; }; -typedef struct SecKeychainAttribute SecKeychainAttribute; +typedef struct SecKeychainAttribute SecKeychainAttribute API_UNAVAILABLE(ios); /*! @typedef SecKeychainAttributePtr @abstract Represents a pointer to a keychain attribute structure. */ -typedef SecKeychainAttribute *SecKeychainAttributePtr; +typedef SecKeychainAttribute *SecKeychainAttributePtr API_UNAVAILABLE(ios); /*! @typedef SecKeychainAttributeList @@ -168,42 +171,42 @@ typedef SecKeychainAttribute *SecKeychainAttributePtr; @field count An unsigned 32-bit integer that represents the number of keychain attributes in the array. @field attr A pointer to the first keychain attribute in the array. */ -struct SecKeychainAttributeList +struct API_UNAVAILABLE(ios) SecKeychainAttributeList { UInt32 count; SecKeychainAttribute * __nullable attr; }; -typedef struct SecKeychainAttributeList SecKeychainAttributeList; +typedef struct SecKeychainAttributeList SecKeychainAttributeList API_UNAVAILABLE(ios); /*! @typedef SecKeychainStatus @abstract Represents the status of a keychain. */ -typedef UInt32 SecKeychainStatus; +typedef UInt32 SecKeychainStatus API_UNAVAILABLE(ios); /*! @typedef SecTrustedApplicationRef @abstract Contains information about a trusted application. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrustedApplication) *SecTrustedApplicationRef; +typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrustedApplication) *SecTrustedApplicationRef API_UNAVAILABLE(ios); /*! @typedef SecAccessRef @abstract Contains information about an access. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecAccess) *SecAccessRef; +typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecAccess) *SecAccessRef API_UNAVAILABLE(ios); /*! @typedef SecACLRef @abstract Contains information about an access control list (ACL) entry. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrust) *SecACLRef; +typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrust) *SecACLRef API_UNAVAILABLE(ios); /*! @typedef SecPasswordRef @abstract Contains information about a password. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecPassword) *SecPasswordRef; +typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecPassword) *SecPasswordRef API_UNAVAILABLE(ios); /*! @typedef SecKeychainAttributeInfo @@ -213,15 +216,13 @@ typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecPassword) *SecPasswordRef; @field format A pointer to the first CSSM_DB_ATTRIBUTE_FORMAT in the array. @discussion Each tag and format item form a pair. */ -struct SecKeychainAttributeInfo +struct API_UNAVAILABLE(ios) SecKeychainAttributeInfo { UInt32 count; UInt32 *tag; UInt32 * __nullable format; }; -typedef struct SecKeychainAttributeInfo SecKeychainAttributeInfo; - -#endif // SEC_OS_OSX_INCLUDES +typedef struct SecKeychainAttributeInfo SecKeychainAttributeInfo API_UNAVAILABLE(ios); /*! @function SecCopyErrorMessageString diff --git a/base/SecBasePriv.h b/base/SecBasePriv.h index 40e33b3e..d2732607 100644 --- a/base/SecBasePriv.h +++ b/base/SecBasePriv.h @@ -94,12 +94,16 @@ enum errSecAuthNeeded = -25330, /* Auth is needed before the requested action can be performed. An array of constraints to be fulfilled is passed inside error.userInfo's 'cons' key. */ + + errSecPeersNotAvailable = -25336, /* No peers in the circle are available/online. */ + errSecErrorStringNotAvailable= -25337, /* Unable to load error string for error */ + + /* UNUSED enums */ errSecDeviceIDNeeded = -25332, /* Cannot send IDS messages without having our own IDS ID. */ errSecIDSNotRegistered = -25333, /* IDS is not set up or devices are not registered/available within an IDS account. */ errSecFailedToSendIDSMessage = -25334, /* Failed to send IDS message. */ errSecDeviceIDNoMatch = -25335, /* The provided device ID does not match any device IDs in the ids account. */ - errSecPeersNotAvailable = -25336, /* No peers in the circle are available/online. */ - errSecErrorStringNotAvailable= -25337, /* Unable to load error string for error */ + errSecTimedOut = -25336, /* Timed out waiting for task */ }; // Guard for CFNetwork @@ -120,7 +124,9 @@ OSStatus SecKeychainErrFromOSStatus(OSStatus osStatus) * * This only apply to MacOS where background session exists. */ -void _SecSetSecuritydTargetUID(uid_t uid); +void _SecSetSecuritydTargetUID(uid_t uid) + API_AVAILABLE(macos(10.13.5)) API_UNAVAILABLE(ios, iosmac, watchos, tvos, bridgeos); + __END_DECLS diff --git a/base/SecRandom.h b/base/SecRandom.h index 862d6103..0741e1d8 100644 --- a/base/SecRandom.h +++ b/base/SecRandom.h @@ -52,9 +52,25 @@ extern const SecRandomRef kSecRandomDefault /*! @function SecRandomCopyBytes - @abstract Return count random bytes in *bytes, allocated by the caller. - It is critical to check the return value for error + + @abstract + Return count random bytes in *bytes, allocated by the caller. It + is critical to check the return value for error. + + @param rnd + Only @p kSecRandomDefault is supported. + + @param count + The number of bytes to generate. + + @param bytes + A buffer to fill with random output. + @result Return 0 on success, any other value on failure. + + @discussion + If @p rnd is unrecognized or unsupported, @p kSecRandomDefault is + used. */ int SecRandomCopyBytes(SecRandomRef __nullable rnd, size_t count, void *bytes) __attribute__ ((warn_unused_result)) diff --git a/base/Security.apinotes b/base/Security.apinotes new file mode 100644 index 00000000..9ec2d091 --- /dev/null +++ b/base/Security.apinotes @@ -0,0 +1,8 @@ +Name: Security +SwiftVersions: + - Version: 4 + Functions: + - Name: SecTrustEvaluate + Parameters: + - Position: 1 + Nullability: O diff --git a/base/Security.h b/base/Security.h index 3fd993d4..c5c4914c 100644 --- a/base/Security.h +++ b/base/Security.h @@ -34,10 +34,9 @@ #include #include #include - -#if SEC_OS_IPHONE_INCLUDES #include -#endif +#include +#include #if SEC_OS_OSX_INCLUDES #include diff --git a/cssm/cssmapple.h b/cssm/cssmapple.h index 1cead1e6..293b4305 100644 --- a/cssm/cssmapple.h +++ b/cssm/cssmapple.h @@ -1080,7 +1080,7 @@ enum CSSM_CERT_STATUS_TRUST_SETTINGS_IGNORED_ERROR = 0x00000800 }; -typedef struct { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { CSSM_TP_APPLE_CERT_STATUS StatusBits; uint32 NumStatusCodes; CSSM_RETURN *StatusCodes; @@ -1096,7 +1096,7 @@ typedef struct { /* CRLReason code if cert is revoked */ sint32 CrlReason; #endif /* SEC_OS_IPHONE */ -} CSSM_TP_APPLE_EVIDENCE_INFO; +} CSSM_TP_APPLE_EVIDENCE_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; #if SEC_OS_OSX diff --git a/header_symlinks/Security/OTConstants.h b/header_symlinks/Security/OTConstants.h new file mode 120000 index 00000000..927ecd92 --- /dev/null +++ b/header_symlinks/Security/OTConstants.h @@ -0,0 +1 @@ +./../keychain/ot/OTConstants.h \ No newline at end of file diff --git a/header_symlinks/Security/SFSignInAnalytics.h b/header_symlinks/Security/SFSignInAnalytics.h new file mode 120000 index 00000000..fca39ae9 --- /dev/null +++ b/header_symlinks/Security/SFSignInAnalytics.h @@ -0,0 +1 @@ +./../keychain/Signin Metrics/SFSignInAnalytics.h \ No newline at end of file diff --git a/header_symlinks/Security/SecKeyProxy.h b/header_symlinks/Security/SecKeyProxy.h new file mode 120000 index 00000000..9356c2c8 --- /dev/null +++ b/header_symlinks/Security/SecKeyProxy.h @@ -0,0 +1 @@ +./../keychain/SecKeyProxy.h \ No newline at end of file diff --git a/header_symlinks/Security/SecProtocol.h b/header_symlinks/Security/SecProtocol.h new file mode 120000 index 00000000..191ce0ad --- /dev/null +++ b/header_symlinks/Security/SecProtocol.h @@ -0,0 +1 @@ +./../protocol/SecProtocol.h \ No newline at end of file diff --git a/header_symlinks/Security/SecProtocolMetadata.h b/header_symlinks/Security/SecProtocolMetadata.h new file mode 120000 index 00000000..caccc5d4 --- /dev/null +++ b/header_symlinks/Security/SecProtocolMetadata.h @@ -0,0 +1 @@ +./../protocol/SecProtocolMetadata.h \ No newline at end of file diff --git a/header_symlinks/Security/SecProtocolObject.h b/header_symlinks/Security/SecProtocolObject.h new file mode 120000 index 00000000..5effda4d --- /dev/null +++ b/header_symlinks/Security/SecProtocolObject.h @@ -0,0 +1 @@ +./../protocol/SecProtocolObject.h \ No newline at end of file diff --git a/header_symlinks/Security/SecProtocolOptions.h b/header_symlinks/Security/SecProtocolOptions.h new file mode 120000 index 00000000..2bbe2b3f --- /dev/null +++ b/header_symlinks/Security/SecProtocolOptions.h @@ -0,0 +1 @@ +./../protocol/SecProtocolOptions.h \ No newline at end of file diff --git a/header_symlinks/Security/SecProtocolTypes.h b/header_symlinks/Security/SecProtocolTypes.h new file mode 120000 index 00000000..b21e634d --- /dev/null +++ b/header_symlinks/Security/SecProtocolTypes.h @@ -0,0 +1 @@ +./../protocol/SecProtocolTypes.h \ No newline at end of file diff --git a/header_symlinks/Security/SecSharedCredential.h b/header_symlinks/Security/SecSharedCredential.h new file mode 120000 index 00000000..f1b330cf --- /dev/null +++ b/header_symlinks/Security/SecSharedCredential.h @@ -0,0 +1 @@ +./../keychain/SecSharedCredential.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecSharedCredential.h b/header_symlinks/macOS/Security/SecSharedCredential.h deleted file mode 120000 index 645d048c..00000000 --- a/header_symlinks/macOS/Security/SecSharedCredential.h +++ /dev/null @@ -1 +0,0 @@ -./../../keychain/SecSharedCredential.h \ No newline at end of file diff --git a/keychain/CoreDataKeychain/KeychainModel.xcdatamodeld/KeychainModel.xcdatamodel/contents b/keychain/CoreDataKeychain/KeychainModel.xcdatamodeld/KeychainModel.xcdatamodel/contents new file mode 100644 index 00000000..af687f71 --- /dev/null +++ b/keychain/CoreDataKeychain/KeychainModel.xcdatamodeld/KeychainModel.xcdatamodel/contents @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/keychain/CoreDataKeychain/SecCDKeychain.h b/keychain/CoreDataKeychain/SecCDKeychain.h new file mode 100644 index 00000000..cc2488d5 --- /dev/null +++ b/keychain/CoreDataKeychain/SecCDKeychain.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "SecKeybagSupport.h" + +#if !TARGET_OS_BRIDGE + +#if USE_KEYSTORE +#import +#import +#endif + +#import +#import +#import + +@class SecCDKeychainItemMetadata; +@class SecCDKeychainLookupTuple; +@class SecCDKeychainManagedItemType; +@class SecCDKeychainAccessControlEntity; +@class SFKeychainServerConnection; +@class SFAESKey; + +NS_ASSUME_NONNULL_BEGIN + +@class SecCDKeychainItem; + +@protocol SecCDKeychainLookupValueType +@end +typedef NSString SecCDKeychainLookupValueType; + +extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeString; +extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeData; +extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeNumber; +extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDate; +extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeArray; +extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDictionary; + +@interface SecCDKeychain : NSObject + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithStorageURL:(NSURL*)persistentStoreURL modelURL:(NSURL*)managedObjectURL encryptDatabase:(bool)encryptDatabase; + +- (void)insertItems:(NSArray*)items withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(bool success, NSError* _Nullable error))completionHandler; + +- (void)fetchItemForPersistentID:(NSUUID*)persistentID withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(SecCDKeychainItem* _Nullable item, NSError* _Nullable error))completionHandler; +- (void)fetchItemsWithValue:(NSString*)value forLookupKey:(NSString*)lookupKey ofType:(SecCDKeychainLookupValueType*)lookupValueType withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(NSArray* items, NSError* error))completionHandler; + +- (void)deleteItemWithPersistentID:(NSUUID*)persistentID withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(bool success, NSError* _Nullable error))completionHandler; + +@end + +@interface SecCDKeychainItemType : NSObject + +@property (readonly, copy) NSString* name; +@property (readonly) int32_t version; + +// for both primaryKeys and syncableKeys, nil means "all the attributes" +@property (readonly, copy, nullable) NSArray* primaryKeys; +@property (readonly, copy, nullable) NSArray* syncableKeys; + +@property (readonly) SecCDKeychainManagedItemType* managedItemType; + +// subclasses must override ++ (nullable instancetype)itemType; ++ (nullable instancetype)itemTypeForVersion:(int32_t)version; + +// to be called only by subclass implementations of +itemType +- (instancetype)_initWithName:(NSString*)name version:(int32_t)version primaryKeys:(nullable NSArray*)primaryKeys syncableKeys:(nullable NSArray*)syncableKeys; + +@end + +@interface SecCDKeychainItemMetadata : NSObject + +@property (readonly) SecCDKeychainItemType* itemType; +@property (readonly) SecCDKeychainAccessControlEntity* owner; +@property (readonly) NSUUID* persistentID; +@property (readonly, copy) NSDictionary* attributes; +@property (readonly, copy) NSArray* lookupAttributes; +@property (readonly) keyclass_t keyclass; + +- (instancetype)init NS_UNAVAILABLE; +- (void)fetchFullItemWithKeychain:(SecCDKeychain*)keychain withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(SecCDKeychainItem* _Nullable item, NSError* _Nullable error))completionHandler; + +@end + +@interface SecCDKeychainItem : NSObject + +@property (readonly) SecCDKeychainItemType* itemType; +@property (readonly) SecCDKeychainAccessControlEntity* owner; +@property (readonly) NSUUID* persistentID; +@property (readonly) NSDictionary* attributes; +@property (readonly) NSArray* lookupAttributes; +@property (readonly) keyclass_t keyclass; +@property (readonly) NSDictionary* secrets; + +@property (readonly) SecCDKeychainItemMetadata* metadata; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initItemType:(SecCDKeychainItemType*)itemType withPersistentID:(NSUUID*)persistentID attributes:(NSDictionary*)attributes lookupAttributes:(nullable NSArray*)lookupAttributes secrets:(NSDictionary*)secrets owner:(SecCDKeychainAccessControlEntity*)owner keyclass:(keyclass_t)keyclass; + +@end + +@interface SecCDKeychainLookupTuple : NSObject + +@property (readonly, copy) NSString* key; +@property (readonly, copy) id value; +@property (readonly, copy) SecCDKeychainLookupValueType* valueType; +@property (readonly, copy) NSString* stringRepresentation; + ++ (instancetype)lookupTupleWithKey:(NSString*)key value:(id)value; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithKey:(NSString*)key value:(id)value; + +@end + +typedef NS_ENUM(NSInteger, SecCDKeychainAccessControlEntityType) { + SecCDKeychainAccessControlEntityTypeAccessGroup = 0, +}; + +@interface SecCDKeychainAccessControlEntity : NSObject + +@property (nonatomic, readonly) SecCDKeychainAccessControlEntityType entityType; +@property (nonatomic, readonly) NSString* stringRepresentation; + ++ (instancetype)accessControlEntityWithType:(SecCDKeychainAccessControlEntityType)type stringRepresentation:(NSString*)stringRepresentation; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +#if USE_KEYSTORE + +@protocol SecAKSRefKey + +@property (readonly) NSData* refKeyBlob; + +- (instancetype)initWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass; +- (instancetype)initWithBlob:(NSData*)blob keybag:(keybag_handle_t)keybag; + +- (nullable NSData*)wrappedDataForKey:(SFAESKey*)key; +- (nullable SFAESKey*)keyWithWrappedData:(NSData*)wrappedKeyData; + +@end + +@interface SecAKSRefKey : NSObject +@end + +#endif // USE_KEYSTORE + +NS_ASSUME_NONNULL_END + +#endif // !TARGET_OS_BRIDGE diff --git a/keychain/CoreDataKeychain/SecCDKeychain.m b/keychain/CoreDataKeychain/SecCDKeychain.m new file mode 100644 index 00000000..e444b51f --- /dev/null +++ b/keychain/CoreDataKeychain/SecCDKeychain.m @@ -0,0 +1,1495 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import + +#if !TARGET_OS_BRIDGE + +#import "SecCDKeychain.h" +#import "SecCDKeychainManagedItem+CoreDataClass.h" +#import "SecCDKeychainManagedLookupEntry+CoreDataClass.h" +#import "SecCDKeychainManagedItemType+CoreDataClass.h" +#import "SecCDKeychainManagedAccessControlEntity+CoreDataClass.h" +#import "SecFileLocations.h" +#import "SecItemServer.h" +#import "SecItem.h" +#import "SecItemPriv.h" +#import "SecBase.h" +#import "SFKeychainServer.h" +#import "CloudKitCategories.h" +#import "securityd_client.h" +#import "SecKeybagSupport.h" +#import "SecKeybagSupport.h" +#import "keychain/categories/NSError+UsefulConstructors.h" +#import +#import +#import +#import +#import +#if USE_KEYSTORE +#import +#endif +#import +#import + +static NSString* const SecCDKeychainErrorDomain = @"com.apple.security.cdkeychain"; + +static NSString* const SecCDKeychainEntityLookupEntry = @"LookupEntry"; +static NSString* const SecCDKeychainEntityItem = @"Item"; +static NSString* const SecCDKeychainEntityItemType = @"ItemType"; +static NSString* const SecCDKeychainEntityTypeAccessControlEntity = @"AccessControlEntity"; + +static NSString* const SecCDKeychainItemMetadataSHA256 = @"SecCDKeychainItemMetadataSHA256"; + +static const NSInteger SecCDKeychainErrorDeserializing = 1; +static const NSInteger SecCDKeychainErrorInternal = 2; +//static const NSInteger SecCDKeychainErrorMetadataDoesNotMatch = 3; + +SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeString = (SecCDKeychainLookupValueType*)@"SecCDKeychainLookupValueTypeString"; +SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeData = (SecCDKeychainLookupValueType*)@"SecCDKeychainLookupValueTypeData"; +SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeNumber = (SecCDKeychainLookupValueType*)@"SecCDKeychainLookupValueTypeNumber"; +SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDate = (SecCDKeychainLookupValueType*)@"SecCDKeychainLookupValueTypeDate"; + +@interface SecCDKeychainItem () + +- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error; + +- (NSString*)primaryKeyStringRepresentationWithError:(NSError**)error; +- (NSData*)encryptedSecretDataWithAttributeData:(NSData*)attributeData keybag:(keybag_handle_t)keybag error:(NSError**)error; + +@end + +@interface SecCDKeychainItemMetadata () + +@property (readonly, copy) NSSet* lookupAttributesSet; +@property (readonly, copy) NSData* managedDataBlob; + +- (instancetype)initWithItemType:(SecCDKeychainItemType*)itemType persistentID:(NSUUID*)persistentID attributes:(NSDictionary*)attributes lookupAttributes:(NSArray*)lookupAttributes owner:(SecCDKeychainAccessControlEntity*)owner keyclass:(keyclass_t)keyclass; +- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error; + +@end + +@interface SecCDKeychainLookupTuple () + ++ (instancetype)lookupTupleWithManagedLookupEntry:(SecCDKeychainManagedLookupEntry*)lookupEntry; + +@end + +@interface SecCDKeychainItemType () + +- (SecCDKeychainManagedItemType*)managedItemTypeWithContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error; + +@end + +@interface SecCDKeychainAccessControlEntity () + +- (instancetype)initWithManagedEntity:(SecCDKeychainManagedAccessControlEntity*)managedAccessControlEntity; + +@end + +@interface SecCDKeychainItemWrappedSecretData : NSObject + +@property (readonly) SFAuthenticatedCiphertext* ciphertext; +@property (readonly) NSData* wrappedKeyData; +@property (readonly) NSData* refKeyBlob; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKeyData:(NSData*)wrappedKeyData refKeyBlob:(NSData*)refKeyBlob; + +@end + +@implementation SecCDKeychainItemWrappedSecretData { + SFAuthenticatedCiphertext* _ciphertext; + NSData* _wrappedKeyData; + NSData* _refKeyBlob; +} + +@synthesize ciphertext = _ciphertext; +@synthesize wrappedKeyData = _wrappedKeyData; +@synthesize refKeyBlob = _refKeyBlob; + ++ (BOOL)supportsSecureCoding +{ + return YES; +} + +- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKeyData:(NSData*)wrappedKeyData refKeyBlob:(NSData*)refKeyBlob +{ + if (self = [super init]) { + _ciphertext = ciphertext; + _wrappedKeyData = wrappedKeyData.copy; + _refKeyBlob = refKeyBlob.copy; + } + + return self; +} + +- (instancetype)initWithCoder:(NSCoder*)coder +{ + if (self = [super init]) { + _ciphertext = [coder decodeObjectOfClass:[SFAuthenticatedCiphertext class] forKey:@"SecCDKeychainItemCiphertext"]; + _wrappedKeyData = [coder decodeObjectOfClass:[NSData class] forKey:@"SecCDKeychainItemWrappedKey"]; + _refKeyBlob = [coder decodeObjectOfClass:[NSData class] forKey:@"SecCDKeychainItemRefKeyBlob"]; + + if (!_ciphertext || !_wrappedKeyData || !_refKeyBlob) { + self = nil; + secerror("SecCDKeychain: failed to deserialize wrapped secret data"); + [coder failWithError:[NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorDeserializing userInfo:@{NSLocalizedDescriptionKey : @"failed to deserialize wrapped secret data"}]]; + } + } + + return self; +} + +- (void)encodeWithCoder:(NSCoder*)coder +{ + [coder encodeObject:_ciphertext forKey:@"SecCDKeychainItemCiphertext"]; + [coder encodeObject:_wrappedKeyData forKey:@"SecCDKeychainItemWrappedKey"]; + [coder encodeObject:_refKeyBlob forKey:@"SecCDKeychainItemRefKeyBlob"]; +} + +@end + +#if USE_KEYSTORE + +@implementation SecAKSRefKey { + aks_ref_key_t _refKey; +} + +- (instancetype)initWithKeybag:(keyclass_t)keybag keyclass:(keyclass_t)keyclass +{ + if (self = [super init]) { + if (aks_ref_key_create(keybag, keyclass, key_type_sym, NULL, 0, &_refKey) != kAKSReturnSuccess) { + self = nil; + } + } + + return self; +} + +- (instancetype)initWithBlob:(NSData*)blob keybag:(keybag_handle_t)keybag +{ + if (self = [super init]) { + if (aks_ref_key_create_with_blob(keybag, blob.bytes, blob.length, &_refKey) != kAKSReturnSuccess) { + self = nil; + } + } + + return self; +} + +- (void)dealloc +{ + aks_ref_key_free(&_refKey); +} + +- (NSData*)wrappedDataForKey:(SFAESKey*)key +{ + void* wrappedKeyBytes = NULL; + size_t wrappedKeyLength = 0; + if (aks_ref_key_wrap(_refKey, NULL, 0, key.keyData.bytes, key.keyData.length, &wrappedKeyBytes, &wrappedKeyLength) == kAKSReturnSuccess) { + return [NSData dataWithBytesNoCopy:wrappedKeyBytes length:wrappedKeyLength]; + } + + return nil; +} + +- (SFAESKey*)keyWithWrappedData:(NSData*)wrappedKeyData +{ + void* unwrappedKeyBytes = NULL; + size_t unwrappedKeyLength = 0; + int aksResult = aks_ref_key_unwrap(_refKey, NULL, 0, wrappedKeyData.bytes, wrappedKeyData.length, &unwrappedKeyBytes, &unwrappedKeyLength); + if (aksResult != kAKSReturnSuccess || !unwrappedKeyBytes) { + return nil; + } + + NSData* keyData = [NSData dataWithBytesNoCopy:unwrappedKeyBytes length:unwrappedKeyLength]; + NSError* error = nil; + SFAESKey* key = [[SFAESKey alloc] initWithData:keyData specifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256] error:&error]; + if (!key) { + secerror("SecCDKeychain: error creating AES key from unwrapped item key data with error: %@", error); + } + + return key; +} + +- (NSData*)refKeyBlob +{ + size_t refKeyBlobLength = 0; + const uint8_t* refKeyBlobBytes = aks_ref_key_get_blob(_refKey, &refKeyBlobLength); + return [NSData dataWithBytes:refKeyBlobBytes length:refKeyBlobLength]; +} + +@end + +#endif // USE_KEYSTORE + +@implementation SecCDKeychain { + NSURL* _persistentStoreBaseURL; + NSPersistentStoreCoordinator* _persistentStoreCoordinator; + NSManagedObjectContext* _managedObjectContext; + NSMutableDictionary* _managedItemTypeDict; + NSMutableDictionary* _itemTypeDict; + bool _encryptDatabase; + dispatch_queue_t _queue; + NSArray* _classAPersistentStores; +} + ++ (SecCDKeychainLookupValueType*)lookupValueTypeForObject:(id)object +{ + if ([object isKindOfClass:[NSString class]]) { + return SecCDKeychainLookupValueTypeString; + } + else if ([object isKindOfClass:[NSData class]]) { + return SecCDKeychainLookupValueTypeData; + } + else if ([object isKindOfClass:[NSDate class]]) { + return SecCDKeychainLookupValueTypeDate; + } + else if ([object isKindOfClass:[NSNumber class]]) { + return SecCDKeychainLookupValueTypeNumber; + } + else { + return nil; + } +} + +- (instancetype)initWithStorageURL:(NSURL*)persistentStoreURL modelURL:(NSURL*)managedObjectURL encryptDatabase:(bool)encryptDatabase +{ + if (!persistentStoreURL) { + secerror("SecCDKeychain: no persistent store URL, so we can't create or open a database"); + return nil; + } + if (!managedObjectURL) { + secerror("SecCDKeychain: no managed object model URL, so we can't create or open a database"); + return nil; + } + + if (self = [super init]) { + _queue = dispatch_queue_create("SecCDKeychain", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + + _persistentStoreBaseURL = persistentStoreURL.copy; + _encryptDatabase = encryptDatabase; + + NSManagedObjectModel* managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:managedObjectURL]; + _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel]; + } + + return self; +} + +- (NSData*)_onQueueGetDatabaseKeyDataWithError:(NSError**)error +{ + NSData* keyData = nil; + NSDictionary* databaseKeyQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccessGroup : @"com.apple.security.securityd", + (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @(YES), + (id)kSecAttrService : @"com.apple.security.keychain.ak", + (id)kSecReturnData : @(YES) }; + + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)databaseKeyQuery, &result); + + if (status == errSecItemNotFound) { + NSMutableDictionary* addKeyQuery = databaseKeyQuery.mutableCopy; + [addKeyQuery removeObjectForKey:(id)kSecReturnData]; + + uint8_t* keyBytes = malloc(16); + if (SecRandomCopyBytes(NULL, 16, keyBytes) != 0) { + secerror("SecCDKeychain: failed to create random key for CD database encryption - this means we won't be able to create a database"); + if (error) { + *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"failed to create random key for CD database encryption"}]; + } + return nil; + } + + keyData = [NSData _newZeroingDataWithBytesNoCopy:keyBytes length:16 deallocator:nil]; + addKeyQuery[(id)kSecValueData] = keyData; + status = SecItemAdd((__bridge CFDictionaryRef)addKeyQuery, NULL); + if (status == errSecSuccess) { + return keyData; + } + else { + secerror("SecCDKeychain: failed to save encryption key to keychain, so bailing on database creation; status: %d", (int)status); + CFErrorRef cfError = NULL; + SecError(status, &cfError, CFSTR("failed to save encryption key to keychain, so bailing on database creation")); + if (error) { + *error = CFBridgingRelease(cfError); + cfError = NULL; + } + else { + CFReleaseNull(cfError); + } + return nil; + } + } + else if (status == errSecInteractionNotAllowed) { + //// add SFKeychainErrorDeviceLocked + + secerror("SecCDKeychain: can't create a class A store right now because the keychain is locked"); + CFErrorRef cfError = NULL; + SecError(status, &cfError, CFSTR("can't create a class A store right now because the keychain is locked")); + if (error) { + *error = CFBridgingRelease(cfError); + cfError = NULL; + } + else { + CFReleaseNull(cfError); + } + return nil; + } + else if (status == errSecSuccess) { + if ([(__bridge id)result isKindOfClass:[NSData class]]) { + return (__bridge_transfer NSData*)result; + } + else { + if (error) { + *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"result of keychain query for database key is wrong kind of class: %@", [(__bridge id)result class]]}]; + } + + CFReleaseNull(result); + return nil; + } + } + else { + secerror("failed to save or retrieve key for CD database encryption - this means we won't be able to create a database; status: %d", (int)status); + if (error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:@{NSLocalizedDescriptionKey : @"failed to save or retrieve key for CD database encryption"}]; + } + + CFReleaseNull(result); + return nil; + } +} + +- (NSManagedObjectContext*)_onQueueGetManagedObjectContextWithError:(NSError* __autoreleasing *)error +{ + dispatch_assert_queue(_queue); + + if (!_managedObjectContext) { + NSURL* akStoreURL = [_persistentStoreBaseURL URLByAppendingPathExtension:@"ak"]; + + NSData* keyData = [self _onQueueGetDatabaseKeyDataWithError:error]; + if (!keyData) { + return nil; + } + + if (_encryptDatabase) { + NSPersistentStore* classAStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:akStoreURL options:@{NSSQLiteSEEKeychainItemOption : keyData} error:error]; + _classAPersistentStores = @[classAStore]; + } + else { + NSPersistentStore* classAStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:akStoreURL options:nil error:error]; + _classAPersistentStores = @[classAStore]; + } + + NSManagedObjectContext* managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; + managedObjectContext.persistentStoreCoordinator = _persistentStoreCoordinator; + + // the first time around, setup our items types; grab old ones from the database and register any new ones + // we can skip for subsequent loads of the store in the same run of securityd + if (!_managedItemTypeDict || !_itemTypeDict) { + _managedItemTypeDict = [NSMutableDictionary dictionary]; + _itemTypeDict = [NSMutableDictionary dictionary]; + [managedObjectContext performBlockAndWait:^{ + NSFetchRequest* managedItemTypeFetchRequest = [SecCDKeychainManagedItemType fetchRequest]; + NSArray* managedItemTypes = [managedObjectContext executeFetchRequest:managedItemTypeFetchRequest error:error]; + if (managedItemTypes.count == 0) { + // TODO do some error handling here + } + else { + for (SecCDKeychainManagedItemType* managedItemType in managedItemTypes) { + NSMutableDictionary* itemTypeVersionDict = self->_managedItemTypeDict[managedItemType.name]; + if (!itemTypeVersionDict) { + itemTypeVersionDict = [NSMutableDictionary dictionary]; + self->_managedItemTypeDict[managedItemType.name] = itemTypeVersionDict; + } + itemTypeVersionDict[@(managedItemType.version)] = managedItemType; + } + } + + [self registerItemType:[SecCDKeychainItemTypeCredential itemType] withManagedObjectContext:managedObjectContext]; + }]; + } + + _managedObjectContext = managedObjectContext; + + int token = 0; + __weak __typeof(self) weakSelf = self; + notify_register_dispatch(kUserKeybagStateChangeNotification, &token, _queue, ^(int token) { + bool locked = true; + CFErrorRef error = NULL; + if (!SecAKSGetIsLocked(&locked, &error)) { + secerror("SecDbKeychainMetadataKeyStore: error getting lock state: %@", error); + CFReleaseNull(error); + } + + if (locked) { + [weakSelf _onQueueDropClassAPersistentStore]; + } + }); + } + + return _managedObjectContext; +} + +- (void)_onQueueDropClassAPersistentStore +{ + for (NSPersistentStore* store in _classAPersistentStores) { + NSError* error = nil; + if (![_persistentStoreCoordinator removePersistentStore:store error:&error]) { + secerror("SecCDKeychain: failed to remove persistent store with error: %@", error); + } + } + + _classAPersistentStores = nil; + _managedObjectContext = nil; + _persistentStoreCoordinator = nil; +} + +- (dispatch_queue_t)_queue +{ + return _queue; +} + +- (void)performOnManagedObjectQueue:(void (^)(NSManagedObjectContext* context, NSError* error))block +{ + __weak __typeof(self) weakSelf = self; + dispatch_async(_queue, ^{ + NSError* error = nil; + NSManagedObjectContext* context = [weakSelf _onQueueGetManagedObjectContextWithError:&error]; + if (context) { + [context performBlock:^{ + block(context, nil); + }]; + } + else { + if (!error) { + error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal description:@"unknown error retrieving managed object context"]; + } + block(nil, error); + } + }); +} + +- (void)performOnManagedObjectQueueAndWait:(void (^)(NSManagedObjectContext* context, NSError* error))block +{ + dispatch_sync(_queue, ^{ + NSError* error = nil; + NSManagedObjectContext* context = [self _onQueueGetManagedObjectContextWithError:&error]; + if (context) { + [context performBlockAndWait:^{ + block(context, nil); + }]; + } + else { + block(nil, error); + } + }); +} + +- (NSString*)primaryKeyNameForItemTypeName:(NSString*)itemTypeName +{ + return [NSString stringWithFormat:@"SecCDKeychain-PrimaryKey-%@", itemTypeName]; +} + +- (bool)validateItemOwner:(SecCDKeychainAccessControlEntity*)owner withConnection:(SFKeychainServerConnection*)connection withError:(NSError**)error +{ + // in the future we may support more owner types than just an access group, but for now, access group or bust + + NSError* localError = nil; + NSString* accessGroup = owner.entityType == SecCDKeychainAccessControlEntityTypeAccessGroup ? owner.stringRepresentation : nil; + if (accessGroup) { + if ([connection.clientAccessGroups containsObject:accessGroup]) { + return true; + } + else { + localError = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInvalidAccessGroup userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"client not in access group: %@", accessGroup]}]; + } + } + else { + localError = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorMissingAccessGroup userInfo:@{NSLocalizedDescriptionKey : @"keychain item missing access group"}]; + } + + if (error) { + *error = localError; + } + secerror("SecCDKeychain: failed to validate item owner with error: %@", localError); + return false; +} + +- (void)insertItems:(NSArray*)items withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(bool success, NSError* error))completionHandler +{ + __weak __typeof(self) weakSelf = self; + [self performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) { + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + secerror("SecCDKeychain: attempt to insert items into deallocated keychain instance"); + completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"attempt to insert items into deallocated keychain instance"}]); + return; + } + + if (!managedObjectContext) { + secerror("SecCDKeychain: insertItems: could not get managed object context"); + completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{ NSLocalizedDescriptionKey : @"insertItems: could not get managed object context", NSUnderlyingErrorKey : managedObjectError }]); + return; + } + + __block NSError* error = nil; + __block bool success = true; + for (SecCDKeychainItem* item in items) { + if (![self validateItemOwner:item.owner withConnection:connection withError:&error]) { + success = false; + break; + } + + NSString* itemTypeName = item.itemType.name; + NSString* primaryKeyValue = [item primaryKeyStringRepresentationWithError:&error]; + if (primaryKeyValue) { + NSFetchRequest* primaryKeyFetchRequest = [SecCDKeychainManagedLookupEntry fetchRequest]; + primaryKeyFetchRequest.predicate = [NSPredicate predicateWithFormat:@"lookupKey == %@ AND lookupValue == %@", [self primaryKeyNameForItemTypeName:itemTypeName], primaryKeyValue]; + SecCDKeychainManagedLookupEntry* managedLookupEntry = [[managedObjectContext executeFetchRequest:primaryKeyFetchRequest error:&error] firstObject]; + if (managedLookupEntry) { + secerror("SecCDKeychain: failed to unique item (%@) using primary keys: %@", item, item.itemType.primaryKeys); + success = false; + error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorDuplicateItem userInfo:@{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"failed to unique item (%@) using primary keys: %@", item, item.itemType.primaryKeys] }]; + break; + } + } + else { + secerror("SecCDKeychain: error creating primary key string representation for item: %@; error: %@", item, error); + success = false; + break; + } + + SecCDKeychainManagedItem* managedItem = [self managedItemWithItem:item withManagedObjectContext:managedObjectContext error:&error]; + if (!managedItem) { + secerror("SecCDKeychain: error creating managed item for insertion: %@; item: %@", error, item); + success = false; + break; + } + + // add a lookup entry for the primary key + SecCDKeychainManagedLookupEntry* primaryKeyLookupEntry = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityLookupEntry inManagedObjectContext:managedObjectContext]; + primaryKeyLookupEntry.itemTypeName = itemTypeName; + primaryKeyLookupEntry.lookupKey = [self primaryKeyNameForItemTypeName:itemTypeName]; + primaryKeyLookupEntry.lookupValue = primaryKeyValue; + primaryKeyLookupEntry.lookupValueType = SecCDKeychainLookupValueTypeString; + primaryKeyLookupEntry.systemEntry = YES; + [primaryKeyLookupEntry addMatchingItemsObject:managedItem]; + secdebug("SecCDKeychain", "added primary key: %@ value: %@", primaryKeyLookupEntry.lookupKey, primaryKeyLookupEntry.lookupValue); + + // and add lookup entries for all the things we're supposed to be able to lookup on + for (SecCDKeychainLookupTuple* lookupTuple in item.lookupAttributes) { + NSFetchRequest* lookupEntryFetchRequest = [SecCDKeychainManagedLookupEntry fetchRequest]; + lookupEntryFetchRequest.predicate = [NSPredicate predicateWithFormat:@"lookupKey == %@ AND lookupValueType == %@ AND lookupValue == %@", lookupTuple.key, lookupTuple.valueType, lookupTuple.value]; + SecCDKeychainManagedLookupEntry* lookupEntry = [[managedObjectContext executeFetchRequest:lookupEntryFetchRequest error:&error] firstObject]; + if (error) { + secerror("SecCDKeychain: error fetching lookup entry during item insertion: %@", (__bridge CFErrorRef)error); + success = false; + break; + } + else if (!lookupEntry) { + // we didn't get an error, but we didn't find a lookup entry + // that means there simply wasn't one in the db, so we should create one + lookupEntry = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityLookupEntry inManagedObjectContext:managedObjectContext]; + lookupEntry.itemTypeName = itemTypeName; + lookupEntry.lookupKey = lookupTuple.key; + lookupEntry.lookupValue = lookupTuple.stringRepresentation; + lookupEntry.lookupValueType = lookupTuple.valueType; + secdebug("SecCDKeychain", "added item for key (%@) : value (%@)", lookupEntry.lookupKey, lookupEntry.lookupValue); + } + + [lookupEntry addMatchingItemsObject:managedItem]; + } + + if (!success) { + break; + } + } + + if (success) { + secnotice("SecCDKeychain", "saving managed object context for items: %@", items); + success = [managedObjectContext save:&error]; + if (error) { + secerror("SecCDKeychain: saving managed object context failed with error: %@", error); + } + else { + secnotice("SecCDKeychain", "saving managed object context succeeded"); + } + } + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + completionHandler(success, error); + }); + }]; +} + +- (SecCDKeychainManagedItem*)fetchManagedItemForPersistentID:(NSUUID*)persistentID withManagedObjectContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error +{ + NSError* localError = nil; + NSFetchRequest* lookupEntryFetchRequest = [SecCDKeychainManagedItem fetchRequest]; + lookupEntryFetchRequest.predicate = [NSPredicate predicateWithFormat:@"persistentID == %@", persistentID]; + SecCDKeychainManagedItem* managedItem = [[managedObjectContext executeFetchRequest:lookupEntryFetchRequest error:&localError] firstObject]; + + if (error) { + *error = localError; + } + + return managedItem; +} + +- (void)fetchItemForPersistentID:(NSUUID*)persistentID withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(SecCDKeychainItem* item, NSError* error))completionHandler +{ + __weak __typeof(self) weakSelf = self; + [self performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) { + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + secerror("SecCDKeychain: attempt to fetch item from deallocated keychain instance"); + completionHandler(false, [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"attempt to fetch item from deallocated keychain instance"}]); + return; + } + + if (!managedObjectContext) { + secerror("SecCDKeychain: fetchItemForPersistentID: could not get managed object context"); + completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{ NSLocalizedDescriptionKey : @"fetchItemForPersistentID: could not get managed object context", NSUnderlyingErrorKey : managedObjectError }]); + return; + } + + NSError* error = nil; + SecCDKeychainItem* fetchedItem = nil; + SecCDKeychainManagedItem* managedItem = [self fetchManagedItemForPersistentID:persistentID withManagedObjectContext:managedObjectContext error:&error]; + if (error) { + secerror("SecCDKeychain: error fetching item for persistent id: %@; error: %@", persistentID, error); + } + else if (!managedItem) { + // we didn't get an error, but we didn't find an item + // that means there simply wasn't one in the db, so this lookup finds nothing + error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorItemNotFound userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"did not find any keychain items matching persistent ID: %@", persistentID.UUIDString]}]; + } + else { + fetchedItem = [[SecCDKeychainItem alloc] initWithManagedItem:managedItem keychain:self error:&error]; + if (!fetchedItem || error) { + secerror("SecCDKeychain: failed to create SecCDKeychainItem from managed item with error: %@", error); + fetchedItem = nil; + } + else if (![self validateItemOwner:fetchedItem.owner withConnection:connection withError:nil]) { // if we fail owner validation, we don't return an error; we pretend it didn't exist + fetchedItem = nil; + error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorItemNotFound userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"did not find any keychain items matching persistent ID: %@", persistentID.UUIDString]}]; + } + } + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + completionHandler(fetchedItem, error); + }); + }]; +} + +- (void)fetchItemsWithValue:(NSString*)value forLookupKey:(NSString*)lookupKey ofType:(SecCDKeychainLookupValueType*)lookupValueType withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(NSArray* items, NSError* error))completionHandler +{ + __weak __typeof(self) weakSelf = self; + [self performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) { + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + secerror("SecCDKeychain: attempt to fetch items from deallocated keychain instance"); + completionHandler(false, [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"attempt to lookup items from deallocated keychain instance"}]); + return; + } + + if (!managedObjectContext) { + secerror("SecCDKeychain: fetchItemsWithValue: could not get managed object context"); + completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{ NSLocalizedDescriptionKey : @"fetchItemsWithValue: could not get managed object context", NSUnderlyingErrorKey : managedObjectError }]); + return; + } + + NSError* error = nil; + NSMutableArray* fetchedItems = [[NSMutableArray alloc] init]; + NSFetchRequest* lookupEntryFetchRequest = [SecCDKeychainManagedLookupEntry fetchRequest]; + lookupEntryFetchRequest.predicate = [NSPredicate predicateWithFormat:@"lookupKey == %@ AND lookupValueType == %@ AND lookupValue == %@", lookupKey, lookupValueType, value]; + NSArray* lookupEntries = [managedObjectContext executeFetchRequest:lookupEntryFetchRequest error:&error]; + if (error) { + secerror("SecCDKeychain: error fetching lookup entry during item lookup: %@", error); + fetchedItems = nil; + } + else if (lookupEntries.count == 0) { + // we didn't get an error, but we didn't find a lookup entry + // that means there simply wasn't one in the db, so this lookup finds nothing + CFErrorRef cfError = NULL; + SecError(errSecItemNotFound, &cfError, CFSTR("did not find any keychain items matching query")); + error = CFBridgingRelease(cfError); + } + else { + for (SecCDKeychainManagedLookupEntry* lookupEntry in lookupEntries) { + for (SecCDKeychainManagedItem* item in lookupEntry.matchingItems) { + SecCDKeychainItemMetadata* fetchedItem = [[SecCDKeychainItemMetadata alloc] initWithManagedItem:item keychain:self error:&error]; + if (!fetchedItem || error) { + secerror("SecCDKeychain: failed to create SecCDKeychainItemMetadata from managed item with error: %@", error); + fetchedItems = nil; + break; + } + else if (![self validateItemOwner:fetchedItem.owner withConnection:connection withError:nil]) { // not an error; just pretend it's not there + continue; + } + + [fetchedItems addObject:fetchedItem]; + } + } + } + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + completionHandler(fetchedItems, error); + }); + }]; +} + +- (void)deleteItemWithPersistentID:(NSUUID*)persistentID withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(bool success, NSError* _Nullable error))completionHandler +{ + __weak __typeof(self) weakSelf = self; + [self performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) { + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + secerror("SecCDKeychain: attempt to fetch items from deallocated keychain instance"); + completionHandler(false, [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"attempt to insert items into deallocated keychain instance"}]); + return; + } + + if (!managedObjectContext) { + secerror("SecCDKeychain: deleteItemWithPersistentID: could not get managed object context"); + completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{ NSLocalizedDescriptionKey : @"deleteItemWIthPersistentID: could not get managed object context", NSUnderlyingErrorKey : managedObjectError }]); + return; + } + + NSError* error = nil; + SecCDKeychainManagedItem* managedItem = [self fetchManagedItemForPersistentID:persistentID withManagedObjectContext:managedObjectContext error:&error]; + bool success = false; + if (managedItem && !error) { + SecCDKeychainAccessControlEntity* owner = [[SecCDKeychainAccessControlEntity alloc] initWithManagedEntity:managedItem.owner]; + if ([self validateItemOwner:owner withConnection:connection withError:nil]) { // don't pass error here because we will treat it below as simply "item could not be found" + for (SecCDKeychainManagedLookupEntry* lookupEntry in managedItem.lookupEntries.copy) { + [lookupEntry removeMatchingItemsObject:managedItem]; + if (lookupEntry.matchingItems.count == 0) { + [managedObjectContext deleteObject:lookupEntry]; + } + } + + SecCDKeychainManagedAccessControlEntity* managedOwner = managedItem.owner; + [managedOwner removeOwnedItemsObject:managedItem]; + [managedOwner removeAccessedItemsObject:managedItem]; + if (managedOwner.ownedItems.count == 0 && managedOwner.accessedItems == 0) { + [managedObjectContext deleteObject:managedOwner]; + } + + for (SecCDKeychainManagedAccessControlEntity* accessControlEntity in managedItem.accessControlList) { + [accessControlEntity removeAccessedItemsObject:managedItem]; + if (accessControlEntity.ownedItems.count == 0 && accessControlEntity.accessedItems == 0) { + [managedObjectContext deleteObject:accessControlEntity]; + } + } + + [managedObjectContext deleteObject:managedItem]; + success = [managedObjectContext save:&error]; + } + else { + success = false; + } + } + + if (!success && !error) { + secerror("SecCDKeychain: attempt to delete item with persistant identifier that could not be found: %@", persistentID); + error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorItemNotFound userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"attempt to delete item with persistant identifier that could not be found: %@", persistentID]}]; + } + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + completionHandler(success, error); + }); + }]; +} + +- (void)registerItemType:(SecCDKeychainItemType*)itemType withManagedObjectContext:(NSManagedObjectContext*)managedObjectContext +{ + _itemTypeDict[itemType.name] = itemType; + + NSMutableDictionary* itemTypeVersionDict = _managedItemTypeDict[itemType.name]; + if (!itemTypeVersionDict) { + itemTypeVersionDict = [NSMutableDictionary dictionary]; + _managedItemTypeDict[itemType.name] = itemTypeVersionDict; + } + + if (!itemTypeVersionDict[@(itemType.version)]) { + NSError* error = nil; + SecCDKeychainManagedItemType* managedItemType = [itemType managedItemTypeWithContext:managedObjectContext error:&error]; + if (managedItemType) { + itemTypeVersionDict[@(itemType.version)] = managedItemType; + [managedObjectContext save:&error]; + } + + if (!managedItemType || error) { + secerror("SecCDKeychain: error registering managedItemType for for itemType: %@", itemType); + } + } +} + +// this method is only for use by tests because built-in types should get registered at initial store setup +- (void)_registerItemTypeForTesting:(SecCDKeychainItemType*)itemType +{ + [self performOnManagedObjectQueueAndWait:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) { + if (!managedObjectContext) { + secerror("SecCDKeychain: _registerItemTypeForTesting: could not get managed object context"); + return; + } + + [self registerItemType:itemType withManagedObjectContext:managedObjectContext]; + }]; +} + +- (SecCDKeychainItemType*)itemTypeForItemTypeName:(NSString*)itemTypeName +{ + return _itemTypeDict[itemTypeName]; +} + +- (SecCDKeychainManagedItem*)managedItemWithItem:(SecCDKeychainItem*)item withManagedObjectContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error +{ + NSError* localError = nil; + SecCDKeychainManagedItem* managedItem = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityItem inManagedObjectContext:managedObjectContext]; + managedItem.itemType = [[_managedItemTypeDict valueForKey:item.itemType.name] objectForKey:@(item.itemType.version)]; + managedItem.persistentID = item.metadata.persistentID; + + NSData* attributeData = [NSPropertyListSerialization dataWithPropertyList:item.attributes format:NSPropertyListBinaryFormat_v1_0 options:0 error:&localError]; + managedItem.metadata = attributeData; + + SecCDKeychainManagedAccessControlEntity* owner = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityTypeAccessControlEntity inManagedObjectContext:managedObjectContext]; + owner.type = item.owner.entityType; + owner.stringRepresentation = item.owner.stringRepresentation; + managedItem.owner = owner; + [owner addOwnedItemsObject:managedItem]; + [owner addAccessedItemsObject:managedItem]; + + // today, we only support the device keybag + // someday, that will have to change + managedItem.data = [item encryptedSecretDataWithAttributeData:attributeData keybag:KEYBAG_DEVICE error:&localError]; + + if (error) { + *error = localError; + } + + return localError ? nil : managedItem; +} + +@end + +@implementation SecCDKeychainItemMetadata { + SecCDKeychainItemType* _itemType; + SecCDKeychainAccessControlEntity* _owner; + NSUUID* _persistentID; + NSDictionary* _attributes; + NSSet* _lookupAttributes; + NSData* _managedDataBlob; // hold onto this to verify metadata been tampered with + keyclass_t _keyclass; +} + +@synthesize itemType = _itemType; +@synthesize owner = _owner; +@synthesize persistentID = _persistentID; +@synthesize attributes = _attributes; +@synthesize lookupAttributesSet = _lookupAttributes; +@synthesize managedDataBlob = _managedDataBlob; +@synthesize keyclass = _keyclass; + +- (instancetype)initWithItemType:(SecCDKeychainItemType*)itemType persistentID:(NSUUID*)persistentID attributes:(NSDictionary*)attributes lookupAttributes:(NSArray*)lookupAttributes owner:(SecCDKeychainAccessControlEntity*)owner keyclass:(keyclass_t)keyclass +{ + if (self = [super init]) { + _itemType = itemType; + _owner = owner; + _persistentID = persistentID.copy; + _attributes = attributes.copy; + _keyclass = keyclass; + + if (lookupAttributes) { + _lookupAttributes = [NSSet setWithArray:lookupAttributes]; + } + else { + NSMutableSet* lookupAttributes = [[NSMutableSet alloc] init]; + [_attributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id value, BOOL* stop) { + SecCDKeychainLookupTuple* lookupTuple = [SecCDKeychainLookupTuple lookupTupleWithKey:key value:value]; + [lookupAttributes addObject:lookupTuple]; + }]; + _lookupAttributes = lookupAttributes.copy; + } + } + + return self; +} + +- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error +{ + if (self = [super init]) { + _itemType = [keychain itemTypeForItemTypeName:managedItem.itemType.name]; + _persistentID = managedItem.persistentID.copy; + _managedDataBlob = managedItem.metadata; + _attributes = [NSPropertyListSerialization propertyListWithData:_managedDataBlob options:NSPropertyListImmutable format:NULL error:error]; + _owner = [[SecCDKeychainAccessControlEntity alloc] initWithManagedEntity:managedItem.owner]; + + NSMutableSet* lookupAttributes = [NSMutableSet set]; + for (SecCDKeychainManagedLookupEntry* lookupEntry in managedItem.lookupEntries) { + if (!lookupEntry.systemEntry) { + [lookupAttributes addObject:[SecCDKeychainLookupTuple lookupTupleWithManagedLookupEntry:lookupEntry]]; + } + } + _lookupAttributes = lookupAttributes.copy; + + if (!_itemType || !_persistentID || !_owner || ![_attributes isKindOfClass:[NSDictionary class]]) { + if (error) { + *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorDeserializing userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"failed to deserialize SecCDKeychainItemMetadata with item type (%@) persistentID: %@ owner: %@", _itemType, _persistentID, _owner]}]; + } + self = nil;; + } + } + + return self; +} + +- (BOOL)isEqual:(SecCDKeychainItemMetadata*)object +{ + return [_itemType isEqual:object.itemType] && + [_owner isEqual:object.owner] && + [_persistentID isEqual:object.persistentID] && + [_attributes isEqual:object.attributes] && + [_lookupAttributes isEqual:object.lookupAttributesSet]; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"%@: itemType:(%@) owner:(%@) persistentID:(%@)\n attributes: %@\n lookup attributes: %@", [super description], self.itemType, self.owner, self.persistentID, self.attributes, self.lookupAttributes]; +} + +- (void)fetchFullItemWithKeychain:(SecCDKeychain*)keychain withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(SecCDKeychainItem* _Nullable item, NSError* _Nullable error))completionHandler +{ + [keychain fetchItemForPersistentID:_persistentID withConnection:connection completionHandler:completionHandler]; +} + +- (NSArray*)lookupAttributes +{ + return _lookupAttributes.allObjects; +} + +- (NSArray*)primaryKeys +{ + return _itemType.primaryKeys; +} + +@end + +@implementation SecCDKeychainItem { + SecCDKeychainItemMetadata* _metadata; + NSData* _encryptedSecretData; + NSDictionary* _secrets; +} + +@synthesize metadata = _metadata; +@synthesize secrets = _secrets; + +- (instancetype)initItemType:(SecCDKeychainItemType*)itemType withPersistentID:(NSUUID*)persistentID attributes:(NSDictionary*)attributes lookupAttributes:(NSArray*)lookupAttributes secrets:(NSDictionary*)secrets owner:(SecCDKeychainAccessControlEntity*)owner keyclass:(keyclass_t)keyclass +{ + if (self = [super init]) { + _secrets = secrets.copy; + _metadata = [[SecCDKeychainItemMetadata alloc] initWithItemType:itemType persistentID:persistentID attributes:attributes lookupAttributes:lookupAttributes owner:owner keyclass:keyclass]; + if (!_metadata) { + self = nil; + } + } + + return self; +} + +- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error +{ + if (self = [super init]) { + NSError* localError; + _metadata = [[SecCDKeychainItemMetadata alloc] initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:keychain error:&localError]; + if (!_metadata) { + if (error) { + // TODO: add a negative unit test + + *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorDeserializing userInfo:@{NSLocalizedDescriptionKey : @"could not create SecCDKeychainItem from managed item - managed item was malformed"}]; + } + return nil; + } + + _secrets = [self secretsFromEncryptedData:managedItem.data withKeybag:KEYBAG_DEVICE error:&localError]; + if (!_secrets) { + if (error) { + *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorItemDecryptionFailed userInfo:@{ NSLocalizedDescriptionKey : @"could not decrypt secrets for item", NSUnderlyingErrorKey : localError }]; + } + return nil; + } + } + + return self; +} + +- (BOOL)isEqual:(SecCDKeychainItem*)object +{ + return [object isKindOfClass:[SecCDKeychainItem class]] + && [_metadata isEqual:object.metadata] + && [_secrets isEqual:object.secrets]; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"%@: itemType:(%@) persistentID:(%@)\n owner: %@\n attributes: %@\n lookup attributes: %@\nprimaryKeys: %@", [super description], self.itemType, self.persistentID, self.owner, self.attributes, self.lookupAttributes, self.primaryKeys]; +} + +- (SecCDKeychainItemType*)itemType +{ + return _metadata.itemType; +} + +- (SecCDKeychainAccessControlEntity*)owner +{ + return _metadata.owner; +} + +- (NSUUID*)persistentID +{ + return _metadata.persistentID; +} + +- (NSDictionary*)attributes +{ + return _metadata.attributes; +} + +- (NSArray*)lookupAttributes +{ + return _metadata.lookupAttributes; +} + +- (NSArray*)primaryKeys +{ + return _metadata.primaryKeys; +} + +- (NSString*)primaryKeyStringRepresentationWithError:(NSError**)error +{ + NSDictionary* attributes = _metadata.attributes; + NSArray* primaryKeys = _metadata.primaryKeys.count > 0 ? _metadata.primaryKeys : attributes.allKeys; + NSArray* sortedPrimaryKeys = [primaryKeys sortedArrayUsingComparator:^NSComparisonResult(NSString* firstKey, NSString* secondKey) { + return [firstKey compare:secondKey options:NSForcedOrderingSearch]; + }]; + + SFSHA256DigestOperation* digest = [[SFSHA256DigestOperation alloc] init]; + [digest addData:[_metadata.owner.stringRepresentation dataUsingEncoding:NSUTF8StringEncoding]]; + + for (NSString* key in sortedPrimaryKeys) { + [digest addData:[key dataUsingEncoding:NSUTF8StringEncoding]]; + + id value = attributes[key]; + if ([value isKindOfClass:[NSData class]]) { + [digest addData:value]; + } + else if ([value isKindOfClass:[NSString class]]) { + [digest addData:[value dataUsingEncoding:NSUTF8StringEncoding]]; + } + else { + NSData* valueData = [NSKeyedArchiver archivedDataWithRootObject:value requiringSecureCoding:YES error:error]; + if (valueData) { + [digest addData:valueData]; + } + else { + return nil; + } + } + } + + return [[digest hashValue] base64EncodedStringWithOptions:0]; +} + +- (NSData*)encryptedSecretDataWithAttributeData:(NSData*)attributeData keybag:(keybag_handle_t)keybag error:(NSError**)error +{ +#if USE_KEYSTORE + NSError* localError = nil; + NSString* errorDescription = nil; + + SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; + SFAESKey* randomKey = [[SFAESKey alloc] initRandomKeyWithSpecifier:keySpecifier error:&localError]; + if (!randomKey) { + secerror("SecCDKeychain: failed to create random key for encrypting item with error: %@", localError); + errorDescription = @"failed to create random key for encrypting item"; + } + + NSData* itemSecrets = [NSPropertyListSerialization dataWithPropertyList:_secrets format:NSPropertyListBinaryFormat_v1_0 options:0 error:&localError]; + if (!itemSecrets) { + secerror("SecCDKeychain: failed to serialize item secrets dictionary with error: %@", localError); + errorDescription = @"failed to serialize item secrets dictionary"; + } + + SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:keySpecifier]; + SFAuthenticatedCiphertext* ciphertext = nil; + if (randomKey && itemSecrets) { + NSData* attributeDataSHA256 = [SFSHA256DigestOperation digest:attributeData]; + ciphertext = [encryptionOperation encrypt:itemSecrets withKey:randomKey additionalAuthenticatedData:attributeDataSHA256 error:&localError]; + if (!ciphertext) { + secerror("SecCDKeychain: failed to encrypt item secret data with error: %@", localError); + errorDescription = @"failed to encrypt item secret data"; + } + } + + SecAKSRefKey* refKey = nil; + NSData* refKeyBlobData = nil; + + if (ciphertext) { + refKey = [[SecAKSRefKey alloc] initWithKeybag:keybag keyclass:_metadata.keyclass]; + refKeyBlobData = refKey.refKeyBlob; + if (!refKey || !refKeyBlobData) { + secerror("SecCDKeychain: failed to create refKey"); + errorDescription = @"failed to create refKey"; + } + } + + NSData* wrappedKeyData = nil; + if (refKey && refKeyBlobData) { + wrappedKeyData = [refKey wrappedDataForKey:randomKey]; + if (!wrappedKeyData) { + secerror("SecCDKeychain: failed to encrypt item"); + errorDescription = @"failed to encrypt item"; + } + } + + if (wrappedKeyData) { + SecCDKeychainItemWrappedSecretData* wrappedSecretData = [[SecCDKeychainItemWrappedSecretData alloc] initWithCiphertext:ciphertext wrappedKeyData:wrappedKeyData refKeyBlob:refKeyBlobData]; + NSData* wrappedSecretDataBlob = [NSKeyedArchiver archivedDataWithRootObject:wrappedSecretData requiringSecureCoding:YES error:&localError]; + if (wrappedSecretDataBlob) { + return wrappedSecretDataBlob; + } + else { + secerror("SecCDKeychain: failed to serialize item secret data blob with error: %@", localError); + errorDescription = @"failed to serialize item secret data blob"; + } + } + + if (error) { + NSDictionary* userInfo = localError ? @{ NSUnderlyingErrorKey : localError, NSLocalizedDescriptionKey : errorDescription } : @{NSLocalizedDescriptionKey : errorDescription}; + *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:userInfo]; + } + +#endif + return nil; +} + +- (NSDictionary*)secretsFromEncryptedData:(NSData*)secretData withKeybag:(keybag_handle_t)keybag error:(NSError**)error +{ +#if USE_KEYSTORE + SecCDKeychainItemWrappedSecretData* wrappedSecretData = [NSKeyedUnarchiver unarchivedObjectOfClass:[SecCDKeychainItemWrappedSecretData class] fromData:secretData error:error]; + if (!wrappedSecretData) { + secerror("SecCDKeychain: failed to deserialize item wrapped secret data"); + return nil; + } + + SecAKSRefKey* refKey = [[SecAKSRefKey alloc] initWithBlob:wrappedSecretData.refKeyBlob keybag:keybag]; + if (!refKey) { + secerror("SecCDKeychain: failed to create refKey for unwrapping item secrets"); + if (error) { + *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"failed to create refKey for unwrapping item secrets"}]; + } + return nil; + } + + SFAESKey* key = [refKey keyWithWrappedData:wrappedSecretData.wrappedKeyData]; + if (!key) { + secerror("SecCDKeychain: failed to create item key for decryption"); + return nil; + } + + SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; + SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:keySpecifier]; + NSData* metadataSHA256 = [SFSHA256DigestOperation digest:_metadata.managedDataBlob]; + NSData* decryptedSecretData = [encryptionOperation decrypt:wrappedSecretData.ciphertext withKey:key additionalAuthenticatedData:metadataSHA256 error:error]; + if (!decryptedSecretData) { + secerror("SecCDKeychain: failed to decrypt item secret data"); + return nil; + } + + NSDictionary* secrets = [NSPropertyListSerialization propertyListWithData:decryptedSecretData options:0 format:NULL error:error]; + if (![secrets isKindOfClass:[NSDictionary class]]) { + secerror("SecCDKeychain: failed to deserialize item decrypted secret data"); + return nil; + } + + return secrets; +#else + return nil; +#endif +} + +// TODO: get back to this as part of CKKS integration work + +//- (NSDictionary*)attributesPropertyListWithError:(NSError**)error +//{ +// __block NSDictionary* (^dictionaryToPropertyList)(NSDictionary*) = NULL; +// __block NSArray* (^arrayToPropertyList)(NSArray*) = NULL; +// +// dictionaryToPropertyList = ^(NSDictionary* dict) { +// NSMutableDictionary* propertyList = [NSMutableDictionary dictionary]; +// [dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, id object, BOOL* stop) { +// Class objectClass = [object class]; +// if ([objectClass isKindOfClass:[NSString class]] || [objectClass isKindOfClass:[NSData class]] || [objectClass isKindOfClass:[NSDate class]] || [objectClass isKindOfClass:[NSNumber class]]) { +// propertyList[key] = object; +// } +// else if ([objectClass isKindOfClass:[NSDictionary class]]){ +// NSDictionary* objectAsPropertyList = dictionaryToPropertyList(object); +// if (objectAsPropertyList) { +// propertyList[key] = objectAsPropertyList; +// } +// else { +// *stop = YES; +// } +// } +// else if ([objectClass isKindOfClass:[NSArray class]]) { +// NSArray* objectAsPropertyList = arrayToPropertyList(object); +// if (objectAsPropertyList) { +// propertyList[key] = objectAsPropertyList; +// } +// else { +// *stop = YES; +// } +// } +// else if ([object conformsToProtocol:@protocol(NSSecureCoding)]) { +// NSData* +// } +// }]; +// } +//} + +@end + +@implementation SecCDKeychainLookupTuple { + NSString* _key; + id _value; + SecCDKeychainLookupValueType* _valueType; +} + +@synthesize key = _key; +@synthesize value = _value; +@synthesize valueType = _valueType; + ++ (instancetype)lookupTupleWithKey:(NSString*)key value:(id)value +{ + return [[self alloc] initWithKey:key value:value]; +} + ++ (instancetype)lookupTupleWithManagedLookupEntry:(SecCDKeychainManagedLookupEntry*)lookupEntry +{ + NSString* valueString = lookupEntry.lookupValue; + id value; + NSString* valueType = lookupEntry.lookupValueType; + if ([valueType isEqualToString:SecCDKeychainLookupValueTypeString]) { + value = valueString; + } + else { + NSData* valueData = [[NSData alloc] initWithBase64EncodedString:valueString options:0]; + + if ([valueType isEqualToString:SecCDKeychainLookupValueTypeData]) { + value = valueData; + } + else if ([valueType isEqualToString:SecCDKeychainLookupValueTypeDate]) { + // TODO: error parameter + value = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSDate class] fromData:valueData error:nil]; + } + else if ([valueType isEqualToString:SecCDKeychainLookupValueTypeNumber]) { + value = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSNumber class] fromData:valueData error:nil]; + } + else { + // TODO: error here + value = nil; + } + } + + return value ? [[self alloc] initWithKey:lookupEntry.lookupKey value:value] : nil; +} + +- (instancetype)initWithKey:(NSString*)key value:(id)value +{ + if (self = [super init]) { + SecCDKeychainLookupValueType* valueType = [SecCDKeychain lookupValueTypeForObject:value]; + BOOL zeroLengthValue = ([valueType isEqualToString:SecCDKeychainLookupValueTypeString] && [(NSString*)value length] == 0) || ([valueType isEqualToString:SecCDKeychainLookupValueTypeData] && [(NSData*)value length] == 0); + if (valueType && !zeroLengthValue) { + _key = key.copy; + _value = [value copyWithZone:nil]; + _valueType = valueType.copy; + } + else { + // TODO: add an error parameter to this method + self = nil; + } + } + + return self; +} + +- (BOOL)isEqual:(SecCDKeychainLookupTuple*)object +{ + return [_key isEqualToString:object.key] && [_value isEqual:object.value] && [_valueType isEqualToString:object.valueType]; +} + +- (NSUInteger)hash +{ + return _key.hash ^ _value.hash ^ _valueType.hash; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"%@ : %@ [%@]", _key, _value, _valueType]; +} + +- (NSString*)stringRepresentation +{ + if ([_valueType isEqualToString:SecCDKeychainLookupValueTypeString]) { + return (NSString*)_value; + } + else if ([_valueType isEqualToString:SecCDKeychainLookupValueTypeData]) { + return [(NSData*)_value base64EncodedStringWithOptions:0]; + } + else { + return [[NSKeyedArchiver archivedDataWithRootObject:_value requiringSecureCoding:YES error:nil] base64EncodedStringWithOptions:0]; + } +} + +@end + +@implementation SecCDKeychainItemType { + NSString* _name; + int32_t _version; + NSSet* _primaryKeys; + NSSet* _syncableKeys; + SecCDKeychainManagedItemType* _managedItemType; +} + +@synthesize name = _name; +@synthesize version = _version; + ++ (instancetype)itemType +{ + return nil; +} + ++ (nullable instancetype)itemTypeForVersion:(int32_t)version +{ + return [self itemType]; +} + +- (instancetype)_initWithName:(NSString*)name version:(int32_t)version primaryKeys:(NSArray*)primaryKeys syncableKeys:(NSArray*)syncableKeys +{ + if (self = [super init]) { + _name = name.copy; + _version = version; + _primaryKeys = [NSSet setWithArray:primaryKeys]; + _syncableKeys = [NSSet setWithArray:syncableKeys]; + } + + return self; +} + +- (BOOL)isEqual:(SecCDKeychainItemType*)object +{ + return [object isKindOfClass:[SecCDKeychainItemType class]] && + [_name isEqualToString:object.name] && + _version == object.version && + [_primaryKeys isEqualToSet:object->_primaryKeys] && + [_syncableKeys isEqualToSet:object->_syncableKeys]; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"%@ | %d", _name, _version]; +} + +- (NSString*)debugDescription +{ + return [NSString stringWithFormat:@"%@\n name: %@\n version: %d\n primaryKeys: %@\n syncableKeys: %@", [super debugDescription], _name, _version, _primaryKeys, _syncableKeys]; +} + +- (NSArray*)primaryKeys +{ + return _primaryKeys.allObjects; +} + +- (NSArray*)syncableKeys +{ + return _syncableKeys.allObjects; +} + +- (SecCDKeychainManagedItemType*)managedItemTypeWithContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error +{ + NSError* localError = nil; + SecCDKeychainManagedItemType* managedItemType = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityItemType inManagedObjectContext:managedObjectContext]; + managedItemType.name = _name; + managedItemType.version = _version; + managedItemType.primaryKeys = [NSPropertyListSerialization dataWithPropertyList:_primaryKeys.allObjects format:NSPropertyListBinaryFormat_v1_0 options:0 error:&localError]; + managedItemType.syncableKeys = [NSPropertyListSerialization dataWithPropertyList:_syncableKeys.allObjects format:NSPropertyListBinaryFormat_v1_0 options:0 error:&localError]; + + if (error) { + *error = localError; + } + + return localError ? nil : managedItemType; +} + +@end + +@implementation SecCDKeychainAccessControlEntity { + SecCDKeychainAccessControlEntityType _entityType; + NSString* _stringRepresentation; +} + +@synthesize entityType = _entityType; +@synthesize stringRepresentation = _stringRepresentation; + ++ (instancetype)accessControlEntityWithType:(SecCDKeychainAccessControlEntityType)type stringRepresentation:(NSString*)stringRepresentation +{ + return [[self alloc] _initWithEntityType:type stringRepresentation:stringRepresentation]; +} + +- (instancetype)_initWithEntityType:(SecCDKeychainAccessControlEntityType)type stringRepresentation:(NSString*)stringRepresentation +{ + if (self = [super init]) { + _entityType = type; + _stringRepresentation = stringRepresentation.copy; + } + + return self; +} + +- (instancetype)initWithManagedEntity:(SecCDKeychainManagedAccessControlEntity*)managedAccessControlEntity +{ + return [self _initWithEntityType:managedAccessControlEntity.type stringRepresentation:managedAccessControlEntity.stringRepresentation]; +} + +- (BOOL)isEqual:(SecCDKeychainAccessControlEntity*)object +{ + return _entityType == object.entityType && [_stringRepresentation isEqualToString:object.stringRepresentation]; +} + +@end + +#endif // TARGET_OS_BRIDGE diff --git a/keychain/KeychainDataclassOwner/Info.plist b/keychain/KeychainDataclassOwner/Info.plist new file mode 100644 index 00000000..fe2367c5 --- /dev/null +++ b/keychain/KeychainDataclassOwner/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSPrincipalClass + KeychainDataclassOwner + + diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h b/keychain/KeychainDataclassOwner/KeychainDataclassOwner.h similarity index 53% rename from KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h rename to keychain/KeychainDataclassOwner/KeychainDataclassOwner.h index 1a2f70a0..bc2e8346 100644 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h +++ b/keychain/KeychainDataclassOwner/KeychainDataclassOwner.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,15 +21,12 @@ * @APPLE_LICENSE_HEADER_END@ */ +#import +#import -#import "IDSProxy.h" - -@interface KeychainSyncingOverIDSProxy (ReceiveMessage) -//receive message routines --(BOOL) checkForFragmentation:(NSDictionary*)message id:(NSString*)fromID data:(NSData*)messageData; --(NSMutableDictionary*) combineMessage:(NSString*)deviceID peerID:(NSString*)peerID uuid:(NSString*)uuid; -- (void)service:(IDSService *)service account:(IDSAccount *)account incomingMessage:(NSDictionary *)message fromID:(NSString *)fromID context:(IDSMessageContext *)context; --(void)sendMessageToSecurity:(NSMutableDictionary*)messageAndFromID fromID:(NSString*)fromID shouldSendAck:(NSString *)useAck peerID:(NSString*)peerID messageID:(NSString*)messageID deviceID:(NSString*)deviceID; -- (void) handleAllPendingMessage; +NS_ASSUME_NONNULL_BEGIN +@interface KeychainDataclassOwner : NSObject @end + +NS_ASSUME_NONNULL_END diff --git a/keychain/KeychainDataclassOwner/KeychainDataclassOwner.m b/keychain/KeychainDataclassOwner/KeychainDataclassOwner.m new file mode 100644 index 00000000..af2ef1dd --- /dev/null +++ b/keychain/KeychainDataclassOwner/KeychainDataclassOwner.m @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2018 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@ + */ + +#import "KeychainDataclassOwner.h" +#import "NSError+UsefulConstructors.h" +#import "OTControl.h" +#import "SecCFRelease.h" +#import "SOSCloudCircle.h" +#import "debugging.h" +#import "OT.h" +#import +#import +#import +#import +#import + +@implementation KeychainDataclassOwner + +static NSString* const KeychainDataclass = @"KeychainDataclass"; + ++ (NSArray*)dataclasses +{ + return @[kAccountDataclassKeychainSync]; +} + +- (NSArray*)actionsForDeletingAccount:(ACAccount*)account forDataclass:(NSString*)dataclass +{ + if (![dataclass isEqual:kAccountDataclassKeychainSync]) { + return nil; + } + + ACDataclassAction* cancelAction = [ACDataclassAction actionWithType:ACDataclassActionCancel]; + ACDataclassAction* deleteAction = [ACDataclassAction actionWithType:ACDataclassActionDeleteSyncData]; + ACDataclassAction* keepAction = [ACDataclassAction actionWithType:ACDataclassActionMergeSyncDataIntoLocalData]; + + return @[cancelAction, deleteAction, keepAction]; +} + +- (NSArray*)actionsForDisablingDataclassOnAccount:(ACAccount*)account forDataclass:(NSString*)dataclass +{ + return [self actionsForDeletingAccount:account forDataclass:dataclass]; +} + + +- (BOOL)performAction:(ACDataclassAction*)action forAccount:(ACAccount*)account withChildren:(NSArray*)childAccounts forDataclass:(NSString*)dataclass withError:(NSError**)error +{ + // if the user asked us to delete their data, do that now + // we should rejigger this implementation to send a new custom message to security with an entitlement specifically for the signout case + // then we can do all the things we need to in securityd without having to entitlement the dataclass owners manager to read keychain items + // redo KeychainDataclassOwner to remove Safari items from DataclassOwnerManager's entitlements + if (action.type == ACDataclassActionDeleteSyncData) { + NSDictionary* baseQuery = @{ (id)kSecAttrSynchronizable : @(YES), + (id)kSecAttrAccessGroup : @"com.apple.cfnetwork", + (id)kSecAttrNoLegacy : @(YES), + (id)kSecAttrTombstone : @(NO) }; + NSMutableDictionary* inetQuery = baseQuery.mutableCopy; + inetQuery[(id)kSecClass] = (id)kSecClassInternetPassword; + OSStatus inetResult = SecItemDelete((__bridge CFDictionaryRef)inetQuery); + + NSMutableDictionary* genpQuery = baseQuery.mutableCopy; + genpQuery[(id)kSecClass] = (id)kSecClassGenericPassword; + OSStatus genpResult = SecItemDelete((__bridge CFDictionaryRef)genpQuery); + + NSMutableDictionary* certQuery = baseQuery.mutableCopy; + certQuery[(id)kSecClass] = (id)kSecClassCertificate; + OSStatus certResult = SecItemDelete((__bridge CFDictionaryRef)certQuery); + + NSMutableDictionary* keyQuery = baseQuery.mutableCopy; + keyQuery[(id)kSecClass] = (id)kSecClassKey; + OSStatus keyResult = SecItemDelete((__bridge CFDictionaryRef)keyQuery); + + NSMutableDictionary* creditCardsQuery = baseQuery.mutableCopy; + creditCardsQuery[(id)kSecClass] = (id)kSecClassGenericPassword; + creditCardsQuery[(id)kSecAttrAccessGroup] = @"com.apple.safari.credit-cards"; + OSStatus creditCardsResult = SecItemDelete((__bridge CFDictionaryRef)creditCardsQuery); + + if (inetResult != errSecSuccess) { + secwarning("failed to delete synchronizable passwords from table inet: %d", (int)inetResult); + } + if (genpResult != errSecSuccess) { + secwarning("failed to delete synchronizable passwords from table genp: %d", (int)genpResult); + } + if (certResult != errSecSuccess) { + secwarning("failed to delete synchronizable passwords from table cert: %d", (int)certResult); + } + if (keyResult != errSecSuccess) { + secwarning("failed to delete synchronizable passwords from table keys: %d", (int)keyResult); + } + if (creditCardsResult != errSecSuccess) { + secwarning("failed to delete credit cards from table genp: %d", (int)creditCardsResult); + } + } + + return YES; +} + +@end diff --git a/keychain/KeychainResources/Info.plist b/keychain/KeychainResources/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/keychain/KeychainResources/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/keychain/SecItem.h b/keychain/SecItem.h index 1329fa22..ad370e53 100644 --- a/keychain/SecItem.h +++ b/keychain/SecItem.h @@ -1021,7 +1021,7 @@ extern const CFStringRef kSecValuePersistentRef keychain operations. */ extern const CFStringRef kSecUseItemList - API_AVAILABLE(macos(10.6), ios(2.0)); + API_AVAILABLE(macos(10.6)) API_UNAVAILABLE(ios, tvos, watchos); extern const CFStringRef kSecUseKeychain API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecUseOperationPrompt diff --git a/keychain/SecItemPriv.h b/keychain/SecItemPriv.h index d827b882..9e4f9d77 100644 --- a/keychain/SecItemPriv.h +++ b/keychain/SecItemPriv.h @@ -362,9 +362,9 @@ extern const CFStringRef kSecAttrViewHintManatee; extern const CFStringRef kSecAttrViewHintAutoUnlock; extern const CFStringRef kSecAttrViewHintHealth; extern const CFStringRef kSecAttrViewHintApplePay; +extern const CFStringRef kSecAttrViewHintHome; -#if SEC_OS_IPHONE extern const CFStringRef kSecUseSystemKeychain __TVOS_AVAILABLE(9.2) __WATCHOS_AVAILABLE(3.0) @@ -376,7 +376,6 @@ extern const CFStringRef kSecUseSyncBubbleKeychain __WATCHOS_AVAILABLE(3.0) __OSX_AVAILABLE(10.11.4) __IOS_AVAILABLE(9.3); -#endif /* SEC_OS_IPHONE */ /*! @enum Other Constants (Private) @@ -411,6 +410,8 @@ extern const CFStringRef kSecUseSyncBubbleKeychain which have non-empty kSecAttrTokenID are not going through client-side postprocessing, only raw form stored in the database is listed. This flag is ignored in other operations than SecItemCopyMatching(). + @constant kSecUseCertificatesWithMatchIssuers If set to true, + SecItemCopyMatching allows to return certificates when kSecMatchIssuers is specified. */ extern const CFStringRef kSecUseTombstones __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); @@ -420,6 +421,8 @@ extern const CFStringRef kSecUseCallerName __OSX_AVAILABLE(10.11.4) __IOS_AVAILABLE(9.3) __TVOS_AVAILABLE(9.3) __WATCHOS_AVAILABLE(2.3); extern const CFStringRef kSecUseTokenRawItems __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +extern const CFStringRef kSecUseCertificatesWithMatchIssuers + __OSX_AVAILABLE(10.14) __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; extern const CFStringRef kSOSInternalAccessGroup __OSX_AVAILABLE(10.9) __IOS_AVAILABLE(7.0) __TVOS_AVAILABLE(9.3) __WATCHOS_AVAILABLE(2.3); @@ -512,7 +515,6 @@ void SecItemFetchCurrentItemAcrossAllDevices(CFStringRef accessGroup, void _SecItemFetchDigests(NSString *itemClass, NSString *accessGroup, void (^complete)(NSArray *, NSError *)); #endif -#if SEC_OS_IPHONE /*! @function SecItemDeleteAllWithAccessGroups @abstract Deletes all items for each class for the given access groups @@ -522,7 +524,6 @@ void _SecItemFetchDigests(NSString *itemClass, NSString *accessGroup, void (^com Requires entitlement "com.apple.private.uninstall.deletion" */ bool SecItemDeleteAllWithAccessGroups(CFArrayRef accessGroups, CFErrorRef *error); -#endif /* SEC_OS_IPHONE */ /* Ensure the escrow keybag has been used to unlock the system keybag before @@ -568,6 +569,7 @@ bool _SecKeychainRollKeys(bool force, CFErrorRef *error); CFDictionaryRef _SecSecuritydCopyWhoAmI(CFErrorRef *error); XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyCKKSEndpoint(CFErrorRef *error); +XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopySFKeychainEndpoint(CFErrorRef* error); XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyKeychainControlEndpoint(CFErrorRef* error); #if SEC_OS_IPHONE @@ -577,9 +579,7 @@ bool _SecSyncBubbleTransfer(CFArrayRef services, CFErrorRef *error); #endif /* SEC_OS_IPHONE */ bool _SecSystemKeychainTransfer(CFErrorRef *error); -#if SEC_OS_IPHONE bool _SecSyncDeleteUserViews(uid_t uid, CFErrorRef *error); -#endif /* SEC_OS_IPHONE */ @@ -589,7 +589,6 @@ OSStatus SecItemUpdateTokenItems(CFTypeRef tokenID, CFArrayRef tokenItemsAttribu CFTypeRef SecItemCreateFromAttributeDictionary_osx(CFDictionaryRef refAttributes); #endif -#if SEC_OS_IPHONE /*! * @function SecCopyLastError * @abstract return the last CFErrorRef for this thread @@ -620,7 +619,6 @@ SecItemUpdateWithError(CFDictionaryRef inQuery, __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __IOS_AVAILABLE(10.0); -#endif // SEC_OS_IPHONE #if SEC_OS_OSX /*! diff --git a/keychain/SecKeyPriv.h b/keychain/SecKeyPriv.h index 77bfcb5b..0c61b2cf 100644 --- a/keychain/SecKeyPriv.h +++ b/keychain/SecKeyPriv.h @@ -46,7 +46,6 @@ __BEGIN_DECLS -#if SEC_OS_IPHONE typedef struct __SecDERKey { uint8_t *oid; CFIndex oidLength; @@ -58,7 +57,6 @@ typedef struct __SecDERKey { uint8_t *key; CFIndex keyLength; } SecDERKey; -#endif // SEC_OS_IPHONE typedef struct SecRSAPublicKeyParams { uint8_t *modulus; /* modulus */ @@ -218,13 +216,12 @@ typedef struct __SecKeyDescriptor { #endif } SecKeyDescriptor; -#if SEC_OS_IPHONE struct __SecKey { CFRuntimeBase _base; const SecKeyDescriptor *key_class; -#if !TARGET_OS_IPHONE +#if TARGET_OS_OSX // On OSX, keep optional SecKeyRef which holds dynamically, on-demand created CSSM-based key with the same // key material. It is used to implement SecKeyGetCSSMKey(). SecKeyRef cdsaKey; @@ -233,7 +230,6 @@ struct __SecKey { /* The actual key handled by class. */ void *key; }; -#endif /* Create a public key from a CFData containing a SubjectPublicKeyInfo in DER format. */ SecKeyRef SecKeyCreateFromSubjectPublicKeyInfoData(CFAllocatorRef allocator, @@ -243,7 +239,6 @@ SecKeyRef SecKeyCreateFromSubjectPublicKeyInfoData(CFAllocatorRef allocator, CFDataRef SecKeyCopySubjectPublicKeyInfo(SecKeyRef key); -#if SEC_OS_IPHONE /*! @function SecKeyCreate @abstract Given a private key and data to sign, generate a digital signature. @@ -265,7 +260,6 @@ SecKeyRef SecKeyCreatePublicFromDER(CFAllocatorRef allocator, /* Create public key from private key */ SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey); -#endif // SEC_OS_IPHONE /* Get Private Key (if present) by publicKey. */ SecKeyRef SecKeyCopyMatchingPrivateKey(SecKeyRef publicKey, CFErrorRef *error); @@ -280,6 +274,10 @@ CFDictionaryRef CreatePrivateKeyMatchingQuery(SecKeyRef publicKey, bool returnPe in a keychain. */ SecKeyRef SecKeyCreateFromAttributeDictionary(CFDictionaryRef refAttributes); +// SecAsn1AlgId is deprecated, but we still need to use it. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + OSStatus SecKeyDigestAndVerify( SecKeyRef key, /* Public key */ const SecAsn1AlgId *algId, /* algorithm oid/params */ @@ -288,7 +286,6 @@ OSStatus SecKeyDigestAndVerify( const uint8_t *sig, /* signature to verify */ size_t sigLen); /* length of sig */ -#if SEC_OS_IPHONE /* Return an attribute dictionary used to store this item in a keychain. */ CFDictionaryRef SecKeyCopyAttributeDictionary(SecKeyRef key); @@ -316,6 +313,8 @@ OSStatus SecKeySignDigest( uint8_t *sig, /* signature, RETURNED */ size_t *sigLen); /* IN/OUT */ +#pragma clang diagnostic pop + OSStatus SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* serializedPublic); SecKeyRef SecKeyCreateFromPublicBytes(CFAllocatorRef allocator, CFIndex algorithmID, const uint8_t *keyData, CFIndex keyDataLength); SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef serialized); @@ -333,7 +332,6 @@ CFDictionaryRef SecKeyGeneratePrivateAttributeDictionary(SecKeyRef key, CFDataRef privateBlob); CF_RETURNS_RETAINED CFDictionaryRef SecKeyGeneratePublicAttributeDictionary(SecKeyRef key, CFTypeRef keyType); -#endif // SEC_OS_IPHONE enum { kSecNullAlgorithmID = 0, @@ -342,7 +340,16 @@ enum { kSecECDSAAlgorithmID = 3, }; -#if SEC_OS_IPHONE_INCLUDES +/*! + @function SecKeyGetAlgorithmId + @abstract Returns an enumerated constant value which identifies the algorithm for the given key. + @param key A key reference. + @result An algorithm identifier. + */ +CFIndex SecKeyGetAlgorithmId(SecKeyRef key) +API_AVAILABLE(macos(10.8), ios(9.0)); + +#if TARGET_OS_IPHONE /*! @function SecKeyGetAlgorithmID @abstract Returns an enumerated constant value which identifies the algorithm for the given key. @@ -353,26 +360,32 @@ enum { For compatibility, your code should migrate to use SecKeyGetAlgorithmId instead. */ CFIndex SecKeyGetAlgorithmID(SecKeyRef key) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_8, __IPHONE_5_0, __IPHONE_9_0); +API_DEPRECATED_WITH_REPLACEMENT("SecKeyGetAlgorithmId", ios(5.0, 9.0)) API_UNAVAILABLE(iosmac); +#endif // TARGET_OS_IPHONE +#if TARGET_OS_OSX /*! - @function SecKeyGetAlgorithmId - @abstract Returns an enumerated constant value which identifies the algorithm for the given key. - @param key A key reference. - @result An algorithm identifier. -*/ -CFIndex SecKeyGetAlgorithmId(SecKeyRef key) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_9_0); -#endif //#SEC_OS_IPHONE_INCLUDES + @function SecKeyGetAlgorithmID + @abstract Returns a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure for the given key. + @param key A key reference. + @param algid On return, a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure. + @result A result code. See "Security Error Codes" (SecBase.h). + @discussion Deprecated in OS X 10.8 and later. Continued use is strongly discouraged, + since there is a naming conflict with a similar function (also deprecated) on iOS that + had different arguments and a different return value. Use SecKeyGetAlgorithmId instead. + */ +OSStatus SecKeyGetAlgorithmID(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER **algid) +API_DEPRECATED_WITH_REPLACEMENT("SecKeyGetAlgorithmId", macos(10.2, 10.8)) API_UNAVAILABLE(ios); +#endif -#if SEC_OS_IPHONE -typedef enum { +#if !SEC_OS_OSX +typedef CF_ENUM(int, SecKeySize) { kSecKeyKeySizeInBits = 0, kSecKeySignatureSize = 1, kSecKeyEncryptedDataSize = 2, // More might belong here, but we aren't settled on how // to take into account padding and/or digest types. -} SecKeySize; +}; /*! @function SecKeyGetSize @@ -385,11 +398,8 @@ typedef enum { */ size_t SecKeyGetSize(SecKeyRef key, SecKeySize whichSize) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); - #endif -#if SEC_OS_IPHONE - /*! @function SecKeyLookupPersistentRef @abstract Looks up a SecKeyRef via persistent ref. @@ -399,7 +409,6 @@ __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); */ OSStatus SecKeyFindWithPersistentRef(CFDataRef persistentRef, SecKeyRef* lookedUpData) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); -#endif // SEC_OS_IPHONE /*! @function SecKeyCopyPersistentRef @@ -411,12 +420,6 @@ __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); OSStatus SecKeyCopyPersistentRef(SecKeyRef key, CFDataRef* persistentRef) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); -#if SEC_OS_IPHONE - -/* - * - */ - extern const CFStringRef _kSecKeyWrapPGPSymAlg; /* CFNumber */ extern const CFStringRef _kSecKeyWrapPGPFingerprint; /* CFDataRef, at least 20 bytes */ extern const CFStringRef _kSecKeyWrapPGPWrapAlg; /* kSecKeyWrapRFC6637WrapNNN, or any of the other PGP wrap algs */ @@ -443,32 +446,7 @@ CFDataRef _SecKeyCopyUnwrapKey(SecKeyRef key, SecKeyWrapType type, CFDataRef wrappedKey, CFDictionaryRef parameters, CFDictionaryRef *outParam, CFErrorRef *error) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); -#endif // SEC_OS_IPHONE - - #if SEC_OS_OSX_INCLUDES -/*! - @function SecKeyGetAlgorithmID - @abstract Returns a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure for the given key. - @param key A key reference. - @param algid On return, a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure. - @result A result code. See "Security Error Codes" (SecBase.h). - @discussion Deprecated in OS X 10.8 and later. Continued use is strongly discouraged, - since there is a naming conflict with a similar function (also deprecated) on iOS that - had different arguments and a different return value. Use SecKeyGetAlgorithmId instead. -*/ -OSStatus SecKeyGetAlgorithmID(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER **algid) - DEPRECATED_IN_MAC_OS_X_VERSION_10_8_AND_LATER; - -/*! - @function SecKeyGetAlgorithmId - @abstract Returns an enumerated constant value which identifies the algorithm for the given key. - @param key A key reference. - @result An algorithm identifier. -*/ -CFIndex SecKeyGetAlgorithmId(SecKeyRef key) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_9_0); - /*! @function SecKeyGetStrengthInBits @abstract Returns key strength in bits for the given key. @@ -477,7 +455,7 @@ CFIndex SecKeyGetAlgorithmId(SecKeyRef key) @param strength On return, the key strength in bits. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeyGetStrengthInBits(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER *algid, unsigned int *strength); +OSStatus SecKeyGetStrengthInBits(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER *algid, unsigned int *strength) API_DEPRECATED("CSSM_X509_ALGORITHM_IDENTIFIER is deprecated", macos(10.4, 10.14)); /*! @function SecKeyImportPair @@ -527,7 +505,7 @@ SecKeyRef SecKeyCreate(CFAllocatorRef allocator, @result A result code. See "Security Error Codes" (SecBase.h). @discussion Warning: this function is NOT intended for use outside the Security stack in its current state. */ -OSStatus SecKeyCreateWithCSSMKey(const CSSM_KEY *key, SecKeyRef* keyRef); +OSStatus SecKeyCreateWithCSSMKey(const CSSM_KEY *key, SecKeyRef* keyRef) API_DEPRECATED("CSSM_KEY is deprecated", macos(10.11, 10.14)); /*! @@ -647,6 +625,9 @@ OSStatus SecKeyDecrypt( uint8_t *plainText, size_t *plainTextLen); /* IN/OUT */ +// SecAsn1AlgId is deprecated, but we still need to use it. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" OSStatus SecKeyVerifyDigest( SecKeyRef key, /* Private key */ const SecAsn1AlgId *algId, /* algorithm oid/params */ @@ -662,6 +643,9 @@ OSStatus SecKeySignDigest( size_t digestDataLen, /* length of digestData */ uint8_t *sig, /* signature, RETURNED */ size_t *sigLen); /* IN/OUT */ +#pragma clang diagnostic pop + +#endif // SEC_OS_OSX_INCLUDES /* These are the named curves we support. These values come from RFC 4492 @@ -713,6 +697,7 @@ SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey); */ SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef publicBytes); +#if SEC_OS_OSX_INCLUDES OSStatus SecKeyRawVerifyOSX( SecKeyRef key, SecPadding padding, @@ -729,9 +714,11 @@ OSStatus SecKeyRawVerifyOSX( */ typedef CF_ENUM(uint32_t, SecKeyAttestationKeyType) { - kSecKeyAttestationKeyTypeSIK = 0, - kSecKeyAttestationKeyTypeGID -} __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + 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)); /*! @function SecKeyCopyAttestationKey @@ -743,7 +730,7 @@ typedef CF_ENUM(uint32_t, SecKeyAttestationKeyType) @result On success a SecKeyRef containing the requested key is returned, on failure it returns NULL. */ SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef *error) -__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)); /*! @function SecKeyCreateAttestation @@ -758,7 +745,7 @@ __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AV @discussion Key attestation only works for CTK SEP keys, i.e. keys created with kSecAttrTokenID=kSecAttrTokenIDSecureEnclave. */ CFDataRef SecKeyCreateAttestation(SecKeyRef key, SecKeyRef keyToAttest, CFErrorRef *error) -__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)); /*! @function SecKeySetParameter @@ -774,11 +761,30 @@ __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AV 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) -__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +API_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)); +/*! + 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)); + +/*! + @function SecKeyControlLifetime + @abstract Performs key lifetime control operations for SEP system keys. + + @param key Key to be controlled, currently must be either proposed or committed system UIK. + @param type Type of the control operation to be performed. + @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)); + /*! @function SecKeyCreateDuplicate @abstract Creates duplicate fo the key. @@ -790,7 +796,7 @@ API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); If the key is immutable (i.e. does not support SecKeySetParameter), calling this method is identical to calling CFRetain(). */ SecKeyRef SecKeyCreateDuplicate(SecKeyRef key) -__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)); /*! Algorithms for converting between bigendian and core-crypto ccunit data representation. diff --git a/keychain/SecKeyProxy.h b/keychain/SecKeyProxy.h new file mode 100644 index 00000000..00018298 --- /dev/null +++ b/keychain/SecKeyProxy.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2006-2010,2012-2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/*! + @header SecKeyProxy + Declaration of SecKey proxy object allowing SecKeyRef to be accessed remotely through XPC. + */ + +#ifndef _SECURITY_SECKEYPROXY_H_ +#define _SECURITY_SECKEYPROXY_H_ + +#import +#include +#include + +NS_ASSUME_NONNULL_BEGIN + +@interface SecKeyProxy : NSObject { +@private + id _key; + NSData * _Nullable _certificate; + NSXPCListener *_listener; +} + +// Creates new proxy instance. Proxy holds reference to the target key or identity and allows remote access to that target key as long as the proxy instance is kept alive. +- (instancetype)initWithKey:(SecKeyRef)key; +- (instancetype)initWithIdentity:(SecIdentityRef)identity; + +// Retrieve endpoint to this proxy instance. Endpoint can be transferred over NSXPCConnection and passed to +[createKeyFromEndpoint:error:] method. +@property (readonly, nonatomic) NSXPCListenerEndpoint *endpoint; + +// Invalidates all connections to this proxy. +- (void)invalidate; + +// Creates new SecKey/SecIdentity object which forwards all operations to the target SecKey identified by endpoint. Returned SecKeyRef can be used as long as target SecKeyProxy instance is kept alive. ++ (nullable SecKeyRef)createKeyFromEndpoint:(NSXPCListenerEndpoint *)endpoint error:(NSError **)error; ++ (nullable SecIdentityRef)createIdentityFromEndpoint:(NSXPCListenerEndpoint *)endpoint error:(NSError **)error; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* !_SECURITY_SECKEYPROXY_H_ */ diff --git a/keychain/SecSharedCredential.h b/keychain/SecSharedCredential.h index 822a3f3c..21a89444 100644 --- a/keychain/SecSharedCredential.h +++ b/keychain/SecSharedCredential.h @@ -52,8 +52,7 @@ CF_IMPLICIT_BRIDGING_ENABLED shared password. You use this key to get a value of type CFStringRef that contains a password. */ -extern const CFStringRef kSecSharedPassword - __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE; +extern const CFStringRef kSecSharedPassword API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macos, iosmac, tvos, watchos); /*! @function SecAddSharedWebCredential @@ -67,8 +66,7 @@ extern const CFStringRef kSecSharedPassword Note: since a request involving shared web credentials may potentially require user interaction or other verification to be approved, this function is dispatched asynchronously; your code provides a completion handler that will be called once the results (if any) are available. */ void SecAddSharedWebCredential(CFStringRef fqdn, CFStringRef account, CFStringRef __nullable password, - void (^completionHandler)(CFErrorRef __nullable error)) - __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE; + void (^completionHandler)(CFErrorRef __nullable error)) API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macos, iosmac, tvos, watchos); /*! @function SecRequestSharedWebCredential @@ -89,8 +87,7 @@ void SecAddSharedWebCredential(CFStringRef fqdn, CFStringRef account, CFStringRe Note: since a request involving shared web credentials may potentially require user interaction or other verification to be approved, this function is dispatched asynchronously; your code provides a completion handler that will be called once the results (if any) are available. */ void SecRequestSharedWebCredential(CFStringRef __nullable fqdn, CFStringRef __nullable account, - void (^completionHandler)(CFArrayRef __nullable credentials, CFErrorRef __nullable error)) - __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE; + void (^completionHandler)(CFArrayRef __nullable credentials, CFErrorRef __nullable error)) API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macos, iosmac, tvos, watchos); /*! @function SecCreateSharedWebCredentialPassword @@ -98,8 +95,7 @@ void SecRequestSharedWebCredential(CFStringRef __nullable fqdn, CFStringRef __nu @return CFStringRef password in the form xxx-xxx-xxx-xxx where x is taken from the sets "abcdefghkmnopqrstuvwxy", "ABCDEFGHJKLMNPQRSTUVWXYZ", "3456789" with at least one character from each set being present. */ __nullable -CFStringRef SecCreateSharedWebCredentialPassword(void) - __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE; +CFStringRef SecCreateSharedWebCredentialPassword(void) API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macos, iosmac, tvos, watchos); #endif /* __BLOCKS__ */ diff --git a/keychain/Signin Metrics/Resources/SFTMTests-Info.plist b/keychain/Signin Metrics/Resources/SFTMTests-Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/keychain/Signin Metrics/Resources/SFTMTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h b/keychain/Signin Metrics/SFSignInAnalytics+Internal.h similarity index 53% rename from KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h rename to keychain/Signin Metrics/SFSignInAnalytics+Internal.h index 22a7da7e..9801140a 100644 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h +++ b/keychain/Signin Metrics/SFSignInAnalytics+Internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2017 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,14 +21,22 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if __OBJC2__ +#ifndef SFSignInAnalytics_Internal_h +#define SFSignInAnalytics_Internal_h -#import "IDSProxy.h" +#import "SFSignInAnalytics.h" -@interface KeychainSyncingOverIDSProxy (SendMessage) --(BOOL) sendFragmentedIDSMessages:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) ourPeerID senderDeviceID:(NSString*)senderDeviceID error:(NSError**) error; --(BOOL) sendIDSMessage:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) peerID senderDeviceID:(NSString*)senderDeviceID; --(void) ackTimerFired:(NSString*)identifier deviceID:(NSString*)deviceID; --(void) setMessageTimer:(NSString*)identifier deviceID:(NSString*)deviceID message:(NSDictionary*)message; -- (void)pingTimerFired:(NSString*)deviceID peerID:(NSString*)peerID identifier:(NSString*)identifier; --(void) pingDevices:(NSArray*)list peerID:(NSString*)peerID; +@interface SFSignInAnalytics (Internal) +@property (readonly) NSString *signin_uuid; +@property (readonly) NSString *my_uuid; +-(instancetype) initChildWithSignInUUID:(NSString*)signin_uuid andCategory:(NSString*)category andEventName:(NSString*)eventName; @end + +@interface SFSIALoggerObject : SFAnalytics ++ (instancetype)logger; +- (instancetype)init NS_UNAVAILABLE; +@end + +#endif /* SFSignInAnalytics+Internal_h */ +#endif diff --git a/keychain/Signin Metrics/SFSignInAnalytics.h b/keychain/Signin Metrics/SFSignInAnalytics.h new file mode 100644 index 00000000..2863a4d3 --- /dev/null +++ b/keychain/Signin Metrics/SFSignInAnalytics.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ +#ifndef SignInAnalytics_h +#define SignInAnalytics_h + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SFSignInAnalytics : NSObject + +@property (readonly) NSString* eventName; +@property (readonly) NSString* category; +@property (readonly) BOOL stopped; + +/* + abstract: creates a new SignInAnalytics object, automatically starts a timer for this task. + uuid: iCloud sign in transaction UUID + category: name of client subsystem. This will be used as the category name when logging + eventName: name of the event we are measuring + */ +- (instancetype _Nullable)initWithSignInUUID:(NSString *)uuid category:(NSString *)category eventName:(NSString*)eventName; +- (instancetype)init NS_UNAVAILABLE; + +/* + abstract: creates a new SignInAnalytics that starts a timer for the subtask. + ideal for fine grained timing of sub events and automatically creates a dependency chain. + eventNmae: name of the event being timed + */ +- (SFSignInAnalytics* _Nullable)newSubTaskForEvent:(NSString*)eventName; + +/* + abstract: call to log when a recoverable error occurs during sign in + error: error that occured during iCloud Sign in + */ +- (void)logRecoverableError:(NSError*)error; + +/* + abstract: call to log when a unrecoverable error occurs during sign in + error: error that occured during iCloud Sign in + */ +- (void)logUnrecoverableError:(NSError*)error; + +/* + abstract: call to cancel the timer object. + */ +- (void)cancel; + +/* + abstract: call to stop a timer and log the time spent. + eventName: subsystem name + attributes: a dictionary containing event attributes + */ +- (void)stopWithAttributes:(NSDictionary* _Nullable)attributes; + +/* + abstract: call to signal iCloud sign in has finished. + */ +- (void)signInCompleted; + +@end +NS_ASSUME_NONNULL_END +#endif /* SignInAnalytics_h */ +#endif diff --git a/keychain/Signin Metrics/SFSignInAnalytics.m b/keychain/Signin Metrics/SFSignInAnalytics.m new file mode 100644 index 00000000..d134231e --- /dev/null +++ b/keychain/Signin Metrics/SFSignInAnalytics.m @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import "SFSignInAnalytics.h" +#import "SFSignInAnalytics+Internal.h" + +#import +#import "SFAnalyticsDefines.h" +#import "SFAnalyticsSQLiteStore.h" +#import "SFAnalytics.h" + +#import +#import +#import +#import +#import + +//metrics database location +NSString* signinMetricsDatabase = @"signin_metrics"; + +//defaults write results location +static NSString* const SFSignInAnalyticsDumpLoggedResultsToLocation = @"/tmp/signin_results.txt"; +static NSString* const SFSignInAnalyticsPersistedEventList = @"/tmp/signin_eventlist"; + +//analytics constants +static NSString* const SFSignInAnalyticsAttributeRecoverableError = @"recoverableError"; +static NSString* const SFSignInAnalyticsAttributeErrorDomain = @"errorDomain"; +static NSString* const SFSignInAnalyticsAttributeErrorCode = @"errorCode"; +static NSString* const SFSignInAnalyticsAttributeErrorChain = @"errorChain"; +static NSString* const SFSignInAnalyticsAttributeParentUUID = @"parentUUID"; +static NSString* const SFSignInAnalyticsAttributeMyUUID = @"myUUID"; +static NSString* const SFSignInAnalyticsAttributeSignInUUID = @"signinUUID"; +static NSString* const SFSignInAnalyticsAttributeEventName = @"eventName"; +static NSString* const SFSignInAnalyticsAttributeSubsystemName = @"subsystemName"; +static NSString* const SFSignInAnalyticsAttributeBuiltDependencyChains = @"dependencyChains"; + +@implementation SFSIALoggerObject ++ (NSString*)databasePath { + return [SFSIALoggerObject defaultAnalyticsDatabasePath:signinMetricsDatabase]; +} + ++ (instancetype)logger +{ + return [super logger]; +} +@end + + +@interface SFSignInAnalytics () +@property (nonatomic, copy) NSString *signin_uuid; +@property (nonatomic, copy) NSString *my_uuid; +@property (nonatomic, copy) NSString *parent_uuid; +@property (nonatomic, copy) NSString *category; +@property (nonatomic, copy) NSString *eventName; +@property (nonatomic, copy) NSString *persistencePath; + +@property (nonatomic, strong) NSURL *persistedEventPlist; +@property (nonatomic, strong) NSMutableDictionary *eventDependencyList; +@property (nonatomic, strong) NSMutableArray *builtDependencyChains; + +@property (nonatomic) BOOL canceled; +@property (nonatomic) BOOL stopped; + +@property (nonatomic, strong) os_log_t logObject; + +@property (nonatomic, strong) NSNumber *measurement; + +@property (nonatomic, strong) dispatch_queue_t queue; + +@property (nonatomic, strong) SFSignInAnalytics *root; +@property (nonatomic, strong) SFAnalyticsActivityTracker *tracker; + +-(os_log_t) newLogForCategoryName:(NSString*) category; +-(os_log_t) logForCategoryName:(NSString*) category; + +@end + +static NSMutableDictionary *logObjects; +static const NSString* signInLogSpace = @"com.apple.security.wiiss"; + +@implementation SFSignInAnalytics + ++ (BOOL)supportsSecureCoding { + return YES; +} + +-(os_log_t) logForCategoryName:(NSString*) category +{ + return logObjects[category]; +} + +-(os_log_t) newLogForCategoryName:(NSString*) category +{ + return os_log_create([signInLogSpace UTF8String], [category UTF8String]); +} + +- (BOOL)writeDependencyList:(NSError**)error +{ + NSError *localError = nil; + if (![NSPropertyListSerialization propertyList: self.root.eventDependencyList isValidForFormat: NSPropertyListXMLFormat_v1_0]){ + os_log_error(self.logObject, "can't save PersistentState as XML"); + return false; + } + + NSData *data = [NSPropertyListSerialization dataWithPropertyList: self.root.eventDependencyList + format: NSPropertyListXMLFormat_v1_0 options: 0 error: &localError]; + if (data == nil){ + os_log_error(self.logObject, "error serializing PersistentState to xml: %@", localError); + return false; + } + + BOOL writeStatus = [data writeToURL:self.root.persistedEventPlist options: NSDataWritingAtomic error: &localError]; + if (!writeStatus){ + os_log_error(self.logObject, "error writing PersistentState to file: %@", localError); + } + if(localError && error){ + *error = localError; + } + + return writeStatus; +} + +- (instancetype)initWithSignInUUID:(NSString *)uuid category:(NSString *)category eventName:(NSString*)eventName +{ + self = [super init]; + if (self) { + _signin_uuid = uuid; + + _my_uuid = uuid; + _parent_uuid = uuid; + _eventName = eventName; + _category = category; + _root = self; + _canceled = NO; + _stopped = NO; + _builtDependencyChains = [NSMutableArray array]; + + //make plist file containing uuid parent/child + _persistencePath = [NSString stringWithFormat:@"%@-%@.plist", SFSignInAnalyticsPersistedEventList, eventName]; + _persistedEventPlist = [NSURL fileURLWithPath:_persistencePath isDirectory:NO]; + + _eventDependencyList = [NSMutableDictionary dictionary]; + [_eventDependencyList setObject:[NSMutableArray array] forKey:_signin_uuid]; + + _tracker = [[SFSIALoggerObject logger] logSystemMetricsForActivityNamed:eventName withAction:nil]; + [_tracker start]; + + NSError* error = nil; + if(![self writeDependencyList:&error]){ + os_log(self.logObject, "attempting to write dependency list: %@", error); + } + + _queue = dispatch_queue_create("com.apple.security.SignInAnalytics", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + logObjects = [NSMutableDictionary dictionary]; + }); + @synchronized(logObjects){ + if(category){ + _logObject = [self logForCategoryName:category]; + + if(!_logObject){ + _logObject = [self newLogForCategoryName:category]; + [logObjects setObject:_logObject forKey:category]; + } + } + } + } + return self; +} + +-(instancetype) initChildWithSignInUUID:(NSString*)uuid andCategory:(NSString*)category andEventName:(NSString*)eventName +{ + self = [super init]; + if (self) { + _signin_uuid = uuid; + + _my_uuid = uuid; + _parent_uuid = uuid; + _eventName = eventName; + _category = category; + _canceled = NO; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:_signin_uuid forKey:@"UUID"]; + [coder encodeObject:_category forKey:@"category"]; + [coder encodeObject:_parent_uuid forKey:@"parentUUID"]; + [coder encodeObject:_my_uuid forKey:@"myUUID"]; + [coder encodeObject:_measurement forKey:@"measurement"]; + [coder encodeObject:_eventName forKey:@"eventName"]; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)decoder +{ + self = [super init]; + if (self) { + _signin_uuid = [decoder decodeObjectOfClass:[NSString class] forKey:@"UUID"]; + _category = [decoder decodeObjectOfClass:[NSString class] forKey:@"category"]; + _parent_uuid = [decoder decodeObjectOfClass:[NSString class] forKey:@"parentUUID"]; + _my_uuid = [decoder decodeObjectOfClass:[NSString class] forKey:@"myUUID"]; + _measurement = [decoder decodeObjectOfClass:[NSString class] forKey:@"measurement"]; + _eventName = [decoder decodeObjectOfClass:[NSString class] forKey:@"eventName"]; + _queue = dispatch_queue_create("com.apple.security.SignInAnalytics", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + + if(_signin_uuid == nil || + _category == nil || + _parent_uuid == nil){ + [decoder failWithError:[NSError errorWithDomain:@"securityd" code:errSecDecode userInfo:@{NSLocalizedDescriptionKey: @"Failed to decode SignInAnalytics object"}]]; + return nil; + } + } + return self; +} + +- (SFSignInAnalytics*)newSubTaskForEvent:(NSString*)eventName +{ + SFSignInAnalytics *newSubTask = [[SFSignInAnalytics alloc] initChildWithSignInUUID:self.signin_uuid andCategory:self.category andEventName:self.eventName]; + if(newSubTask){ + newSubTask.my_uuid = [NSUUID UUID].UUIDString; + newSubTask.parent_uuid = self.my_uuid; + newSubTask.signin_uuid = self.signin_uuid; + + newSubTask.category = self.category; + newSubTask.eventName = [eventName copy]; + newSubTask.root = self.root; + newSubTask.canceled = NO; + newSubTask.stopped = NO; + + newSubTask.queue = dispatch_queue_create("com.apple.security.SignInAnalytics", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + newSubTask.tracker = [[SFSIALoggerObject logger] logSystemMetricsForActivityNamed:eventName withAction:nil]; + [newSubTask.tracker start]; + + @synchronized(_eventDependencyList){ + NSMutableArray *parentEntry = [newSubTask.root.eventDependencyList objectForKey:newSubTask.parent_uuid]; + + //add new subtask entry to parent event's list + [parentEntry addObject:newSubTask.my_uuid]; + [newSubTask.root.eventDependencyList setObject:parentEntry forKey:newSubTask.parent_uuid]; + + //create new array list for this new subtask incase it has subtasks + [newSubTask.root.eventDependencyList setObject:[NSMutableArray array] forKey:newSubTask.my_uuid]; + NSError* error = nil; + if(![newSubTask writeDependencyList:&error]){ + os_log(self.logObject, "attempting to write dependency list: %@", error); + } + } + } + + return newSubTask; +} + +- (void)logRecoverableError:(NSError*)error +{ + + if (error == nil){ + os_log_error(self.logObject, "attempting to log a nil error for event:%@", self.eventName); + return; + } + + os_log_error(self.logObject, "%@", error); + + NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary]; + + [eventAttributes setValuesForKeysWithDictionary:@{ + SFSignInAnalyticsAttributeRecoverableError : @(YES), + SFSignInAnalyticsAttributeErrorDomain : error.domain, + SFSignInAnalyticsAttributeErrorCode : @(error.code), + SFSignInAnalyticsAttributeMyUUID : self.my_uuid, + SFSignInAnalyticsAttributeParentUUID : self.parent_uuid, + SFSignInAnalyticsAttributeSignInUUID : self.signin_uuid, + SFSignInAnalyticsAttributeEventName : self.eventName, + SFSignInAnalyticsAttributeSubsystemName : self.category + }]; + + [[SFSIALoggerObject logger] logSoftFailureForEventNamed:self.eventName withAttributes:eventAttributes]; + +} + +- (void)logUnrecoverableError:(NSError*)error +{ + if (error == nil){ + os_log_error(self.logObject, "attempting to log a nil error for event:%@", self.eventName); + return; + } + + os_log_error(self.logObject, "%@", error); + + NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary]; + + [eventAttributes setValuesForKeysWithDictionary:@{ + SFSignInAnalyticsAttributeRecoverableError : @(NO), + SFSignInAnalyticsAttributeErrorDomain : error.domain, + SFSignInAnalyticsAttributeErrorCode : @(error.code), + SFSignInAnalyticsAttributeMyUUID : self.my_uuid, + SFSignInAnalyticsAttributeParentUUID : self.parent_uuid, + SFSignInAnalyticsAttributeSignInUUID : self.signin_uuid, + SFSignInAnalyticsAttributeEventName : self.eventName, + SFSignInAnalyticsAttributeSubsystemName : self.category + }]; + + [[SFSIALoggerObject logger] logHardFailureForEventNamed:self.eventName withAttributes:eventAttributes]; +} + +-(void)cancel +{ + dispatch_sync(self.queue, ^{ + [self.tracker cancel]; + self.canceled = YES; + os_log(self.logObject, "canceled timer for %@", self.eventName); + }); +} + +- (void)stopWithAttributes:(NSDictionary*)attributes +{ + dispatch_sync(self.queue, ^{ + + if(self.canceled || self.stopped){ + return; + } + + self.stopped = YES; + + [self.tracker stop]; + + NSMutableDictionary *mutableAttributes = nil; + + if(attributes){ + mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes]; + } + else{ + mutableAttributes = [NSMutableDictionary dictionary]; + } + mutableAttributes[SFSignInAnalyticsAttributeMyUUID] = self.my_uuid; + mutableAttributes[SFSignInAnalyticsAttributeParentUUID] = self.parent_uuid; + mutableAttributes[SFSignInAnalyticsAttributeSignInUUID] = self.signin_uuid; + mutableAttributes[SFSignInAnalyticsAttributeEventName] = self.eventName; + mutableAttributes[SFSignInAnalyticsAttributeSubsystemName] = self.category; + + [mutableAttributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id obj, BOOL * stop) { + os_log(self.logObject, "event: %@, %@ : %@", self.eventName, key, obj); + }]; + + [[SFSIALoggerObject logger] logSuccessForEventNamed:self.eventName]; + [[SFSIALoggerObject logger] logSoftFailureForEventNamed:self.eventName withAttributes:mutableAttributes]; + }); +} + +-(BOOL) writeResultsToTmp { + + bool shouldWriteResultsToTemp = NO; + CFBooleanRef toTmp = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("DumpResultsToTemp"), + CFSTR("com.apple.security"), + kCFPreferencesAnyUser, kCFPreferencesAnyHost); + if(toTmp && CFGetTypeID(toTmp) == CFBooleanGetTypeID()){ + if(toTmp == kCFBooleanFalse){ + os_log(self.logObject, "writing results to splunk"); + shouldWriteResultsToTemp = NO; + } + if(toTmp == kCFBooleanTrue){ + os_log(self.logObject, "writing results to /tmp"); + shouldWriteResultsToTemp = YES; + } + } + + CFReleaseNull(toTmp); + return shouldWriteResultsToTemp; +} + +- (void)processEventChainForUUID:(NSString*)uuid dependencyChain:(NSString*)dependencyChain +{ + NSString* newChain = dependencyChain; + + NSArray* children = [self.root.eventDependencyList objectForKey:uuid]; + for (NSString* child in children) { + newChain = [NSString stringWithFormat:@"%@, %@", dependencyChain, child]; + [self processEventChainForUUID:child dependencyChain:newChain]; + } + if([children count] == 0){ + [self.root.builtDependencyChains addObject:newChain]; + os_log(self.logObject, "current dependency chain list: %@", newChain); + } +} + +- (void)signInCompleted +{ + //print final + os_log(self.logObject, "sign in complete"); + NSError* error = nil; + + //create dependency chains and log them + [self processEventChainForUUID:self.root.my_uuid dependencyChain:self.root.signin_uuid]; + //write to database + if([self.root.builtDependencyChains count] > 0){ + NSDictionary* eventAttributes = @{SFSignInAnalyticsAttributeBuiltDependencyChains : self.root.builtDependencyChains}; + [[SFSIALoggerObject logger] logSoftFailureForEventNamed:SFSignInAnalyticsAttributeBuiltDependencyChains withAttributes:eventAttributes]; + } + + BOOL writingToTmp = [self writeResultsToTmp]; + if(writingToTmp){ //writing sign in analytics to /tmp + os_log(self.logObject, "logging to /tmp"); + + NSData* eventData = [NSKeyedArchiver archivedDataWithRootObject:[[SFSIALoggerObject logger].database allEvents] requiringSecureCoding:YES error:&error]; + if(eventData){ + [eventData writeToFile:SFSignInAnalyticsDumpLoggedResultsToLocation options:0 error:&error]; + + if(error){ + os_log_error(self.logObject, "error writing to file [%@], error:%@", SFSignInAnalyticsDumpLoggedResultsToLocation, error); + }else{ + os_log(self.logObject, "successfully wrote sign in analytics to:%@", SFSignInAnalyticsDumpLoggedResultsToLocation); + } + }else{ + os_log_error(self.logObject, "collected no data"); + } + }else{ //writing to splunk + os_log(self.logObject, "logging to splunk"); + } + + //remove dependency list + BOOL removedPersistedDependencyList = [[NSFileManager defaultManager] removeItemAtPath:self.persistencePath error:&error]; + + if(!removedPersistedDependencyList || error){ + os_log(self.logObject, "encountered error when attempting to remove persisted event list: %@", error); + } + +} + +@end +#endif + diff --git a/keychain/Signin Metrics/SFTransactionMetric.h b/keychain/Signin Metrics/SFTransactionMetric.h deleted file mode 100644 index 6fd9876d..00000000 --- a/keychain/Signin Metrics/SFTransactionMetric.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if __OBJC2__ -#ifndef SFTransactionMetric_h -#define SFTransactionMetric_h - -#import - -@interface SFTransactionMetric : NSObject - -/* - abstract: creates a new SFTransactionMetric object - uuid: iCloud sign in transaction UUID - category: name of client subsystem. This will be used as the category name when logging -*/ -- (instancetype)initWithUUID:(NSString *)uuid category:(NSString *)category; - -/* - abstract: log when a particular event occurs ex. piggybacking, restore from backup - eventName: name of the event that occured - arguments: dictionary containing a set of event attributes a subsystem wishes to log. -*/ -- (void)logEvent:(NSString*)eventName eventAttributes:(NSDictionary*)attributes; - -/* - abstract: call to time tasks that take a while (backup, wait for initial sync) - eventName: name of the event that occured - blockToTime: the block of code you wish to have timed -*/ -- (void)timeEvent:(NSString*)eventName blockToTime:(void(^)(void))blockToTime; - -/* - abstract: call to log when a error occurs during sign in - error: error that occured during iCloud Sign in -*/ -- (void)logError:(NSError*)error; - -/* - abstract: call to signal iCloud sign in has finished. - */ -- (void)signInCompleted; - -@end - - -#endif /* SFTransactionMetric_h */ -#endif diff --git a/keychain/Signin Metrics/SFTransactionMetric.m b/keychain/Signin Metrics/SFTransactionMetric.m deleted file mode 100644 index 74ee8219..00000000 --- a/keychain/Signin Metrics/SFTransactionMetric.m +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if __OBJC2__ - -#import "SFTransactionMetric.h" -#import - -@interface SFTransactionMetric () -@property (nonatomic, copy) NSString *uuid; -@property (nonatomic, copy) NSString *category; -@property (nonatomic, strong) os_log_t logObject; - --(os_log_t) sftmCreateLogCategory:(NSString*) category; --(os_log_t) sftmObjectForCategory:(NSString*) category; -@end - -static NSMutableDictionary *logObjects; -static const NSString* signInLogSpace = @"com.apple.security.wiiss"; - -@implementation SFTransactionMetric - -+ (BOOL)supportsSecureCoding { - return YES; -} - --(os_log_t) sftmObjectForCategory:(NSString*) category -{ - return logObjects[category]; -} - --(os_log_t) sftmCreateLogCategory:(NSString*) category -{ - return os_log_create([signInLogSpace UTF8String], [category UTF8String]); -} - -- (instancetype)initWithUUID:(NSString *)uuid category:(NSString *)category -{ - self = [super init]; - if (self) { - _uuid = uuid; - _category = category; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - logObjects = [NSMutableDictionary dictionary]; - }); - @synchronized(logObjects){ - if(category){ - _logObject = [self sftmObjectForCategory:category]; - - if(!_logObject){ - _logObject = [self sftmCreateLogCategory:category]; - [logObjects setObject:_logObject forKey:category]; - } - } - } - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder { - [coder encodeObject:_uuid forKey:@"UUID"]; - [coder encodeObject:_category forKey:@"category"]; -} - -- (nullable instancetype)initWithCoder:(NSCoder *)decoder -{ - self = [super init]; - if (self) { - _uuid = [decoder decodeObjectOfClass:[NSString class] forKey:@"UUID"]; - _category = [decoder decodeObjectOfClass:[NSString class] forKey:@"category"]; - } - return self; -} - -- (void)logEvent:(NSString*)eventName eventAttributes:(NSDictionary*)attributes -{ - [attributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id obj, BOOL * stop) { - os_log(self.logObject, "event: %@, %@ : %@", eventName, key, obj); - }]; -} - -- (void)timeEvent:(NSString*)eventName blockToTime:(void(^)(void))blockToTime -{ - NSDate *firstTime = [NSDate date]; - - blockToTime(); - - NSDate *SecondTime = [NSDate date]; - - os_log(self.logObject, "event: %@, Time elapsed: %@", eventName, [[NSString alloc] initWithFormat:@"%f", [SecondTime timeIntervalSinceDate:firstTime]]); -} - -- (void)logError:(NSError*)error -{ - os_log_error(self.logObject, "%@", error); -} - -- (void)signInCompleted -{ - //print final - os_log(self.logObject, "sign in complete for %@", self.uuid); -} - -@end -#endif diff --git a/keychain/Signin Metrics/tests/SFSignInAnalyticsTests.m b/keychain/Signin Metrics/tests/SFSignInAnalyticsTests.m new file mode 100644 index 00000000..b9db4c95 --- /dev/null +++ b/keychain/Signin Metrics/tests/SFSignInAnalyticsTests.m @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#import "keychain/Signin Metrics/SFSignInAnalytics.h" +#import "keychain/Signin Metrics/SFSignInAnalytics+Internal.h" +#import "keychain/ot/OTDefines.h" +#import "SFAnalytics+Signin.h" +#import + +static NSInteger _testnum; +static NSString* _path; + +@interface SFSignInAnalyticsTester : SFSignInAnalytics +-(instancetype)init; +@end + +@implementation SFSignInAnalyticsTester + ++ (NSString*)databasePath { + return _path; +} + +-(instancetype)init +{ + self = [super initWithSignInUUID:[NSUUID UUID].UUIDString category:@"CoreCDP" eventName:@"signin"]; + + return self; +} + +@end + + +@interface SignInAnalyticsTests : XCTestCase +@property (nonatomic) SFSignInAnalyticsTester *metric; +@end + +@implementation SignInAnalyticsTests + + +- (void)setUp { + [super setUp]; + _testnum = 0; + self.continueAfterFailure = NO; + _path = [@"/tmp" stringByAppendingFormat:@"/test_%ld.db", (long)++_testnum]; + _metric = [[SFSignInAnalyticsTester alloc] init]; + XCTAssertNotNil(_metric, "SignInAnalyticsTester object should not be nil"); +} + +- (void)tearDown +{ + dispatch_async([SFSIALoggerObject logger].queue, ^{ + [[SFSIALoggerObject logger].database executeSQL:@"delete from all_events"]; + [[SFSIALoggerObject logger].database executeSQL:@"delete from soft_failures"]; + [[SFSIALoggerObject logger].database executeSQL:@"delete from hard_failures"]; + }); + + [[SFSIALoggerObject logger] removeState]; + _metric = nil; + [super tearDown]; +} + +- (void)testStop +{ + sleep(2); + NSDictionary *attributes = @{@"success": @YES, + @"takenFlow" : @"restore", + }; + XCTAssertNotNil(attributes, "attributes dictionary should exist"); + + [_metric stopWithAttributes:attributes]; + + NSArray* results = [[SFSIALoggerObject logger].database allEvents]; + + XCTAssertEqual([results count], 2, @"should have 2 results"); + +} + +- (void)testCancel +{ + [_metric cancel]; +} + +- (void)testLogError +{ + NSError* error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorBottleID userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}]; + [_metric logRecoverableError:error]; + NSArray* results = [[SFSIALoggerObject logger].database softFailures]; + XCTAssertEqual([results count], 1, @"should have 1 results"); +} + +- (void)testCreateNewSubtask +{ + SFSignInAnalytics* child = [_metric newSubTaskForEvent:@"restore"]; + XCTAssertNotNil(child, "child should be created"); + [[SFSIALoggerObject logger] removeState]; + child = nil; +} + + +- (void)testCreateNewSubtaskAndStop +{ + SFSignInAnalytics* child = [_metric newSubTaskForEvent:@"restore"]; + + sleep(2); + NSDictionary *attributes = @{@"success": @YES, + @"takenFlow" : @"piggyback", + }; + + [child stopWithAttributes:attributes]; + + XCTAssertNotNil(child, "child should be created"); + + NSArray* results = [[SFSIALoggerObject logger].database allEvents]; + + XCTAssertEqual([results count], 2, @"should have 2 results"); + + [[SFSIALoggerObject logger] removeState]; + child = nil; +} + +- (void)testStopAfterCancel +{ + sleep(2); + NSDictionary *attributes = @{@"success": @YES, + @"takenFlow" : @"piggyback", + }; + XCTAssertNotNil(attributes, "attributes dictionary should exist"); + + [_metric cancel]; + + [_metric stopWithAttributes:attributes]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + + XCTAssertEqual([allEvents count], 0, @"should have 0 things logged"); +} + +- (void)testStopAfterStop +{ + sleep(2); + NSDictionary *attributes = @{@"success": @YES, + @"takenFlow" : @"piggyback", + }; + XCTAssertNotNil(attributes, "attributes dictionary should exist"); + + [_metric stopWithAttributes:attributes]; + + [_metric stopWithAttributes:attributes]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + + XCTAssertEqual([allEvents count], 2, @"should have 2 things logged"); +} + +-(void)testSignInComplete +{ + NSDictionary* attributes = [NSDictionary dictionary]; + [_metric stopWithAttributes:attributes]; + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array should not be nil"); + XCTAssertTrue(allEvents && [allEvents count] > 0, "array should not be nil and contain an entry"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + XCTAssertTrue(dependencyEntry && [dependencyEntry count] > 0, "dictionary should not be nil and contain an entry"); + + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + + XCTAssertEqual([chains count], 1, "should be one list"); + + XCTAssertTrue([chains containsObject:_metric.signin_uuid], "should contain 1 uuid"); +} + +-(void)testSingleChainDependencyList +{ + SFSignInAnalytics* child1 = [_metric newSubTaskForEvent:@"piggyback"]; + XCTAssertNotNil(child1, "child1 should be created"); + + SFSignInAnalytics* child2 = [child1 newSubTaskForEvent:@"initialsync"]; + XCTAssertNotNil(child2, "child2 should be created"); + + SFSignInAnalytics* child3 = [child2 newSubTaskForEvent:@"backup"]; + XCTAssertNotNil(child3, "child3 should be created"); + + SFSignInAnalytics* child4 = [child3 newSubTaskForEvent:@"processing one ring"]; + XCTAssertNotNil(child4, "child4 should be created"); + + [_metric signInCompleted]; + + NSString *expectedChain = [NSString stringWithFormat:@"%@, %@, %@, %@, %@", child1.signin_uuid, child1.my_uuid, child2.my_uuid, child3.my_uuid, child4.my_uuid]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "should not be nil"); + XCTAssertTrue([allEvents count] > 0, "should be events"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + + XCTAssertEqual([chains count], 1, "should be one list"); + XCTAssertTrue([expectedChain isEqualToString:[chains objectAtIndex:0]], "chains should be the same"); + + child1 = nil; + child2 = nil; + child3 = nil; + child4 = nil; + + child1 = nil; + child2 = nil; + child3 = nil; + child4 = nil; +} + +-(void)testMultipleChildrenPerEvent +{ + SFSignInAnalytics* child1 = [_metric newSubTaskForEvent:@"piggyback"]; + XCTAssertNotNil(child1, "child1 should be created"); + + SFSignInAnalytics* child2 = [child1 newSubTaskForEvent:@"initialsync"]; + XCTAssertNotNil(child2, "child2 should be created"); + + SFSignInAnalytics* child3 = [child1 newSubTaskForEvent:@"backup"]; + XCTAssertNotNil(child3, "child3 should be created"); + + SFSignInAnalytics* child4 = [child1 newSubTaskForEvent:@"processing one ring"]; + XCTAssertNotNil(child4, "child4 should be created"); + + SFSignInAnalytics* child5 = [child2 newSubTaskForEvent:@"processing second ring"]; + XCTAssertNotNil(child5, "child5 should be created"); + + SFSignInAnalytics* child6 = [child2 newSubTaskForEvent:@"processing third ring"]; + XCTAssertNotNil(child6, "child6 should be created"); + + SFSignInAnalytics* child7 = [child2 newSubTaskForEvent:@"processing fourth ring"]; + XCTAssertNotNil(child7, "child7 should be created"); + + SFSignInAnalytics* child8 = [child7 newSubTaskForEvent:@"processing fifth ring"]; + XCTAssertNotNil(child8, "child8 should be created"); + + SFSignInAnalytics* child9 = [child7 newSubTaskForEvent:@"processing one ring"]; + XCTAssertNotNil(child9, "child9 should be created"); + + NSString *expectedChain = [NSString stringWithFormat:@"%@, %@, %@, %@", _metric.signin_uuid, child1.my_uuid, child2.my_uuid, child5.my_uuid]; + + NSString *expectedChain1 = [NSString stringWithFormat:@"%@, %@, %@", _metric.signin_uuid, child1.my_uuid, child3.my_uuid]; + + NSString *expectedChain2 = [NSString stringWithFormat:@"%@, %@, %@", _metric.signin_uuid, child1.my_uuid, child4.my_uuid]; + + NSString *expectedChain3 = [NSString stringWithFormat:@"%@, %@, %@, %@", _metric.signin_uuid, child1.my_uuid, child2.my_uuid, child5.my_uuid]; + + NSString *expectedChain4 = [NSString stringWithFormat:@"%@, %@, %@, %@, %@", _metric.signin_uuid, child1.my_uuid, child2.my_uuid, child7.my_uuid, child8.my_uuid]; + + NSString *expectedChain5 = [NSString stringWithFormat:@"%@, %@, %@, %@, %@", _metric.signin_uuid, child1.my_uuid, child2.my_uuid, child7.my_uuid, child9.my_uuid]; + + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array is not nil"); + XCTAssertTrue([allEvents count] > 0, "array should not be empty"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + + XCTAssertEqual([chains count], 6, "should be one list"); + + XCTAssertTrue([chains containsObject:expectedChain], "chains should contain expectedChain"); + XCTAssertTrue([chains containsObject:expectedChain1], "chains should contain expectedChain1"); + XCTAssertTrue([chains containsObject:expectedChain2], "chains should contain expectedChain2"); + XCTAssertTrue([chains containsObject:expectedChain3], "chains should contain expectedChain3"); + XCTAssertTrue([chains containsObject:expectedChain4], "chains should contain expectedChain4"); + XCTAssertTrue([chains containsObject:expectedChain5], "chains should contain expectedChain5"); + + [[SFSIALoggerObject logger] removeState]; + + child1 = nil; + child2 = nil; + child3 = nil; + child4 = nil; + child5 = nil; + child6 = nil; + child7 = nil; + child8 = nil; + child9 = nil; + +} + +-(void)testSOSCCWaitForInitialSync +{ + CFErrorRef error = nil; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + XCTAssertNotNil(archiver, "should not be nil"); + [_metric encodeWithCoder:archiver]; + CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData; + XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil"); + bool worked = SOSCCWaitForInitialSyncWithAnalytics(parentData, &error); + XCTAssertTrue(worked, "should have worked"); + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array is not nil"); + XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + XCTAssertNotNil(chains, "chains is not nil"); + XCTAssertEqual([chains count], 1, "array should not contain 1 entry"); +} + +-(void)testSOSCCRemoveThisDeviceFromCircle +{ + CFErrorRef error = nil; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + XCTAssertNotNil(archiver, "should not be nil"); + [_metric encodeWithCoder:archiver]; + CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData; + XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil"); + bool worked = SOSCCRemoveThisDeviceFromCircleWithAnalytics(parentData, &error); + XCTAssertTrue(worked, "should have worked"); + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array is not nil"); + XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + XCTAssertNotNil(chains, "chains is not nil"); + XCTAssertEqual([chains count], 1, "array should not contain 1 entry"); +} + +-(void)testSOSCCRequestToJoinCircle +{ + CFErrorRef error = nil; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + XCTAssertNotNil(archiver, "should not be nil"); + [_metric encodeWithCoder:archiver]; + CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData; + XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil"); + SOSCCRequestToJoinCircleWithAnalytics(parentData, &error); + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array is not nil"); + XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + XCTAssertNotNil(chains, "chains is not nil"); + XCTAssertEqual([chains count], 1, "array should not contain 1 entry"); +} + +-(void)testSOSCCRequestToJoinCircleAfterRestore +{ + CFErrorRef error = nil; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + XCTAssertNotNil(archiver, "should not be nil"); + [_metric encodeWithCoder:archiver]; + CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData; + XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil"); + SOSCCRequestToJoinCircleAfterRestoreWithAnalytics(parentData, &error); + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array is not nil"); + XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + XCTAssertNotNil(chains, "chains is not nil"); + XCTAssertEqual([chains count], 1, "array should not contain 1 entry"); +} + +-(void)testSOSCCRemovePeersFromCircle +{ + CFErrorRef error = nil; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + XCTAssertNotNil(archiver, "should not be nil"); + [_metric encodeWithCoder:archiver]; + CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData; + XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil"); + NSArray* peers = [NSArray array]; + SOSCCRemovePeersFromCircleWithAnalytics((__bridge CFArrayRef)peers, parentData, &error); + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array is not nil"); + XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + XCTAssertNotNil(chains, "chains is not nil"); + XCTAssertEqual([chains count], 1, "array should not contain 1 entry"); +} + + +-(void)testSOSCCViewSet +{ + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + XCTAssertNotNil(archiver, "should not be nil"); + [_metric encodeWithCoder:archiver]; + CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData; + XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil"); + CFSetRef enabledViews = nil; + CFSetRef disabledViews = nil; + SOSCCViewSetWithAnalytics(enabledViews, disabledViews, parentData); + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array is not nil"); + XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + XCTAssertNotNil(chains, "chains is not nil"); + XCTAssertEqual([chains count], 1, "array should not contain 1 entry"); +} + +-(void)testSOSCCSetUserCredentialsAndDSID +{ + CFErrorRef error = nil; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + XCTAssertNotNil(archiver, "should not be nil"); + [_metric encodeWithCoder:archiver]; + CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData; + XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil"); + CFStringRef label = nil; + CFDataRef password = nil; + CFStringRef dsid = nil; + SOSCCSetUserCredentialsAndDSIDWithAnalytics(label, password, dsid, parentData, &error); + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array is not nil"); + XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + XCTAssertNotNil(chains, "chains is not nil"); + XCTAssertEqual([chains count], 1, "array should not contain 1 entry"); +} + +-(void)testSOSCCResetToEmpty +{ + CFErrorRef error = nil; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + XCTAssertNotNil(archiver, "should not be nil"); + [_metric encodeWithCoder:archiver]; + CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData; + XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil"); + SOSCCResetToEmptyWithAnalytics(parentData, &error); + + [_metric signInCompleted]; + + NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents]; + XCTAssertNotNil(allEvents, "array is not nil"); + XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry"); + + NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1]; + NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"]; + XCTAssertNotNil(chains, "chains is not nil"); + XCTAssertEqual([chains count], 1, "array should not contain 1 entry"); +} + +- (void)testMultipleDBConnections +{ + NSError* error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorBottleID userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}]; + dispatch_queue_t test_queue = dispatch_queue_create("com.apple.security.signin.tests", DISPATCH_QUEUE_CONCURRENT_WITH_AUTORELEASE_POOL); + + for(int i = 0; i < 1000; i++){ + SFSignInAnalytics *test1 = [_metric newSubTaskForEvent:@"connection1"]; + SFSignInAnalytics *test2 = [_metric newSubTaskForEvent:@"connection2"]; + + dispatch_async(test_queue, ^{ + [test1 logRecoverableError:error]; + }); + dispatch_async(test_queue, ^{ + [test2 stopWithAttributes:nil]; + }); + dispatch_async(test_queue, ^{ + [self->_metric logRecoverableError:error]; + }); + } +} +@end diff --git a/keychain/analytics/CKKSPowerCollection.h b/keychain/analytics/CKKSPowerCollection.h index aa150f07..0df6e511 100644 --- a/keychain/analytics/CKKSPowerCollection.h +++ b/keychain/analytics/CKKSPowerCollection.h @@ -49,6 +49,8 @@ extern OTPowerEvent* const kOTPowerEventEnroll; + (void)CKKSPowerEvent:(CKKSPowerEvent *)operation zone:(NSString *)zone; + (void)CKKSPowerEvent:(CKKSPowerEvent *)operation zone:(NSString *)zone count:(NSUInteger)count; ++ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation count:(NSUInteger)count; + + (void)OTPowerEvent:(NSString *)operation; - (void)storedOQE:(CKKSOutgoingQueueEntry *)oqe; diff --git a/keychain/analytics/CKKSPowerCollection.m b/keychain/analytics/CKKSPowerCollection.m index 7442658c..273a677a 100644 --- a/keychain/analytics/CKKSPowerCollection.m +++ b/keychain/analytics/CKKSPowerCollection.m @@ -61,6 +61,14 @@ OTPowerEvent* const kOTPowerEventEnroll = (OTPowerEvent *)@"enrollBottledPeer"; }); } ++ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation count:(NSUInteger)count +{ + SecPLLogRegisteredEvent(@"CKKSSyncing", @{ + @"operation" : operation, + @"count" : @(count) + }); +} + + (void)OTPowerEvent:(NSString *)operation { SecPLLogRegisteredEvent(@"OctagonTrust", @{ diff --git a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h b/keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h deleted file mode 100644 index 88cd982d..00000000 --- a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h +++ /dev/null @@ -1,50 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#import - -#ifdef __cplusplus -#define AWDKEYCHAINCKKSRATELIMITERAGGREGATEDSCORES_FUNCTION extern "C" -#else -#define AWDKEYCHAINCKKSRATELIMITERAGGREGATEDSCORES_FUNCTION extern -#endif - -@interface AWDKeychainCKKSRateLimiterAggregatedScores : PBCodable -{ - PBRepeatedUInt32 _datas; - uint64_t _timestamp; - NSString *_ratelimitertype; - struct { - int timestamp:1; - } _has; -} - - -@property (nonatomic) BOOL hasTimestamp; -@property (nonatomic) uint64_t timestamp; - -@property (nonatomic, readonly) NSUInteger datasCount; -@property (nonatomic, readonly) uint32_t *datas; -- (void)clearDatas; -- (void)addData:(uint32_t)i; -- (uint32_t)dataAtIndex:(NSUInteger)idx; -- (void)setDatas:(uint32_t *)list count:(NSUInteger)count; - -@property (nonatomic, readonly) BOOL hasRatelimitertype; -@property (nonatomic, retain) NSString *ratelimitertype; - -// Performs a shallow copy into other -- (void)copyTo:(AWDKeychainCKKSRateLimiterAggregatedScores *)other; - -// Performs a deep merge from other into self -// If set in other, singular values in self are replaced in self -// Singular composite values are recursively merged -// Repeated values from other are appended to repeated values in self -- (void)mergeFrom:(AWDKeychainCKKSRateLimiterAggregatedScores *)other; - -AWDKEYCHAINCKKSRATELIMITERAGGREGATEDSCORES_FUNCTION BOOL AWDKeychainCKKSRateLimiterAggregatedScoresReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterAggregatedScores *self, __unsafe_unretained PBDataReader *reader); - -@end - diff --git a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.m b/keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.m deleted file mode 100644 index d6a61068..00000000 --- a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.m +++ /dev/null @@ -1,264 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#if !TARGET_OS_BRIDGE - -#import "AWDKeychainCKKSRateLimiterAggregatedScores.h" -#import -#import -#import - -#if !__has_feature(objc_arc) -# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. -#endif - -@implementation AWDKeychainCKKSRateLimiterAggregatedScores - -- (void)dealloc -{ - PBRepeatedUInt32Clear(&(self->_datas)); -} - -@synthesize timestamp = _timestamp; -- (void)setTimestamp:(uint64_t)v -{ - _has.timestamp = YES; - _timestamp = v; -} -- (void)setHasTimestamp:(BOOL)f -{ - _has.timestamp = f; -} -- (BOOL)hasTimestamp -{ - return _has.timestamp; -} -- (NSUInteger)datasCount -{ - return _datas.count; -} -- (uint32_t *)datas -{ - return _datas.list; -} -- (void)clearDatas -{ - PBRepeatedUInt32Clear(&_datas); -} -- (void)addData:(uint32_t)i -{ - PBRepeatedUInt32Add(&_datas, i); -} -- (uint32_t)dataAtIndex:(NSUInteger)idx -{ - if (_datas.count <= idx) - { - [[NSException exceptionWithName:NSRangeException reason:[NSString stringWithFormat:@"idx (%tu) is out of range (%tu)", idx, _datas.count] userInfo:nil] raise]; - } - return _datas.list[idx]; -} -- (void)setDatas:(uint32_t *)list count:(NSUInteger)count -{ - PBRepeatedUInt32Set(&_datas, list, count); -} -- (BOOL)hasRatelimitertype -{ - return _ratelimitertype != nil; -} -@synthesize ratelimitertype = _ratelimitertype; - -- (NSString *)description -{ - return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; -} - -- (NSDictionary *)dictionaryRepresentation -{ - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - if (self->_has.timestamp) - { - [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"]; - } - [dict setObject:PBRepeatedUInt32NSArray(&(self->_datas)) forKey:@"data"]; - if (self->_ratelimitertype) - { - [dict setObject:self->_ratelimitertype forKey:@"ratelimitertype"]; - } - return dict; -} - -BOOL AWDKeychainCKKSRateLimiterAggregatedScoresReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterAggregatedScores *self, __unsafe_unretained PBDataReader *reader) { - while (PBReaderHasMoreData(reader)) { - uint32_t tag = 0; - uint8_t aType = 0; - - PBReaderReadTag32AndType(reader, &tag, &aType); - - if (PBReaderHasError(reader)) - break; - - if (aType == TYPE_END_GROUP) { - break; - } - - switch (tag) { - - case 1 /* timestamp */: - { - self->_has.timestamp = YES; - self->_timestamp = PBReaderReadUint64(reader); - } - break; - case 2 /* datas */: - { - if (TYPE_LENGTH_DELIMITED == aType) - { - PBDataReaderMark mark_data; - BOOL markError = !PBReaderPlaceMark(reader, &mark_data); - if (markError) - { - return NO; - } - while (PBReaderHasMoreData(reader)) - { - uint32_t new_data = PBReaderReadUint32(reader); - PBRepeatedUInt32Add(&(self->_datas), new_data); - } - PBReaderRecallMark(reader, &mark_data); - } - else - { - PBRepeatedUInt32Add(&(self->_datas), PBReaderReadUint32(reader)); - } - } - break; - case 3 /* ratelimitertype */: - { - NSString *new_ratelimitertype = PBReaderReadString(reader); - self->_ratelimitertype = new_ratelimitertype; - } - break; - default: - if (!PBReaderSkipValueWithTag(reader, tag, aType)) - return NO; - break; - } - } - return !PBReaderHasError(reader); -} - -- (BOOL)readFrom:(PBDataReader *)reader -{ - return AWDKeychainCKKSRateLimiterAggregatedScoresReadFrom(self, reader); -} -- (void)writeTo:(PBDataWriter *)writer -{ - /* timestamp */ - { - if (self->_has.timestamp) - { - PBDataWriterWriteUint64Field(writer, self->_timestamp, 1); - } - } - /* datas */ - { - if (self->_datas.count) - { - NSUInteger i_datas; - for (i_datas = 0; i_datas < self->_datas.count; i_datas++) - { - PBDataWriterWriteUint32Field(writer, self->_datas.list[i_datas], 2); - } - } - } - /* ratelimitertype */ - { - if (self->_ratelimitertype) - { - PBDataWriterWriteStringField(writer, self->_ratelimitertype, 3); - } - } -} - -- (void)copyTo:(AWDKeychainCKKSRateLimiterAggregatedScores *)other -{ - if (self->_has.timestamp) - { - other->_timestamp = _timestamp; - other->_has.timestamp = YES; - } - if ([self datasCount]) - { - [other clearDatas]; - NSUInteger datasCnt = [self datasCount]; - for (NSUInteger i = 0; i < datasCnt; i++) - { - [other addData:[self dataAtIndex:i]]; - } - } - if (_ratelimitertype) - { - other.ratelimitertype = _ratelimitertype; - } -} - -- (id)copyWithZone:(NSZone *)zone -{ - AWDKeychainCKKSRateLimiterAggregatedScores *copy = [[[self class] allocWithZone:zone] init]; - if (self->_has.timestamp) - { - copy->_timestamp = _timestamp; - copy->_has.timestamp = YES; - } - PBRepeatedUInt32Copy(&(copy->_datas), &_datas); - copy->_ratelimitertype = [_ratelimitertype copyWithZone:zone]; - return copy; -} - -- (BOOL)isEqual:(id)object -{ - AWDKeychainCKKSRateLimiterAggregatedScores *other = (AWDKeychainCKKSRateLimiterAggregatedScores *)object; - return [other isMemberOfClass:[self class]] - && - ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp)) - && - PBRepeatedUInt32IsEqual(&(self->_datas), &(other->_datas)) - && - ((!self->_ratelimitertype && !other->_ratelimitertype) || [self->_ratelimitertype isEqual:other->_ratelimitertype]) - ; -} - -- (NSUInteger)hash -{ - return 0 - ^ - (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0) - ^ - PBRepeatedUInt32Hash(&(self->_datas)) - ^ - [self->_ratelimitertype hash] - ; -} - -- (void)mergeFrom:(AWDKeychainCKKSRateLimiterAggregatedScores *)other -{ - if (other->_has.timestamp) - { - self->_timestamp = other->_timestamp; - self->_has.timestamp = YES; - } - NSUInteger datasCnt = [other datasCount]; - for (NSUInteger i = 0; i < datasCnt; i++) - { - [self addData:[other dataAtIndex:i]]; - } - if (other->_ratelimitertype) - { - [self setRatelimitertype:other->_ratelimitertype]; - } -} - -@end -#endif diff --git a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.h b/keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.h deleted file mode 100644 index 6b4f97ce..00000000 --- a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.h +++ /dev/null @@ -1,47 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#import - -#ifdef __cplusplus -#define AWDKEYCHAINCKKSRATELIMITEROVERLOAD_FUNCTION extern "C" -#else -#define AWDKEYCHAINCKKSRATELIMITEROVERLOAD_FUNCTION extern -#endif - -@interface AWDKeychainCKKSRateLimiterOverload : PBCodable -{ - int64_t _durationMsec; - uint64_t _timestamp; - NSString *_ratelimitertype; - struct { - int durationMsec:1; - int timestamp:1; - } _has; -} - - -@property (nonatomic) BOOL hasTimestamp; -@property (nonatomic) uint64_t timestamp; - -@property (nonatomic) BOOL hasDurationMsec; -@property (nonatomic) int64_t durationMsec; - -@property (nonatomic, readonly) BOOL hasRatelimitertype; -@property (nonatomic, retain) NSString *ratelimitertype; - -// Performs a shallow copy into other -- (void)copyTo:(AWDKeychainCKKSRateLimiterOverload *)other; - -// Performs a deep merge from other into self -// If set in other, singular values in self are replaced in self -// Singular composite values are recursively merged -// Repeated values from other are appended to repeated values in self -- (void)mergeFrom:(AWDKeychainCKKSRateLimiterOverload *)other; - -AWDKEYCHAINCKKSRATELIMITEROVERLOAD_FUNCTION BOOL AWDKeychainCKKSRateLimiterOverloadReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterOverload *self, __unsafe_unretained PBDataReader *reader); - -@end - diff --git a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.m b/keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.m deleted file mode 100644 index 9642e21c..00000000 --- a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.m +++ /dev/null @@ -1,227 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#if !TARGET_OS_BRIDGE - -#import "AWDKeychainCKKSRateLimiterOverload.h" -#import -#import -#import - -#if !__has_feature(objc_arc) -# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. -#endif - -@implementation AWDKeychainCKKSRateLimiterOverload - -@synthesize timestamp = _timestamp; -- (void)setTimestamp:(uint64_t)v -{ - _has.timestamp = YES; - _timestamp = v; -} -- (void)setHasTimestamp:(BOOL)f -{ - _has.timestamp = f; -} -- (BOOL)hasTimestamp -{ - return _has.timestamp; -} -@synthesize durationMsec = _durationMsec; -- (void)setDurationMsec:(int64_t)v -{ - _has.durationMsec = YES; - _durationMsec = v; -} -- (void)setHasDurationMsec:(BOOL)f -{ - _has.durationMsec = f; -} -- (BOOL)hasDurationMsec -{ - return _has.durationMsec; -} -- (BOOL)hasRatelimitertype -{ - return _ratelimitertype != nil; -} -@synthesize ratelimitertype = _ratelimitertype; - -- (NSString *)description -{ - return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; -} - -- (NSDictionary *)dictionaryRepresentation -{ - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - if (self->_has.timestamp) - { - [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"]; - } - if (self->_has.durationMsec) - { - [dict setObject:[NSNumber numberWithLongLong:self->_durationMsec] forKey:@"durationMsec"]; - } - if (self->_ratelimitertype) - { - [dict setObject:self->_ratelimitertype forKey:@"ratelimitertype"]; - } - return dict; -} - -BOOL AWDKeychainCKKSRateLimiterOverloadReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterOverload *self, __unsafe_unretained PBDataReader *reader) { - while (PBReaderHasMoreData(reader)) { - uint32_t tag = 0; - uint8_t aType = 0; - - PBReaderReadTag32AndType(reader, &tag, &aType); - - if (PBReaderHasError(reader)) - break; - - if (aType == TYPE_END_GROUP) { - break; - } - - switch (tag) { - - case 1 /* timestamp */: - { - self->_has.timestamp = YES; - self->_timestamp = PBReaderReadUint64(reader); - } - break; - case 2 /* durationMsec */: - { - self->_has.durationMsec = YES; - self->_durationMsec = PBReaderReadInt64(reader); - } - break; - case 3 /* ratelimitertype */: - { - NSString *new_ratelimitertype = PBReaderReadString(reader); - self->_ratelimitertype = new_ratelimitertype; - } - break; - default: - if (!PBReaderSkipValueWithTag(reader, tag, aType)) - return NO; - break; - } - } - return !PBReaderHasError(reader); -} - -- (BOOL)readFrom:(PBDataReader *)reader -{ - return AWDKeychainCKKSRateLimiterOverloadReadFrom(self, reader); -} -- (void)writeTo:(PBDataWriter *)writer -{ - /* timestamp */ - { - if (self->_has.timestamp) - { - PBDataWriterWriteUint64Field(writer, self->_timestamp, 1); - } - } - /* durationMsec */ - { - if (self->_has.durationMsec) - { - PBDataWriterWriteInt64Field(writer, self->_durationMsec, 2); - } - } - /* ratelimitertype */ - { - if (self->_ratelimitertype) - { - PBDataWriterWriteStringField(writer, self->_ratelimitertype, 3); - } - } -} - -- (void)copyTo:(AWDKeychainCKKSRateLimiterOverload *)other -{ - if (self->_has.timestamp) - { - other->_timestamp = _timestamp; - other->_has.timestamp = YES; - } - if (self->_has.durationMsec) - { - other->_durationMsec = _durationMsec; - other->_has.durationMsec = YES; - } - if (_ratelimitertype) - { - other.ratelimitertype = _ratelimitertype; - } -} - -- (id)copyWithZone:(NSZone *)zone -{ - AWDKeychainCKKSRateLimiterOverload *copy = [[[self class] allocWithZone:zone] init]; - if (self->_has.timestamp) - { - copy->_timestamp = _timestamp; - copy->_has.timestamp = YES; - } - if (self->_has.durationMsec) - { - copy->_durationMsec = _durationMsec; - copy->_has.durationMsec = YES; - } - copy->_ratelimitertype = [_ratelimitertype copyWithZone:zone]; - return copy; -} - -- (BOOL)isEqual:(id)object -{ - AWDKeychainCKKSRateLimiterOverload *other = (AWDKeychainCKKSRateLimiterOverload *)object; - return [other isMemberOfClass:[self class]] - && - ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp)) - && - ((self->_has.durationMsec && other->_has.durationMsec && self->_durationMsec == other->_durationMsec) || (!self->_has.durationMsec && !other->_has.durationMsec)) - && - ((!self->_ratelimitertype && !other->_ratelimitertype) || [self->_ratelimitertype isEqual:other->_ratelimitertype]) - ; -} - -- (NSUInteger)hash -{ - return 0 - ^ - (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0) - ^ - (self->_has.durationMsec ? PBHashInt((NSUInteger)self->_durationMsec) : 0) - ^ - [self->_ratelimitertype hash] - ; -} - -- (void)mergeFrom:(AWDKeychainCKKSRateLimiterOverload *)other -{ - if (other->_has.timestamp) - { - self->_timestamp = other->_timestamp; - self->_has.timestamp = YES; - } - if (other->_has.durationMsec) - { - self->_durationMsec = other->_durationMsec; - self->_has.durationMsec = YES; - } - if (other->_ratelimitertype) - { - [self setRatelimitertype:other->_ratelimitertype]; - } -} - -@end -#endif diff --git a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h b/keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h deleted file mode 100644 index 1d649b76..00000000 --- a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h +++ /dev/null @@ -1,50 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#import - -#ifdef __cplusplus -#define AWDKEYCHAINCKKSRATELIMITERTOPWRITERS_FUNCTION extern "C" -#else -#define AWDKEYCHAINCKKSRATELIMITERTOPWRITERS_FUNCTION extern -#endif - -@interface AWDKeychainCKKSRateLimiterTopWriters : PBCodable -{ - uint64_t _timestamp; - NSString *_ratelimitertype; - NSMutableArray *_writers; - struct { - int timestamp:1; - } _has; -} - - -@property (nonatomic) BOOL hasTimestamp; -@property (nonatomic) uint64_t timestamp; - -@property (nonatomic, retain) NSMutableArray *writers; -- (void)clearWriters; -- (void)addWriter:(NSString *)i; -- (NSUInteger)writersCount; -- (NSString *)writerAtIndex:(NSUInteger)idx; -+ (Class)writerType; - -@property (nonatomic, readonly) BOOL hasRatelimitertype; -@property (nonatomic, retain) NSString *ratelimitertype; - -// Performs a shallow copy into other -- (void)copyTo:(AWDKeychainCKKSRateLimiterTopWriters *)other; - -// Performs a deep merge from other into self -// If set in other, singular values in self are replaced in self -// Singular composite values are recursively merged -// Repeated values from other are appended to repeated values in self -- (void)mergeFrom:(AWDKeychainCKKSRateLimiterTopWriters *)other; - -AWDKEYCHAINCKKSRATELIMITERTOPWRITERS_FUNCTION BOOL AWDKeychainCKKSRateLimiterTopWritersReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterTopWriters *self, __unsafe_unretained PBDataReader *reader); - -@end - diff --git a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.m b/keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.m deleted file mode 100644 index 6cfaaa5b..00000000 --- a/keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.m +++ /dev/null @@ -1,244 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#if !TARGET_OS_BRIDGE - -#import "AWDKeychainCKKSRateLimiterTopWriters.h" -#import -#import -#import - -#if !__has_feature(objc_arc) -# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. -#endif - -@implementation AWDKeychainCKKSRateLimiterTopWriters - -@synthesize timestamp = _timestamp; -- (void)setTimestamp:(uint64_t)v -{ - _has.timestamp = YES; - _timestamp = v; -} -- (void)setHasTimestamp:(BOOL)f -{ - _has.timestamp = f; -} -- (BOOL)hasTimestamp -{ - return _has.timestamp; -} -@synthesize writers = _writers; -- (void)clearWriters -{ - [_writers removeAllObjects]; -} -- (void)addWriter:(NSString *)i -{ - if (!_writers) - { - _writers = [[NSMutableArray alloc] init]; - } - [_writers addObject:i]; -} -- (NSUInteger)writersCount -{ - return [_writers count]; -} -- (NSString *)writerAtIndex:(NSUInteger)idx -{ - return [_writers objectAtIndex:idx]; -} -+ (Class)writerType -{ - return [NSString class]; -} -- (BOOL)hasRatelimitertype -{ - return _ratelimitertype != nil; -} -@synthesize ratelimitertype = _ratelimitertype; - -- (NSString *)description -{ - return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; -} - -- (NSDictionary *)dictionaryRepresentation -{ - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - if (self->_has.timestamp) - { - [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"]; - } - if (self->_writers) - { - [dict setObject:self->_writers forKey:@"writer"]; - } - if (self->_ratelimitertype) - { - [dict setObject:self->_ratelimitertype forKey:@"ratelimitertype"]; - } - return dict; -} - -BOOL AWDKeychainCKKSRateLimiterTopWritersReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterTopWriters *self, __unsafe_unretained PBDataReader *reader) { - while (PBReaderHasMoreData(reader)) { - uint32_t tag = 0; - uint8_t aType = 0; - - PBReaderReadTag32AndType(reader, &tag, &aType); - - if (PBReaderHasError(reader)) - break; - - if (aType == TYPE_END_GROUP) { - break; - } - - switch (tag) { - - case 1 /* timestamp */: - { - self->_has.timestamp = YES; - self->_timestamp = PBReaderReadUint64(reader); - } - break; - case 2 /* writers */: - { - NSString *new_writers = PBReaderReadString(reader); - if (new_writers) - { - [self addWriter:new_writers]; - } - } - break; - case 3 /* ratelimitertype */: - { - NSString *new_ratelimitertype = PBReaderReadString(reader); - self->_ratelimitertype = new_ratelimitertype; - } - break; - default: - if (!PBReaderSkipValueWithTag(reader, tag, aType)) - return NO; - break; - } - } - return !PBReaderHasError(reader); -} - -- (BOOL)readFrom:(PBDataReader *)reader -{ - return AWDKeychainCKKSRateLimiterTopWritersReadFrom(self, reader); -} -- (void)writeTo:(PBDataWriter *)writer -{ - /* timestamp */ - { - if (self->_has.timestamp) - { - PBDataWriterWriteUint64Field(writer, self->_timestamp, 1); - } - } - /* writers */ - { - for (NSString *s_writers in self->_writers) - { - PBDataWriterWriteStringField(writer, s_writers, 2); - } - } - /* ratelimitertype */ - { - if (self->_ratelimitertype) - { - PBDataWriterWriteStringField(writer, self->_ratelimitertype, 3); - } - } -} - -- (void)copyTo:(AWDKeychainCKKSRateLimiterTopWriters *)other -{ - if (self->_has.timestamp) - { - other->_timestamp = _timestamp; - other->_has.timestamp = YES; - } - if ([self writersCount]) - { - [other clearWriters]; - NSUInteger writersCnt = [self writersCount]; - for (NSUInteger i = 0; i < writersCnt; i++) - { - [other addWriter:[self writerAtIndex:i]]; - } - } - if (_ratelimitertype) - { - other.ratelimitertype = _ratelimitertype; - } -} - -- (id)copyWithZone:(NSZone *)zone -{ - AWDKeychainCKKSRateLimiterTopWriters *copy = [[[self class] allocWithZone:zone] init]; - if (self->_has.timestamp) - { - copy->_timestamp = _timestamp; - copy->_has.timestamp = YES; - } - for (NSString *v in _writers) - { - NSString *vCopy = [v copyWithZone:zone]; - [copy addWriter:vCopy]; - } - copy->_ratelimitertype = [_ratelimitertype copyWithZone:zone]; - return copy; -} - -- (BOOL)isEqual:(id)object -{ - AWDKeychainCKKSRateLimiterTopWriters *other = (AWDKeychainCKKSRateLimiterTopWriters *)object; - return [other isMemberOfClass:[self class]] - && - ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp)) - && - ((!self->_writers && !other->_writers) || [self->_writers isEqual:other->_writers]) - && - ((!self->_ratelimitertype && !other->_ratelimitertype) || [self->_ratelimitertype isEqual:other->_ratelimitertype]) - ; -} - -- (NSUInteger)hash -{ - return 0 - ^ - (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0) - ^ - [self->_writers hash] - ^ - [self->_ratelimitertype hash] - ; -} - -- (void)mergeFrom:(AWDKeychainCKKSRateLimiterTopWriters *)other -{ - if (other->_has.timestamp) - { - self->_timestamp = other->_timestamp; - self->_has.timestamp = YES; - } - for (NSString *iter_writers in other->_writers) - { - [self addWriter:iter_writers]; - } - if (other->_ratelimitertype) - { - [self setRatelimitertype:other->_ratelimitertype]; - } -} - -@end -#endif diff --git a/keychain/analytics/awd/AWDKeychainSOSKeychainBackupFailed.h b/keychain/analytics/awd/AWDKeychainSOSKeychainBackupFailed.h deleted file mode 100644 index 4786d223..00000000 --- a/keychain/analytics/awd/AWDKeychainSOSKeychainBackupFailed.h +++ /dev/null @@ -1,38 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#import - -#ifdef __cplusplus -#define AWDKEYCHAINSOSKEYCHAINBACKUPFAILED_FUNCTION extern "C" -#else -#define AWDKEYCHAINSOSKEYCHAINBACKUPFAILED_FUNCTION extern -#endif - -@interface AWDKeychainSOSKeychainBackupFailed : PBCodable -{ - uint64_t _timestamp; - struct { - int timestamp:1; - } _has; -} - - -@property (nonatomic) BOOL hasTimestamp; -@property (nonatomic) uint64_t timestamp; - -// Performs a shallow copy into other -- (void)copyTo:(AWDKeychainSOSKeychainBackupFailed *)other; - -// Performs a deep merge from other into self -// If set in other, singular values in self are replaced in self -// Singular composite values are recursively merged -// Repeated values from other are appended to repeated values in self -- (void)mergeFrom:(AWDKeychainSOSKeychainBackupFailed *)other; - -AWDKEYCHAINSOSKEYCHAINBACKUPFAILED_FUNCTION BOOL AWDKeychainSOSKeychainBackupFailedReadFrom(__unsafe_unretained AWDKeychainSOSKeychainBackupFailed *self, __unsafe_unretained PBDataReader *reader); - -@end - diff --git a/keychain/analytics/awd/AWDKeychainSOSKeychainBackupFailed.m b/keychain/analytics/awd/AWDKeychainSOSKeychainBackupFailed.m deleted file mode 100644 index bf93f6ee..00000000 --- a/keychain/analytics/awd/AWDKeychainSOSKeychainBackupFailed.m +++ /dev/null @@ -1,142 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#if !TARGET_OS_BRIDGE - -#import "AWDKeychainSOSKeychainBackupFailed.h" -#import -#import -#import - -#if !__has_feature(objc_arc) -# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. -#endif - -@implementation AWDKeychainSOSKeychainBackupFailed - -@synthesize timestamp = _timestamp; -- (void)setTimestamp:(uint64_t)v -{ - _has.timestamp = YES; - _timestamp = v; -} -- (void)setHasTimestamp:(BOOL)f -{ - _has.timestamp = f; -} -- (BOOL)hasTimestamp -{ - return _has.timestamp; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; -} - -- (NSDictionary *)dictionaryRepresentation -{ - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - if (self->_has.timestamp) - { - [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"]; - } - return dict; -} - -BOOL AWDKeychainSOSKeychainBackupFailedReadFrom(__unsafe_unretained AWDKeychainSOSKeychainBackupFailed *self, __unsafe_unretained PBDataReader *reader) { - while (PBReaderHasMoreData(reader)) { - uint32_t tag = 0; - uint8_t aType = 0; - - PBReaderReadTag32AndType(reader, &tag, &aType); - - if (PBReaderHasError(reader)) - break; - - if (aType == TYPE_END_GROUP) { - break; - } - - switch (tag) { - - case 1 /* timestamp */: - { - self->_has.timestamp = YES; - self->_timestamp = PBReaderReadUint64(reader); - } - break; - default: - if (!PBReaderSkipValueWithTag(reader, tag, aType)) - return NO; - break; - } - } - return !PBReaderHasError(reader); -} - -- (BOOL)readFrom:(PBDataReader *)reader -{ - return AWDKeychainSOSKeychainBackupFailedReadFrom(self, reader); -} -- (void)writeTo:(PBDataWriter *)writer -{ - /* timestamp */ - { - if (self->_has.timestamp) - { - PBDataWriterWriteUint64Field(writer, self->_timestamp, 1); - } - } -} - -- (void)copyTo:(AWDKeychainSOSKeychainBackupFailed *)other -{ - if (self->_has.timestamp) - { - other->_timestamp = _timestamp; - other->_has.timestamp = YES; - } -} - -- (id)copyWithZone:(NSZone *)zone -{ - AWDKeychainSOSKeychainBackupFailed *copy = [[[self class] allocWithZone:zone] init]; - if (self->_has.timestamp) - { - copy->_timestamp = _timestamp; - copy->_has.timestamp = YES; - } - return copy; -} - -- (BOOL)isEqual:(id)object -{ - AWDKeychainSOSKeychainBackupFailed *other = (AWDKeychainSOSKeychainBackupFailed *)object; - return [other isMemberOfClass:[self class]] - && - ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp)) - ; -} - -- (NSUInteger)hash -{ - return 0 - ^ - (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0) - ; -} - -- (void)mergeFrom:(AWDKeychainSOSKeychainBackupFailed *)other -{ - if (other->_has.timestamp) - { - self->_timestamp = other->_timestamp; - self->_has.timestamp = YES; - } -} - -@end -#endif diff --git a/keychain/analytics/awd/AWDKeychainSecDbMarkedCorrupt.h b/keychain/analytics/awd/AWDKeychainSecDbMarkedCorrupt.h deleted file mode 100644 index 4c2743b1..00000000 --- a/keychain/analytics/awd/AWDKeychainSecDbMarkedCorrupt.h +++ /dev/null @@ -1,48 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#import - -#ifdef __cplusplus -#define AWDKEYCHAINSECDBMARKEDCORRUPT_FUNCTION extern "C" -#else -#define AWDKEYCHAINSECDBMARKEDCORRUPT_FUNCTION extern -#endif - -@interface AWDKeychainSecDbMarkedCorrupt : PBCodable -{ - uint64_t _timestamp; - uint32_t _reason; - uint32_t _sqlitecode; - struct { - int timestamp:1; - int reason:1; - int sqlitecode:1; - } _has; -} - - -@property (nonatomic) BOOL hasTimestamp; -@property (nonatomic) uint64_t timestamp; - -@property (nonatomic) BOOL hasReason; -@property (nonatomic) uint32_t reason; - -@property (nonatomic) BOOL hasSqlitecode; -@property (nonatomic) uint32_t sqlitecode; - -// Performs a shallow copy into other -- (void)copyTo:(AWDKeychainSecDbMarkedCorrupt *)other; - -// Performs a deep merge from other into self -// If set in other, singular values in self are replaced in self -// Singular composite values are recursively merged -// Repeated values from other are appended to repeated values in self -- (void)mergeFrom:(AWDKeychainSecDbMarkedCorrupt *)other; - -AWDKEYCHAINSECDBMARKEDCORRUPT_FUNCTION BOOL AWDKeychainSecDbMarkedCorruptReadFrom(__unsafe_unretained AWDKeychainSecDbMarkedCorrupt *self, __unsafe_unretained PBDataReader *reader); - -@end - diff --git a/keychain/analytics/awd/AWDKeychainSecDbMarkedCorrupt.m b/keychain/analytics/awd/AWDKeychainSecDbMarkedCorrupt.m deleted file mode 100644 index d597b31a..00000000 --- a/keychain/analytics/awd/AWDKeychainSecDbMarkedCorrupt.m +++ /dev/null @@ -1,242 +0,0 @@ -// This file was automatically generated by protocompiler -// DO NOT EDIT! -// Compiled from stdin - -#import -#if !TARGET_OS_BRIDGE - -#import "AWDKeychainSecDbMarkedCorrupt.h" -#import -#import -#import - -#if !__has_feature(objc_arc) -# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. -#endif - -@implementation AWDKeychainSecDbMarkedCorrupt - -@synthesize timestamp = _timestamp; -- (void)setTimestamp:(uint64_t)v -{ - _has.timestamp = YES; - _timestamp = v; -} -- (void)setHasTimestamp:(BOOL)f -{ - _has.timestamp = f; -} -- (BOOL)hasTimestamp -{ - return _has.timestamp; -} -@synthesize reason = _reason; -- (void)setReason:(uint32_t)v -{ - _has.reason = YES; - _reason = v; -} -- (void)setHasReason:(BOOL)f -{ - _has.reason = f; -} -- (BOOL)hasReason -{ - return _has.reason; -} -@synthesize sqlitecode = _sqlitecode; -- (void)setSqlitecode:(uint32_t)v -{ - _has.sqlitecode = YES; - _sqlitecode = v; -} -- (void)setHasSqlitecode:(BOOL)f -{ - _has.sqlitecode = f; -} -- (BOOL)hasSqlitecode -{ - return _has.sqlitecode; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; -} - -- (NSDictionary *)dictionaryRepresentation -{ - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - if (self->_has.timestamp) - { - [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"]; - } - if (self->_has.reason) - { - [dict setObject:[NSNumber numberWithUnsignedInt:self->_reason] forKey:@"reason"]; - } - if (self->_has.sqlitecode) - { - [dict setObject:[NSNumber numberWithUnsignedInt:self->_sqlitecode] forKey:@"sqlitecode"]; - } - return dict; -} - -BOOL AWDKeychainSecDbMarkedCorruptReadFrom(__unsafe_unretained AWDKeychainSecDbMarkedCorrupt *self, __unsafe_unretained PBDataReader *reader) { - while (PBReaderHasMoreData(reader)) { - uint32_t tag = 0; - uint8_t aType = 0; - - PBReaderReadTag32AndType(reader, &tag, &aType); - - if (PBReaderHasError(reader)) - break; - - if (aType == TYPE_END_GROUP) { - break; - } - - switch (tag) { - - case 1 /* timestamp */: - { - self->_has.timestamp = YES; - self->_timestamp = PBReaderReadUint64(reader); - } - break; - case 2 /* reason */: - { - self->_has.reason = YES; - self->_reason = PBReaderReadUint32(reader); - } - break; - case 3 /* sqlitecode */: - { - self->_has.sqlitecode = YES; - self->_sqlitecode = PBReaderReadUint32(reader); - } - break; - default: - if (!PBReaderSkipValueWithTag(reader, tag, aType)) - return NO; - break; - } - } - return !PBReaderHasError(reader); -} - -- (BOOL)readFrom:(PBDataReader *)reader -{ - return AWDKeychainSecDbMarkedCorruptReadFrom(self, reader); -} -- (void)writeTo:(PBDataWriter *)writer -{ - /* timestamp */ - { - if (self->_has.timestamp) - { - PBDataWriterWriteUint64Field(writer, self->_timestamp, 1); - } - } - /* reason */ - { - if (self->_has.reason) - { - PBDataWriterWriteUint32Field(writer, self->_reason, 2); - } - } - /* sqlitecode */ - { - if (self->_has.sqlitecode) - { - PBDataWriterWriteUint32Field(writer, self->_sqlitecode, 3); - } - } -} - -- (void)copyTo:(AWDKeychainSecDbMarkedCorrupt *)other -{ - if (self->_has.timestamp) - { - other->_timestamp = _timestamp; - other->_has.timestamp = YES; - } - if (self->_has.reason) - { - other->_reason = _reason; - other->_has.reason = YES; - } - if (self->_has.sqlitecode) - { - other->_sqlitecode = _sqlitecode; - other->_has.sqlitecode = YES; - } -} - -- (id)copyWithZone:(NSZone *)zone -{ - AWDKeychainSecDbMarkedCorrupt *copy = [[[self class] allocWithZone:zone] init]; - if (self->_has.timestamp) - { - copy->_timestamp = _timestamp; - copy->_has.timestamp = YES; - } - if (self->_has.reason) - { - copy->_reason = _reason; - copy->_has.reason = YES; - } - if (self->_has.sqlitecode) - { - copy->_sqlitecode = _sqlitecode; - copy->_has.sqlitecode = YES; - } - return copy; -} - -- (BOOL)isEqual:(id)object -{ - AWDKeychainSecDbMarkedCorrupt *other = (AWDKeychainSecDbMarkedCorrupt *)object; - return [other isMemberOfClass:[self class]] - && - ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp)) - && - ((self->_has.reason && other->_has.reason && self->_reason == other->_reason) || (!self->_has.reason && !other->_has.reason)) - && - ((self->_has.sqlitecode && other->_has.sqlitecode && self->_sqlitecode == other->_sqlitecode) || (!self->_has.sqlitecode && !other->_has.sqlitecode)) - ; -} - -- (NSUInteger)hash -{ - return 0 - ^ - (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0) - ^ - (self->_has.reason ? PBHashInt((NSUInteger)self->_reason) : 0) - ^ - (self->_has.sqlitecode ? PBHashInt((NSUInteger)self->_sqlitecode) : 0) - ; -} - -- (void)mergeFrom:(AWDKeychainSecDbMarkedCorrupt *)other -{ - if (other->_has.timestamp) - { - self->_timestamp = other->_timestamp; - self->_has.timestamp = YES; - } - if (other->_has.reason) - { - self->_reason = other->_reason; - self->_has.reason = YES; - } - if (other->_has.sqlitecode) - { - self->_sqlitecode = other->_sqlitecode; - self->_has.sqlitecode = YES; - } -} - -@end -#endif diff --git a/keychain/analytics/awd/AWDMetricIds_Keychain.h b/keychain/analytics/awd/AWDMetricIds_Keychain.h deleted file mode 100644 index e96ab84c..00000000 --- a/keychain/analytics/awd/AWDMetricIds_Keychain.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// AWDMetricIds_Keychain.h -// AppleWirelessDiagnostics -// -// WARNING :: DO NOT MODIFY THIS FILE! -// -// This file is auto-generated! Do not modify it or your changes will get overwritten! -// - -#ifndef AWD_MetricId_HeaderGuard_Keychain -#define AWD_MetricId_HeaderGuard_Keychain - -// Component Id: -// --------------- -// Use this value for any API requesting the "component id" for your component. -enum { - AWDComponentId_Keychain = 0x60 -}; - - -// Simple Metrics: -// --------------- -// The following metrics are compatible with the 'simple metric' API: -enum { - - AWDMetricId_Keychain_SOSKeychainBackupFailed = 0x600004 -}; - -// General Metrics: -// ---------------- -enum { - AWDMetricId_Keychain_CKKSRateLimiterOverload = 0x600000, - AWDMetricId_Keychain_CKKSRateLimiterTopWriters = 0x600001, - AWDMetricId_Keychain_CKKSRateLimiterAggregatedScores = 0x600002, - AWDMetricId_Keychain_SecDbMarkedCorrupt = 0x600003 -}; - -#endif // AWD_MetricId_HeaderGuard_Keychain diff --git a/keychain/analytics/awd/AwdMetadata-0x60-Keychain.bin b/keychain/analytics/awd/AwdMetadata-0x60-Keychain.bin deleted file mode 100644 index 2201be299b555e5de84e9645e2bb7e4bbed4b43c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1067 zcmaJ>U5nE|6rD+8HxBzzBCN41EE|LsmO|5P+w5cAB0{aZ7?<_2)5#b^KN2UYvfxAg z0DqP*;)~CVPrmpod{S>WnO3whFl2J>oO`(E3~8TtdKh7(B7_vAp+3Ajur6VJxl{Y8 z=GZNa&?g0$t3$=mCbEQdVKNZIpDiykR0z`J-Bb>V}C6Yis|lp)1}R^d!rk za*LA-`bHX*fCVcD=_mx{13>ktQJgd+{gm5uBYLcCn+7rkkxjUm9_3q1x>?f(n~ml~i5}fQ8Nc`>XYN2%yf?H&1K22${%o(Xj znSX;=-FZF&+&!x#I8CC7VSr2XZ<4$i!8Ku#&q;HcL_uULdy~6OTDM)BJ!|<*r|ujb w*@MGFM(u$!pbg4e4aaFXP;`u)Hv9;9Dngb#t+pDqs$C5v+5Gt7$L05f-|$lf#sB~S diff --git a/keychain/categories/NSError+UsefulConstructors.h b/keychain/categories/NSError+UsefulConstructors.h new file mode 100644 index 00000000..c6c387f4 --- /dev/null +++ b/keychain/categories/NSError+UsefulConstructors.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018 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@ + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSError (UsefulConstructors) + +// Every error should have a description ++ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description; + +// Sometimes you also want to have an underlying error (which might be null) ++ (instancetype)errorWithDomain:(NSErrorDomain)domain + code:(NSInteger)code + description:(NSString*)description + underlying:(NSError* _Nullable)underlying; +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/categories/NSError+UsefulConstructors.m b/keychain/categories/NSError+UsefulConstructors.m new file mode 100644 index 00000000..c8cd432a --- /dev/null +++ b/keychain/categories/NSError+UsefulConstructors.m @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018 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@ + */ + + +#import "NSError+UsefulConstructors.h" + +@implementation NSError (UsefulConstructors) + ++ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description { + return [NSError errorWithDomain:domain code:code description:description underlying:nil]; +} + ++ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description underlying:(NSError*)underlying { + // Obj-C throws a fit if there's nulls in dictionaries, so we can't use a dictionary literal here. + // Use the null-assignment semantics of NSMutableDictionary to make a dictionary either with either, both, or neither key. + NSMutableDictionary* mut = [[NSMutableDictionary alloc] init]; + mut[NSLocalizedDescriptionKey] = description; + mut[NSUnderlyingErrorKey] = underlying; + + return [NSError errorWithDomain:domain code:code userInfo:mut]; +} + +@end diff --git a/keychain/ckks/CKKS.h b/keychain/ckks/CKKS.h index 45d4fc98..76050f4f 100644 --- a/keychain/ckks/CKKS.h +++ b/keychain/ckks/CKKS.h @@ -79,7 +79,7 @@ extern CKKSKeyClass* const SecCKKSKeyClassA; extern CKKSKeyClass* const SecCKKSKeyClassC; /* Useful CloudKit configuration */ -extern NSString* const SecCKKSContainerName; +extern NSString* SecCKKSContainerName; extern bool SecCKKSContainerUsePCS; extern NSString* const SecCKKSSubscriptionID; extern NSString* const SecCKKSAPSNamedPort; @@ -195,6 +195,8 @@ extern CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKShares; extern CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKSharesFailed; // The key hierarchy state machine needs to wait for the fixup operation to complete extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForFixupOperation; +// The key hierarchy state machine is responding to a key state reprocess request +extern CKKSZoneKeyState* const SecCKKSZoneKeyStateProcess; // CKKS is resetting the remote zone, due to key hierarchy reasons. Will not proceed until the local reset occurs. extern CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingZone; @@ -316,6 +318,8 @@ typedef CF_ENUM(CFIndex, CKKSErrorCode) { CKKSNotHSA2 = 40, CKKSiCloudGreyMode = 41, + + CKKSNoFetchesRequested = 50, }; typedef CF_ENUM(CFIndex, CKKSResultDescriptionErrorCode) { diff --git a/keychain/ckks/CKKS.m b/keychain/ckks/CKKS.m index 4c7e99df..c7602021 100644 --- a/keychain/ckks/CKKS.m +++ b/keychain/ckks/CKKS.m @@ -59,7 +59,7 @@ CKKSKeyClass* const SecCKKSKeyClassTLK = (CKKSKeyClass*) @"tlk"; CKKSKeyClass* const SecCKKSKeyClassA = (CKKSKeyClass*) @"classA"; CKKSKeyClass* const SecCKKSKeyClassC = (CKKSKeyClass*) @"classC"; -NSString* const SecCKKSContainerName = @"com.apple.security.keychain"; +NSString* SecCKKSContainerName = @"com.apple.security.keychain"; bool SecCKKSContainerUsePCS = false; NSString* const SecCKKSSubscriptionID = @"keychain-changes"; @@ -142,6 +142,7 @@ CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingZone = (CKKSZoneKeyState*) @ CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingLocalData = (CKKSZoneKeyState*) @"resetlocal"; CKKSZoneKeyState* const SecCKKSZoneKeyStateLoggedOut = (CKKSZoneKeyState*) @"loggedout"; CKKSZoneKeyState* const SecCKKSZoneKeyStateZoneCreationFailed = (CKKSZoneKeyState*) @"zonecreationfailed"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateProcess = (CKKSZoneKeyState*) @"process"; NSDictionary* CKKSZoneKeyStateMap(void) { static NSDictionary* map = nil; diff --git a/keychain/ckks/CKKSAPSReceiver.h b/keychain/ckks/CKKSAPSReceiver.h index 7f83dc0a..9b1b714e 100644 --- a/keychain/ckks/CKKSAPSReceiver.h +++ b/keychain/ckks/CKKSAPSReceiver.h @@ -29,8 +29,16 @@ #import "keychain/ckks/CKKSCondition.h" #import "keychain/ckks/CloudKitDependencies.h" + NS_ASSUME_NONNULL_BEGIN +// APS is giving us a tracingUUID and a tracingEnabled bool, but our interfaces take a CKRecordZoneNotification. Add them to that class, then. +@interface CKRecordZoneNotification (CKKSPushTracing) +@property (nonatomic, assign) BOOL ckksPushTracingEnabled; +@property (nonatomic, strong, nullable) NSString* ckksPushTracingUUID; +@property (nonatomic, strong, nullable) NSDate* ckksPushReceivedDate; +@end + @protocol CKKSZoneUpdateReceiver - (void)notifyZoneChange:(CKRecordZoneNotification* _Nullable)notification; @end diff --git a/keychain/ckks/CKKSAPSReceiver.m b/keychain/ckks/CKKSAPSReceiver.m index 57fa30a6..1d62a535 100644 --- a/keychain/ckks/CKKSAPSReceiver.m +++ b/keychain/ckks/CKKSAPSReceiver.m @@ -28,6 +28,33 @@ #import #include +@implementation CKRecordZoneNotification (CKKSPushTracing) +- (void)setCkksPushTracingEnabled:(BOOL)ckksPushTracingEnabled { + objc_setAssociatedObject(self, "ckksPushTracingEnabled", ckksPushTracingEnabled ? @YES : @NO, OBJC_ASSOCIATION_RETAIN); +} + +- (BOOL)ckksPushTracingEnabled { + return !![objc_getAssociatedObject(self, "ckksPushTracingEnabled") boolValue]; +} + +- (void)setCkksPushTracingUUID:(NSString*)ckksPushTracingUUID { + objc_setAssociatedObject(self, "ckksPushTracingUUID", ckksPushTracingUUID, OBJC_ASSOCIATION_RETAIN); +} + +- (NSString*)ckksPushTracingUUID { + return objc_getAssociatedObject(self, "ckksPushTracingUUID"); +} + +- (void)setCkksPushReceivedDate:(NSDate*)ckksPushReceivedDate { + objc_setAssociatedObject(self, "ckksPushReceivedDate", ckksPushReceivedDate, OBJC_ASSOCIATION_RETAIN); +} + +- (NSDate*)ckksPushReceivedDate { + return objc_getAssociatedObject(self, "ckksPushReceivedDate"); +} +@end + + @interface CKKSAPSReceiver() // If we receive >0 notifications for a CKRecordZoneID that hasn't been registered yet, give them a fake update when they register @property NSMutableSet* undeliveredUpdates; @@ -139,10 +166,18 @@ - (void)connection:(APSConnection *)connection didReceiveIncomingMessage:(APSIncomingMessage *)message { secnotice("ckkspush", "CKKSAPSDelegate received a message: %@ on connection %@", message, connection); + // Report back through APS that we received a message + if(message.tracingEnabled) { + [connection confirmReceiptForMessage:message]; + } + CKNotification* notification = [CKNotification notificationFromRemoteNotificationDictionary:message.userInfo]; if(notification.notificationType == CKNotificationTypeRecordZone) { CKRecordZoneNotification* rznotification = (CKRecordZoneNotification*) notification; + rznotification.ckksPushTracingEnabled = message.tracingEnabled; + rznotification.ckksPushTracingUUID = message.tracingUUID ? [[[NSUUID alloc] initWithUUIDBytes:message.tracingUUID.bytes] UUIDString] : nil; + rznotification.ckksPushReceivedDate = [NSDate date]; // Find receiever in map id recv = [self.zoneMap objectForKey:rznotification.recordZoneID]; @@ -151,6 +186,7 @@ } else { secerror("ckks: received push for unregistered zone: %@", rznotification); if(rznotification.recordZoneID) { + // TODO: save the rznofication itself [self.undeliveredUpdates addObject: rznotification.recordZoneID]; } } diff --git a/keychain/ckks/CKKSAnalytics.m b/keychain/ckks/CKKSAnalytics.m index f26019f9..b512a7e8 100644 --- a/keychain/ckks/CKKSAnalytics.m +++ b/keychain/ckks/CKKSAnalytics.m @@ -32,7 +32,6 @@ #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CKKSKeychainView.h" -#import "Analytics/SFAnalytics.h" #include #include @@ -103,20 +102,7 @@ CKKSAnalyticsActivity* const CKKSActivityBottleCheck = (CKKSAnalyticsActivity *) remove(filename); }); }); - - WithPathInKeychainDirectory(CFSTR("Analytics"), ^(const char *path) { -#if TARGET_OS_IPHONE - mode_t permissions = 0775; -#else - mode_t permissions = 0700; -#endif // TARGET_OS_IPHONE - int ret = mkpath_np(path, permissions); - if (!(ret == 0 || ret == EEXIST)) { - secerror("could not create path: %s (%s)", path, strerror(ret)); - } - chmod(path, permissions); - }); - return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"Analytics/ckks_analytics.db") path]; + return [CKKSAnalytics defaultAnalyticsDatabasePath:@"ckks_analytics"]; } + (instancetype)logger diff --git a/keychain/ckks/CKKSCKAccountStateTracker.h b/keychain/ckks/CKKSCKAccountStateTracker.h index fb055091..5ca81f2c 100644 --- a/keychain/ckks/CKKSCKAccountStateTracker.h +++ b/keychain/ckks/CKKSCKAccountStateTracker.h @@ -51,6 +51,12 @@ typedef NS_ENUM(NSInteger, CKKSAccountStatus) { CKKSAccountStatusNoAccount = 3, }; +@interface SOSAccountStatus : NSObject +@property SOSCCStatus status; +@property (nullable) NSError* error; +- (instancetype)init:(SOSCCStatus)status error:error; +@end + @protocol CKKSAccountStateListener - (void)ckAccountStatusChange:(CKKSAccountStatus)oldStatus to:(CKKSAccountStatus)currentStatus; @end @@ -60,7 +66,7 @@ typedef NS_ENUM(NSInteger, CKKSAccountStatus) { // If you use these, please be aware they could change out from under you at any time @property (nullable) CKAccountInfo* currentCKAccountInfo; -@property SOSCCStatus currentCircleStatus; +@property (nullable) SOSAccountStatus* currentCircleStatus; @property (readonly,atomic) CKKSAccountStatus currentComputedAccountStatus; @property (nullable,readonly,atomic) NSError* currentAccountError; @@ -88,7 +94,7 @@ typedef NS_ENUM(NSInteger, CKKSAccountStatus) { - (dispatch_group_t _Nullable)checkForAllDeliveries; -+ (SOSCCStatus)getCircleStatus; ++ (SOSAccountStatus*)getCircleStatus; + (void)fetchCirclePeerID:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))callback; + (NSString*)stringFromAccountStatus:(CKKSAccountStatus)status; diff --git a/keychain/ckks/CKKSCKAccountStateTracker.m b/keychain/ckks/CKKSCKAccountStateTracker.m index ee8a40ba..116c5070 100644 --- a/keychain/ckks/CKKSCKAccountStateTracker.m +++ b/keychain/ckks/CKKSCKAccountStateTracker.m @@ -34,6 +34,7 @@ #import "keychain/ckks/CloudKitCategories.h" #import "keychain/ckks/CKKSCKAccountStateTracker.h" #import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/categories/NSError+UsefulConstructors.h" @interface CKKSCKAccountStateTracker () @property (readonly) Class nsnotificationCenterClass; @@ -59,7 +60,7 @@ _nsnotificationCenterClass = nsnotificationCenterClass; _changeListeners = [NSMapTable strongToWeakObjectsMapTable]; // Backwards from how we'd like, but it's the best way to have weak pointers to CKKSAccountStateListener. _currentCKAccountInfo = nil; - _currentCircleStatus = kSOSCCError; + _currentCircleStatus = [[SOSAccountStatus alloc] init:kSOSCCError error:nil]; _currentComputedAccountStatus = CKKSAccountStatusUnknown; _currentComputedAccountStatusValid = [[CKKSCondition alloc] init]; @@ -114,7 +115,7 @@ selfString, [self currentStatus], self.currentCKAccountInfo, - SOSCCGetStatusDescription(self.currentCircleStatus), + self.currentCircleStatus, self.currentAccountError ?: @""]; } @@ -197,7 +198,7 @@ -(dispatch_semaphore_t)notifyCircleChange:(__unused id)object { dispatch_semaphore_t finishedSema = dispatch_semaphore_create(0); - SOSCCStatus circleStatus = [CKKSCKAccountStateTracker getCircleStatus]; + SOSAccountStatus* circleStatus = [CKKSCKAccountStateTracker getCircleStatus]; dispatch_sync(self.queue, ^{ self.firstSOSCircleFetch = true; @@ -260,12 +261,12 @@ } // Takes the new ckAccountInfo we're moving to --(void)_onqueueUpdateCirclePeerID: (SOSCCStatus)sosccstatus { +-(void)_onqueueUpdateCirclePeerID: (SOSAccountStatus*)sosstatus { dispatch_assert_queue(self.queue); __weak __typeof(self) weakSelf = self; // If we're in a circle, fetch the peer id - if(sosccstatus == kSOSCCInCircle) { + if(sosstatus.status == kSOSCCInCircle) { [CKKSCKAccountStateTracker fetchCirclePeerID:^(NSString* peerID, NSError* error) { __strong __typeof(self) strongSelf = weakSelf; if(!strongSelf) { @@ -276,7 +277,7 @@ dispatch_async(strongSelf.queue, ^{ __strong __typeof(self) innerstrongSelf = weakSelf; - if(innerstrongSelf.currentCircleStatus == kSOSCCInCircle) { + if(innerstrongSelf.currentCircleStatus && innerstrongSelf.currentCircleStatus.status == kSOSCCInCircle) { secnotice("ckksaccount", "Circle peerID is: %@ %@", peerID, error); // Still in circle. Proceed. innerstrongSelf.accountCirclePeerID = peerID; @@ -293,7 +294,7 @@ }]; } else { // Not in-circle, reset circle ID - secnotice("ckksaccount", "out of circle(%d): resetting peer ID", sosccstatus); + secnotice("ckksaccount", "out of circle(%@): resetting peer ID", sosstatus); self.accountCirclePeerID = nil; self.accountCirclePeerIDError = nil; self.accountCirclePeerIDInitialized = [[CKKSCondition alloc] init]; @@ -339,7 +340,7 @@ return false; } - if(self.currentCircleStatus != kSOSCCInCircle) { + if(self.currentCircleStatus.status != kSOSCCInCircle) { if(error) { *error = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain code:kSOSErrorNotInCircle @@ -351,12 +352,12 @@ return true; } --(void)_onqueueUpdateAccountState:(CKAccountInfo*)ckAccountInfo circle:(SOSCCStatus)sosccstatus deliveredSemaphore:(dispatch_semaphore_t)finishedSema { +-(void)_onqueueUpdateAccountState:(CKAccountInfo*)ckAccountInfo circle:(SOSAccountStatus*)sosstatus deliveredSemaphore:(dispatch_semaphore_t)finishedSema { dispatch_assert_queue(self.queue); - if([self.currentCKAccountInfo isEqual: ckAccountInfo] && self.currentCircleStatus == sosccstatus) { + if([self.currentCKAccountInfo isEqual: ckAccountInfo] && self.currentCircleStatus.status == sosstatus.status) { // no-op. - secinfo("ckksaccount", "received another notification of CK Account State %@ and Circle status %d", ckAccountInfo, (int)sosccstatus); + secinfo("ckksaccount", "received another notification of CK Account State %@ and Circle status %d", ckAccountInfo, (int)sosstatus); dispatch_semaphore_signal(finishedSema); return; } @@ -367,13 +368,13 @@ [self _onqueueUpdateCKDeviceID: ckAccountInfo]; } - if(self.currentCircleStatus != sosccstatus) { - secnotice("ckksaccount", "moving to circle status: %@", SOSCCGetStatusDescription(sosccstatus)); - self.currentCircleStatus = sosccstatus; - if (sosccstatus == kSOSCCInCircle) { + if(self.currentCircleStatus.status != sosstatus.status) { + secnotice("ckksaccount", "moving to circle status: %@", sosstatus); + self.currentCircleStatus = sosstatus; + if (sosstatus.status == kSOSCCInCircle) { [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastInCircle]; } - [self _onqueueUpdateCirclePeerID: sosccstatus]; + [self _onqueueUpdateCirclePeerID: sosstatus]; } if(!self.firstSOSCircleFetch || !self.firstCKAccountFetch) { @@ -382,6 +383,15 @@ return; } + if(self.currentCircleStatus.status == kSOSCCError && + [self.currentCircleStatus.error.domain isEqualToString:(__bridge id)kSOSErrorDomain] && + self.currentCircleStatus.error.code == kSOSErrorNotReady && + self.currentComputedAccountStatus == CKKSAccountStatusUnknown) { + secnotice("ckksaccount", "Device not unlocked yet; can't determine account status. Not passing update along: %@", self); + dispatch_semaphore_signal(finishedSema); + return; + } + CKKSAccountStatus oldComputedStatus = self.currentComputedAccountStatus; NSError* error = nil; @@ -398,7 +408,7 @@ secnotice("ckksaccount", "No change in computed account status: %@ (%@ %@)", [self currentStatus], self.currentCKAccountInfo, - SOSCCGetStatusDescription(self.currentCircleStatus)); + self.currentCircleStatus); dispatch_semaphore_signal(finishedSema); return; } @@ -406,7 +416,7 @@ secnotice("ckksaccount", "New computed account status: %@ (%@ %@)", [self currentStatus], self.currentCKAccountInfo, - SOSCCGetStatusDescription(self.currentCircleStatus)); + self.currentCircleStatus); [self _onqueueDeliverStateChanges:oldComputedStatus deliveredSemaphore:finishedSema]; } @@ -484,16 +494,16 @@ } // This is its own function to allow OCMock to swoop in and replace the result during testing. -+(SOSCCStatus)getCircleStatus { ++ (SOSAccountStatus*)getCircleStatus { CFErrorRef cferror = NULL; SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror); if(cferror) { secerror("ckksaccount: error getting circle status: %@", cferror); - CFReleaseNull(cferror); - return kSOSCCError; + return [[SOSAccountStatus alloc] init:kSOSCCError error:CFBridgingRelease(cferror)]; } - return status; + + return [[SOSAccountStatus alloc] init:status error:nil]; } -(NSString*)currentStatus { @@ -510,4 +520,20 @@ @end +@implementation SOSAccountStatus +- (instancetype)init:(SOSCCStatus)status error:(NSError*)error +{ + if((self = [super init])) { + _status = status; + _error = error; + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", SOSCCGetStatusDescription(self.status), self.error]; +} +@end + #endif // OCTAGON diff --git a/keychain/ckks/CKKSControl.h b/keychain/ckks/CKKSControl.h index 2e3434db..7407c313 100644 --- a/keychain/ckks/CKKSControl.h +++ b/keychain/ckks/CKKSControl.h @@ -43,7 +43,8 @@ typedef NS_ENUM(NSUInteger, CKKSKnownBadState) { - (void)rpcStatus:(NSString* _Nullable)viewName reply:(void (^)(NSArray* _Nullable result, NSError* _Nullable error))reply; - (void)rpcResetLocal:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply; -- (void)rpcResetCloudKit:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply; +- (void)rpcResetCloudKit:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply __deprecated_msg("use rpcResetCloudKit:reason:reply:"); +- (void)rpcResetCloudKit:(NSString* _Nullable)viewName reason:(NSString *)reason reply:(void (^)(NSError* _Nullable error))reply; - (void)rpcResync:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply; - (void)rpcFetchAndProcessChanges:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply; - (void)rpcFetchAndProcessClassAChanges:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply; diff --git a/keychain/ckks/CKKSControl.m b/keychain/ckks/CKKSControl.m index 3f56cf49..f541e02f 100644 --- a/keychain/ckks/CKKSControl.m +++ b/keychain/ckks/CKKSControl.m @@ -68,11 +68,20 @@ - (void)rpcResetCloudKit:(NSString*)viewName reply:(void(^)(NSError* error))reply { [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { reply(error); - }] rpcResetCloudKit:viewName reply:^(NSError* error){ + }] rpcResetCloudKit:viewName reason:[NSString stringWithFormat:@"%s", getprogname()] reply:^(NSError* error){ reply(error); }]; } +- (void)rpcResetCloudKit:(NSString*)viewName reason:(NSString *)reason reply:(void(^)(NSError* error))reply { + [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { + reply(error); + }] rpcResetCloudKit:viewName reason:reason reply:^(NSError* error){ + reply(error); + }]; +} + + - (void)rpcResync:(NSString*)viewName reply:(void(^)(NSError* error))reply { [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { reply(error); diff --git a/keychain/ckks/CKKSControlProtocol.h b/keychain/ckks/CKKSControlProtocol.h index bbf3bc40..ed1749b6 100644 --- a/keychain/ckks/CKKSControlProtocol.h +++ b/keychain/ckks/CKKSControlProtocol.h @@ -26,7 +26,13 @@ @protocol CKKSControlProtocol - (void)performanceCounters:(void(^)(NSDictionary *))reply; - (void)rpcResetLocal: (NSString*)viewName reply: (void(^)(NSError* result)) reply; -- (void)rpcResetCloudKit: (NSString*)viewName reply: (void(^)(NSError* result)) reply; +- (void)rpcResetCloudKit: (NSString*)viewName reply: (void(^)(NSError* result)) reply __deprecated_msg("use rpcResetCloudKit:reason:reply"); + +/** + * Reset CloudKit zone with a caller provided reason, the reason will be logged in the operation group + * name so that the reason for reset can be summarized server side. + */ +- (void)rpcResetCloudKit: (NSString*)viewName reason:(NSString *)reason reply: (void(^)(NSError* result)) reply; - (void)rpcResync:(NSString*)viewName reply: (void(^)(NSError* result)) reply; - (void)rpcResyncLocal:(NSString*)viewName reply:(void(^)(NSError* result))reply; - (void)rpcStatus:(NSString*)viewName reply: (void(^)(NSArray* result, NSError* error)) reply; diff --git a/keychain/ckks/CKKSControlProtocol.m b/keychain/ckks/CKKSControlProtocol.m index 5a73df3b..3821d8b1 100644 --- a/keychain/ckks/CKKSControlProtocol.m +++ b/keychain/ckks/CKKSControlProtocol.m @@ -95,6 +95,7 @@ NSXPCInterface* CKKSSetupControlProtocol(NSXPCInterface* interface) { @try { [interface setClasses:errClasses forSelector:@selector(rpcResetLocal:reply:) argumentIndex:0 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(rpcResetCloudKit:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(rpcResetCloudKit:reason:reply:) argumentIndex:0 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(rpcResync:reply:) argumentIndex:0 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(rpcStatus:reply:) argumentIndex:0 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(rpcStatus:reply:) argumentIndex:1 ofReply:YES]; diff --git a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h index 400ca965..46393ef6 100644 --- a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h +++ b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h @@ -26,30 +26,75 @@ #if OCTAGON @class CKKSKeychainView; #import "keychain/ckks/CKKSGroupOperation.h" -#import "keychain/ckks/CKKSZoneChangeFetcher.h" +#import "keychain/ckks/CloudKitDependencies.h" NS_ASSUME_NONNULL_BEGIN +/* Fetch Reasons */ +@protocol CKKSFetchBecauseProtocol +@end +typedef NSString CKKSFetchBecause; +extern CKKSFetchBecause* const CKKSFetchBecauseAPNS; +extern CKKSFetchBecause* const CKKSFetchBecauseAPIFetchRequest; +extern CKKSFetchBecause* const CKKSFetchBecauseCurrentItemFetchRequest; +extern CKKSFetchBecause* const CKKSFetchBecauseInitialStart; +extern CKKSFetchBecause* const CKKSFetchBecauseSecuritydRestart; +extern CKKSFetchBecause* const CKKSFetchBecausePreviousFetchFailed; +extern CKKSFetchBecause* const CKKSFetchBecauseKeyHierarchy; +extern CKKSFetchBecause* const CKKSFetchBecauseTesting; +extern CKKSFetchBecause* const CKKSFetchBecauseResync; + +/* Clients that register to use fetches */ +@interface CKKSCloudKitFetchRequest : NSObject +@property bool participateInFetch; +@property (nullable) CKServerChangeToken* changeToken; +@end + +@class CKKSCloudKitDeletion; +@protocol CKKSChangeFetcherClient +- (CKRecordZoneID*)zoneID; +- (CKKSCloudKitFetchRequest*)participateInFetch; +- (bool)notifyFetchError:(NSError*)error; +- (void)changesFetched:(NSArray*)changedRecords + deletedRecordIDs:(NSArray*)deleted + oldChangeToken:(CKServerChangeToken* _Nullable)oldChangeToken + newChangeToken:(CKServerChangeToken*)changeToken; +@end + +// I don't understand why recordType isn't part of record ID, but deletions come in as both things +@interface CKKSCloudKitDeletion : NSObject +@property CKRecordID* recordID; +@property NSString* recordType; +- (instancetype)initWithRecordID:(CKRecordID*)recordID recordType:(NSString*)recordType; +@end + + @interface CKKSFetchAllRecordZoneChangesOperation : CKKSGroupOperation +@property (readonly) Class fetchRecordZoneChangesOperationClass; +@property (readonly) CKContainer* container; // Set this to true before starting this operation if you'd like resync behavior: // Fetching everything currently in CloudKit and comparing to local copy @property bool resync; -@property (nullable, weak) CKKSKeychainView* ckks; -@property CKRecordZoneID* zoneID; +@property NSDictionary>* clientMap; +@property (nullable) NSMutableArray* fetchedZoneIDs; @property NSSet* fetchReasons; +@property NSSet* apnsPushes; @property NSMutableDictionary* modifications; -@property NSMutableDictionary* deletions; - -@property (nullable) CKServerChangeToken* serverChangeToken; +@property NSMutableDictionary* deletions; +@property NSMutableDictionary* changeTokens; - (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks - fetchReasons:(NSSet*)fetchReasons - ckoperationGroup:(CKOperationGroup*)ckoperationGroup; +- (instancetype)initWithContainer:(CKContainer*)container + fetchClass:(Class)fetchRecordZoneChangesOperationClass + clients:(NSArray>*)clients + fetchReasons:(NSSet*)fetchReasons + apnsPushes:(NSSet* _Nullable)apnsPushes + forceResync:(bool)forceResync + ckoperationGroup:(CKOperationGroup*)ckoperationGroup; @end diff --git a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m index a2eb44d1..42c20308 100644 --- a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m +++ b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m @@ -25,7 +25,12 @@ #if OCTAGON +#import +#import + +#import "keychain/categories/NSError+UsefulConstructors.h" #import "keychain/ckks/CloudKitDependencies.h" +#import "keychain/ckks/CloudKitCategories.h" #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSKeychainView.h" #import "keychain/ckks/CKKSZoneStateEntry.h" @@ -33,14 +38,32 @@ #import "keychain/ckks/CKKSMirrorEntry.h" #import "keychain/ckks/CKKSManifest.h" #import "keychain/ckks/CKKSManifestLeafRecord.h" +#import "NSError+UsefulConstructors.h" #import "CKKSPowerCollection.h" #include +@implementation CKKSCloudKitFetchRequest +@end + +@implementation CKKSCloudKitDeletion +- (instancetype)initWithRecordID:(CKRecordID*)recordID recordType:(NSString*)recordType +{ + if((self = [super init])) { + _recordID = recordID; + _recordType = recordType; + } + return self; +} +@end + @interface CKKSFetchAllRecordZoneChangesOperation() @property CKDatabaseOperation* fetchRecordZoneChangesOperation; +@property NSMutableDictionary* allClientOptions; + @property CKOperationGroup* ckoperationGroup; @property (assign) NSUInteger fetchedItems; +@property bool forceResync; @end @implementation CKKSFetchAllRecordZoneChangesOperation @@ -52,321 +75,262 @@ return nil; } -- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks - fetchReasons:(NSSet*)fetchReasons - ckoperationGroup:(CKOperationGroup*)ckoperationGroup { - +- (instancetype)initWithContainer:(CKContainer*)container + fetchClass:(Class)fetchRecordZoneChangesOperationClass + clients:(NSArray>*)clients + fetchReasons:(NSSet*)fetchReasons + apnsPushes:(NSSet*)apnsPushes + forceResync:(bool)forceResync + ckoperationGroup:(CKOperationGroup*)ckoperationGroup +{ if(self = [super init]) { - _ckks = ckks; + _container = container; + _fetchRecordZoneChangesOperationClass = fetchRecordZoneChangesOperationClass; + + NSMutableDictionary* clientMap = [NSMutableDictionary dictionary]; + for(id client in clients) { + clientMap[client.zoneID] = client; + } + _clientMap = [clientMap copy]; + _ckoperationGroup = ckoperationGroup; + _forceResync = forceResync; _fetchReasons = fetchReasons; - _zoneID = ckks.zoneID; - - _resync = false; + _apnsPushes = apnsPushes; _modifications = [[NSMutableDictionary alloc] init]; _deletions = [[NSMutableDictionary alloc] init]; - - // Can't fetch unless the zone is created. - [self addNullableDependency:ckks.zoneSetupOperation]; } return self; } -- (void)_onqueueRecordsChanged:(NSArray*)records -{ - for (CKRecord* record in records) { - [self.ckks _onqueueCKRecordChanged:record resync:self.resync]; - } -} - -- (void)_updateLatestTrustedManifest -{ - CKKSKeychainView* ckks = self.ckks; - NSError* error = nil; - NSArray* pendingManifests = [CKKSPendingManifest all:&error]; - NSUInteger greatestKnownManifestGeneration = [CKKSManifest greatestKnownGenerationCount]; - for (CKKSPendingManifest* manifest in pendingManifests) { - if (manifest.generationCount >= greatestKnownManifestGeneration) { - [manifest commitToDatabaseWithError:&error]; - } - else { - // if this is an older generation, just get rid of it - [manifest deleteFromDatabase:&error]; - } - } - - if (![ckks _onqueueUpdateLatestManifestWithError:&error]) { - self.error = error; - ckkserror("ckksfetch", ckks, "failed to get latest manifest"); - } -} - -- (void)_onqueueProcessRecordDeletions -{ - CKKSKeychainView* ckks = self.ckks; - [self.deletions enumerateKeysAndObjectsUsingBlock:^(CKRecordID * _Nonnull recordID, NSString * _Nonnull recordType, BOOL * _Nonnull stop) { - ckksinfo("ckksfetch", ckks, "Processing record deletion(%@): %@", recordType, recordID); - - // CKKS: Check Current Item pointers in the Manifest - // TODO: check that these deletions match a manifest upload - // Delegate these back up into the CKKS object for processing - [ckks _onqueueCKRecordDeleted:recordID recordType:recordType resync:self.resync]; - }]; -} - -- (void)_onqueueScanForExtraneousLocalItems -{ - // TODO: must scan through all CKMirrorEntries and determine if any exist that CloudKit didn't tell us about - CKKSKeychainView* ckks = self.ckks; - NSError* error = nil; - if(self.resync) { - ckksnotice("ckksresync", ckks, "Comparing local UUIDs against the CloudKit list"); - NSMutableArray* uuids = [[CKKSMirrorEntry allUUIDs:ckks.zoneID error:&error] mutableCopy]; - - for(NSString* uuid in uuids) { - if([self.modifications objectForKey: [[CKRecordID alloc] initWithRecordName: uuid zoneID: ckks.zoneID]]) { - ckksnotice("ckksresync", ckks, "UUID %@ is still in CloudKit; carry on.", uuid); - } else { - CKKSMirrorEntry* ckme = [CKKSMirrorEntry tryFromDatabase:uuid zoneID:ckks.zoneID error: &error]; - if(error != nil) { - ckkserror("ckksresync", ckks, "Couldn't read an item from the database, but it used to be there: %@ %@", uuid, error); - self.error = error; - continue; - } - if(!ckme) { - ckkserror("ckksresync", ckks, "Couldn't read ckme(%@) from database; continuing", uuid); - continue; - } - - ckkserror("ckksresync", ckks, "BUG: Local item %@ not found in CloudKit, deleting", uuid); - [ckks _onqueueCKRecordDeleted:ckme.item.storedCKRecord.recordID recordType:ckme.item.storedCKRecord.recordType resync:self.resync]; - } - } - } -} - - (void)groupStart { __weak __typeof(self) weakSelf = self; - CKKSKeychainView* ckks = self.ckks; - if(!ckks) { - ckkserror("ckksresync", ckks, "no CKKS object"); - return; - } + // Ask all our clients for their change tags + self.allClientOptions = [NSMutableDictionary dictionary]; + self.fetchedZoneIDs = [NSMutableArray array]; - [ckks dispatchSync: ^bool{ - ckks.lastRecordZoneChangesOperation = self; + // Unused until [ Changes to discretionary-ness (explicit or derived from QoS) should be "live"] has happened and we can determine network + // discretionaryness. + //bool nilChangeTag = false; - NSError* error = nil; - NSQualityOfService qos = NSQualityOfServiceUtility; + for(CKRecordZoneID* clientZoneID in self.clientMap) { + id client = self.clientMap[clientZoneID]; - CKFetchRecordZoneChangesOptions* options = [[CKFetchRecordZoneChangesOptions alloc] init]; - if(self.resync) { - ckksnotice("ckksresync", ckks, "Beginning resync fetch!"); + CKKSCloudKitFetchRequest* clientPreference = [client participateInFetch]; + if(clientPreference.participateInFetch) { + [self.fetchedZoneIDs addObject:client.zoneID]; - options.previousServerChangeToken = nil; + CKFetchRecordZoneChangesConfiguration* options = [[CKFetchRecordZoneChangesConfiguration alloc] init]; - // currently, resyncs are user initiated (or the key hierarchy is upset, which is implicitly user initiated) - qos = NSQualityOfServiceUserInitiated; - } else { - // This is the normal case: fetch only the delta since the last fetch - CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: ckks.zoneName]; - if(error || !ckse) { - ckkserror("ckksfetch", ckks, "couldn't fetch zone status for %@: %@", ckks.zoneName, error); - self.error = error; - return false; + if(!self.forceResync) { + options.previousServerChangeToken = clientPreference.changeToken; } - // If this is the first sync, or an API fetch, use QoS userInitated - if(ckse.changeToken == nil || [self.fetchReasons containsObject:CKKSFetchBecauseAPIFetchRequest]) { - qos = NSQualityOfServiceUserInitiated; - } + //if(options.previousServerChangeToken == nil) { + // nilChangeTag = true; + //} - options.previousServerChangeToken = ckse.changeToken; + self.allClientOptions[client.zoneID] = options; } + } - ckksnotice("ckksfetch", ckks, "Beginning fetch(%@) starting at change token %@ with QoS %d", ckks.zoneName, options.previousServerChangeToken, (int)qos); - - self.fetchRecordZoneChangesOperation = [[ckks.fetchRecordZoneChangesOperationClass alloc] initWithRecordZoneIDs: @[ckks.zoneID] optionsByRecordZoneID:@{ckks.zoneID: options}]; - - self.fetchRecordZoneChangesOperation.fetchAllChanges = YES; - self.fetchRecordZoneChangesOperation.qualityOfService = qos; - self.fetchRecordZoneChangesOperation.group = self.ckoperationGroup; - ckksnotice("ckksfetch", ckks, "Operation group is %@", self.ckoperationGroup); + if(self.fetchedZoneIDs.count == 0) { + // No clients actually want to fetch right now, so quit + self.error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSNoFetchesRequested description:@"No clients want a fetch right now"]; + secnotice("ckksfetch", "Cancelling fetch: %@", self.error); + return; + } - self.fetchRecordZoneChangesOperation.recordChangedBlock = ^(CKRecord *record) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf) { - ckkserror("ckksfetch", strongCKKS, "received callback for released object"); - return; - } + // Compute the network discretionary approach this fetch will take. + // For now, everything is nondiscretionary, because we can't afford to block a nondiscretionary request later. + // Once [ Changes to discretionary-ness (explicit or derived from QoS) should be "live"] happens, we can come back through and make things + // discretionary, but boost them later. + // + // Rules: + // If there's a nil change tag, go to nondiscretionary. This is likely a zone bringup (which happens during iCloud sign-in) or a resync (which happens due to user input) + // If the fetch reasons include an API fetch, an initial start or a key hierarchy fetch, become nondiscretionary as well. + + CKOperationDiscretionaryNetworkBehavior networkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + //if(nilChangeTag || + // [self.fetchReasons containsObject:CKKSFetchBecauseAPIFetchRequest] || + // [self.fetchReasons containsObject:CKKSFetchBecauseInitialStart] || + // [self.fetchReasons containsObject:CKKSFetchBecauseKeyHierarchy]) { + // networkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + //} + + secnotice("ckks", "Beginning fetch with discretionary network (%d): %@", (int)networkBehavior, self.allClientOptions); + self.fetchRecordZoneChangesOperation = [[self.fetchRecordZoneChangesOperationClass alloc] initWithRecordZoneIDs:self.fetchedZoneIDs + configurationsByRecordZoneID:self.allClientOptions]; + + self.fetchRecordZoneChangesOperation.fetchAllChanges = YES; + self.fetchRecordZoneChangesOperation.configuration.discretionaryNetworkBehavior = networkBehavior; + self.fetchRecordZoneChangesOperation.group = self.ckoperationGroup; + secnotice("ckksfetch", "Operation group is %@", self.ckoperationGroup); + + self.fetchRecordZoneChangesOperation.recordChangedBlock = ^(CKRecord *record) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + secinfo("ckksfetch", "CloudKit notification: record changed(%@): %@", [record recordType], record); + + // Add this to the modifications, and remove it from the deletions + strongSelf.modifications[record.recordID] = record; + [strongSelf.deletions removeObjectForKey:record.recordID]; + strongSelf.fetchedItems++; + }; + + self.fetchRecordZoneChangesOperation.recordWithIDWasDeletedBlock = ^(CKRecordID *recordID, NSString *recordType) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + secinfo("ckksfetch", "CloudKit notification: deleted record(%@): %@", recordType, recordID); + + // Add to the deletions, and remove any pending modifications + [strongSelf.modifications removeObjectForKey: recordID]; + strongSelf.deletions[recordID] = [[CKKSCloudKitDeletion alloc] initWithRecordID:recordID recordType:recordType]; + strongSelf.fetchedItems++; + }; + + self.fetchRecordZoneChangesOperation.recordZoneChangeTokensUpdatedBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + + secinfo("ckksfetch", "Received a new server change token for %@: %@ %@", recordZoneID, serverChangeToken, clientChangeTokenData); + strongSelf.changeTokens[recordZoneID] = serverChangeToken; + }; + + self.fetchRecordZoneChangesOperation.recordZoneFetchCompletionBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData, BOOL moreComing, NSError * recordZoneError) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + if(!strongSelf) { + secerror("ckksfetch: received callback for released object"); + return; + } - ckksinfo("ckksfetch", strongCKKS, "CloudKit notification: record changed(%@): %@", [record recordType], record); + id client = strongSelf.clientMap[recordZoneID]; + if(!client) { + secerror("ckksfetch: no client registered for %@, so why did we get any data?", recordZoneID); + return; + } - // Add this to the modifications, and remove it from the deletions - [strongSelf.modifications setObject: record forKey: record.recordID]; - [strongSelf.deletions removeObjectForKey: record.recordID]; - strongSelf.fetchedItems++; - }; + // First, filter the modifications and deletions for this zone + NSMutableArray* zoneModifications = [NSMutableArray array]; + NSMutableArray* zoneDeletions = [NSMutableArray array]; - self.fetchRecordZoneChangesOperation.recordWithIDWasDeletedBlock = ^(CKRecordID *recordID, NSString *recordType) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf) { - ckkserror("ckksfetch", strongCKKS, "received callback for released object"); - return; + [strongSelf.modifications enumerateKeysAndObjectsUsingBlock:^(CKRecordID* _Nonnull recordID, + CKRecord* _Nonnull record, + BOOL* stop) { + if([recordID.zoneID isEqual:recordZoneID]) { + ckksinfo("ckksfetch", recordZoneID, "Sorting record modification %@: %@", recordID, record); + [zoneModifications addObject:record]; } - - ckksinfo("ckksfetch", strongCKKS, "CloudKit notification: deleted record(%@): %@", recordType, recordID); - - // Add to the deletions, and remove any pending modifications - [strongSelf.modifications removeObjectForKey: recordID]; - [strongSelf.deletions setObject: recordType forKey: recordID]; - strongSelf.fetchedItems++; - }; - - // This class only supports fetching from a single zone, so we can ignore recordZoneID - self.fetchRecordZoneChangesOperation.recordZoneChangeTokensUpdatedBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf) { - ckkserror("ckksfetch", strongCKKS, "received callback for released object"); - return; + }]; + + [strongSelf.deletions enumerateKeysAndObjectsUsingBlock:^(CKRecordID* _Nonnull recordID, + CKKSCloudKitDeletion* _Nonnull deletion, + BOOL* _Nonnull stop) { + if([recordID.zoneID isEqual:recordZoneID]) { + ckksinfo("ckksfetch", recordZoneID, "Sorting record deletion %@: %@", recordID, deletion); + [zoneDeletions addObject:deletion]; } + }]; + + ckksnotice("ckksfetch", recordZoneID, "Record zone fetch complete: changeToken=%@ clientChangeTokenData=%@ changed=%lu deleted=%lu error=%@", serverChangeToken, clientChangeTokenData, + (unsigned long)zoneModifications.count, + (unsigned long)zoneDeletions.count, + recordZoneError); + + if(recordZoneError == nil) { + // Tell the client about these changes! + [client changesFetched:zoneModifications + deletedRecordIDs:zoneDeletions + oldChangeToken:strongSelf.allClientOptions[recordZoneID].previousServerChangeToken + newChangeToken:serverChangeToken]; + ckksnotice("ckksfetch", recordZoneID, "Finished processing fetch"); + } + }; + + // Completion blocks don't count for dependencies. Use this intermediate operation hack instead. + CKKSResultOperation* recordZoneChangesCompletedOperation = [CKKSResultOperation named:@"record-zone-changes-completed" withBlock:^{}]; + + // Called with overall operation success. As I understand it, this block will be called for every operation. + // In the case of, e.g., network failure, the recordZoneFetchCompletionBlock will not be called, but this one will. + self.fetchRecordZoneChangesOperation.fetchRecordZoneChangesCompletionBlock = ^(NSError * _Nullable operationError) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + if(!strongSelf) { + secerror("ckksfetch: received callback for released object"); + return; + } - ckksinfo("ckksfetch", strongCKKS, "Received a new server change token: %@ %@", serverChangeToken, clientChangeTokenData); - strongSelf.serverChangeToken = serverChangeToken; - }; - - // Completion blocks don't count for dependencies. Use this intermediate operation hack instead. - NSBlockOperation* recordZoneChangesCompletedOperation = [[NSBlockOperation alloc] init]; - recordZoneChangesCompletedOperation.name = @"record-zone-changes-completed"; + secnotice("ckksfetch", "Record zone changes fetch complete: error=%@", operationError); + if(operationError) { + strongSelf.error = operationError; + } - self.fetchRecordZoneChangesOperation.recordZoneFetchCompletionBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData, BOOL moreComing, NSError * recordZoneError) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) blockCKKS = strongSelf.ckks; + [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventFetchAllChanges + count:strongSelf.fetchedItems]; - if(!strongSelf) { - ckkserror("ckksfetch", blockCKKS, "received callback for released object"); - return; - } + // Count record changes per zone + NSMutableDictionary* recordChangesPerZone = [NSMutableDictionary dictionary]; + NSNumber* totalModifications = [NSNumber numberWithUnsignedLong:strongSelf.modifications.count]; + NSNumber* totalDeletions = [NSNumber numberWithUnsignedLong:strongSelf.deletions.count]; - if(!blockCKKS) { - ckkserror("ckksfetch", blockCKKS, "no CKKS object"); - return; - } - - ckksnotice("ckksfetch", blockCKKS, "Record zone fetch complete: changeToken=%@ clientChangeTokenData=%@ changed=%lu deleted=%lu error=%@", serverChangeToken, clientChangeTokenData, - (unsigned long)strongSelf.modifications.count, - (unsigned long)strongSelf.deletions.count, - recordZoneError); + for(CKRecordID* recordID in strongSelf.modifications) { + NSNumber* last = recordChangesPerZone[recordID.zoneID]; + recordChangesPerZone[recordID.zoneID] = [NSNumber numberWithUnsignedLong:1+(last ? [last unsignedLongValue] : 0)]; + } + for(CKRecordID* recordID in strongSelf.deletions) { + NSNumber* last = recordChangesPerZone[recordID.zoneID]; + recordChangesPerZone[recordID.zoneID] = [NSNumber numberWithUnsignedLong:1+(last ? [last unsignedLongValue] : 0)]; + } - // Completion! Mark these down. - if(recordZoneError) { - strongSelf.error = recordZoneError; - } - strongSelf.serverChangeToken = serverChangeToken; - - if(recordZoneError != nil) { - // An error occurred. All our fetches are useless. Skip to the end. - } else { - // Commit these changes! - __block NSError* error = nil; - - NSMutableDictionary* changedRecordsDict = [[NSMutableDictionary alloc] init]; - - [blockCKKS dispatchSyncWithAccountKeys:^bool{ - // let's process records in a specific order by type - // 1. Manifest leaf records, without which the manifest master records are meaningless - // 2. Manifest master records, which will be used to validate incoming items - // 3. Intermediate key records - // 4. Current key records - // 5. Item records - - [strongSelf.modifications enumerateKeysAndObjectsUsingBlock:^(CKRecordID* _Nonnull recordID, CKRecord* _Nonnull record, BOOL* stop) { - ckksinfo("ckksfetch", blockCKKS, "Sorting record modification %@: %@", recordID, record); - NSMutableArray* changedRecordsByType = changedRecordsDict[record.recordType]; - if(!changedRecordsByType) { - changedRecordsByType = [[NSMutableArray alloc] init]; - changedRecordsDict[record.recordType] = changedRecordsByType; - }; - - [changedRecordsByType addObject:record]; - }]; - - if ([CKKSManifest shouldSyncManifests]) { - if (!strongSelf.resync) { - [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordManifestLeafType]]; - [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordManifestType]]; - } - - [strongSelf _updateLatestTrustedManifest]; - } + for(CKRecordZoneNotification* rz in strongSelf.apnsPushes) { + if(rz.ckksPushTracingEnabled) { + secnotice("ckksfetch", "Submitting post-fetch CKEventMetric due to notification %@", rz); + + // Schedule submitting this metric on another operation, so hopefully CK will have marked this fetch as done by the time that fires? + CKEventMetric *metric = [[CKEventMetric alloc] initWithEventName:@"APNSPushMetrics"]; + metric.isPushTriggerFired = true; + metric[@"push_token_uuid"] = rz.ckksPushTracingUUID; + metric[@"push_received_date"] = rz.ckksPushReceivedDate; + metric[@"push_event_name"] = @"CKKS Push"; + + metric[@"fetch_error"] = operationError ? @1 : @0; + metric[@"fetch_error_domain"] = operationError.domain; + metric[@"fetch_error_code"] = [NSNumber numberWithLong:operationError.code]; + + metric[@"total_modifications"] = totalModifications; + metric[@"total_deletions"] = totalDeletions; + for(CKRecordZoneID* zoneID in recordChangesPerZone) { + metric[zoneID.zoneName] = recordChangesPerZone[zoneID]; + } - [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordIntermediateKeyType]]; - [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordCurrentKeyType]]; - [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordItemType]]; - [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordCurrentItemType]]; - [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordDeviceStateType]]; - [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordTLKShareType]]; - - [strongSelf _onqueueProcessRecordDeletions]; - [strongSelf _onqueueScanForExtraneousLocalItems]; - - CKKSZoneStateEntry* state = [CKKSZoneStateEntry state: blockCKKS.zoneName]; - state.lastFetchTime = [NSDate date]; // The last fetch happened right now! - if(strongSelf.serverChangeToken) { - ckksdebug("ckksfetch", blockCKKS, "Zone change fetch complete: saving new server change token: %@", strongSelf.serverChangeToken); - state.changeToken = strongSelf.serverChangeToken; - } - [state saveToDatabase:&error]; - if(error) { - ckkserror("ckksfetch", blockCKKS, "Couldn't save new server change token: %@", error); - strongSelf.error = error; - } + // Okay, we now have this metric. But, it's unclear if calling associateWithCompletedOperation in this block will work. So, do something silly with operation scheduling. + // Grab pointers to these things + CKContainer* container = strongSelf.container; + CKDatabaseOperation* rzcOperation = strongSelf.fetchRecordZoneChangesOperation; - if(error) { - ckkserror("ckksfetch", blockCKKS, "horrible error occurred: %@", error); - strongSelf.error = error; - return false; + CKKSResultOperation* launchMetricOp = [CKKSResultOperation named:@"submit-metric" withBlock:^{ + if(![metric associateWithCompletedOperation:rzcOperation]) { + secerror("ckksfetch: Couldn't associate metric with operation: %@ %@", metric, rzcOperation); } - - ckksnotice("ckksfetch", blockCKKS, "Finished processing fetch for %@", recordZoneID); - - return true; + [container submitEventMetric:metric]; + secnotice("ckksfetch", "Metric submitted: %@", metric); }]; - } - }; - - // Called with overall operation success. As I understand it, this block will be called for every operation. - // In the case of, e.g., network failure, the recordZoneFetchCompletionBlock will not be called, but this one will. - self.fetchRecordZoneChangesOperation.fetchRecordZoneChangesCompletionBlock = ^(NSError * _Nullable operationError) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf) { - ckkserror("ckksfetch", strongCKKS, "received callback for released object"); - return; - } + [launchMetricOp addSuccessDependency:recordZoneChangesCompletedOperation]; - ckksnotice("ckksfetch", strongCKKS, "Record zone changes fetch complete: error=%@", operationError); - if(operationError) { - strongSelf.error = operationError; + [strongSelf.operationQueue addOperation:launchMetricOp]; } + } - [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventFetchAllChanges zone:ckks.zoneName count:strongSelf.fetchedItems]; + // Don't need these any more; save some memory + [strongSelf.modifications removeAllObjects]; + [strongSelf.deletions removeAllObjects]; + // Trigger the fake 'we're done' operation. + [strongSelf runBeforeGroupFinished: recordZoneChangesCompletedOperation]; + }; - // Trigger the fake 'we're done' operation. - [strongSelf runBeforeGroupFinished: recordZoneChangesCompletedOperation]; - }; + [self dependOnBeforeGroupFinished:recordZoneChangesCompletedOperation]; + [self dependOnBeforeGroupFinished:self.fetchRecordZoneChangesOperation]; - [self dependOnBeforeGroupFinished: recordZoneChangesCompletedOperation]; - [self dependOnBeforeGroupFinished: self.fetchRecordZoneChangesOperation]; - [ckks.database addOperation: self.fetchRecordZoneChangesOperation]; - return true; - }]; + [self.container.privateCloudDatabase addOperation:self.fetchRecordZoneChangesOperation]; } - (void)cancel { diff --git a/keychain/ckks/CKKSFixups.m b/keychain/ckks/CKKSFixups.m index 97de7c4b..2f20fc78 100644 --- a/keychain/ckks/CKKSFixups.m +++ b/keychain/ckks/CKKSFixups.m @@ -27,6 +27,7 @@ #import "keychain/ckks/CloudKitCategories.h" #import "keychain/ckks/CKKSCurrentItemPointer.h" #import "keychain/ckks/CKKSZoneStateEntry.h" +#import "keychain/categories/NSError+UsefulConstructors.h" @implementation CKKSFixups +(CKKSGroupOperation*)fixup:(CKKSFixup)lastfixup for:(CKKSKeychainView*)keychainView diff --git a/keychain/ckks/CKKSHealKeyHierarchyOperation.m b/keychain/ckks/CKKSHealKeyHierarchyOperation.m index fdf0b0cb..afc9862a 100644 --- a/keychain/ckks/CKKSHealKeyHierarchyOperation.m +++ b/keychain/ckks/CKKSHealKeyHierarchyOperation.m @@ -28,6 +28,7 @@ #import "CKKSGroupOperation.h" #import "CKKSAnalytics.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #if OCTAGON @@ -301,7 +302,11 @@ modifyRecordsOp = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave recordIDsToDelete:recordIDsToDelete]; modifyRecordsOp.atomic = YES; modifyRecordsOp.longLived = NO; // The keys are only in memory; mark this explicitly not long-lived - modifyRecordsOp.qualityOfService = NSQualityOfServiceUserInitiated; // This needs to happen for CKKS to be usable by PCS/cloudd. Make it happen. + + // This needs to happen for CKKS to be usable by PCS/cloudd. Make it happen. + modifyRecordsOp.configuration.automaticallyRetryNetworkFailures = NO; + modifyRecordsOp.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + modifyRecordsOp.group = self.ckoperationGroup; ckksnotice("ckksheal", ckks, "Operation group is %@", self.ckoperationGroup); @@ -371,8 +376,7 @@ return false; } else { // Everything is groovy. HOWEVER, we might still not have processed the keys. Ask for that! - [strongCKKS _onqueueKeyStateMachineRequestProcess]; - [strongCKKS _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateReady withError: nil]; + [strongCKKS _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateProcess withError: nil]; } } else { // ERROR. This isn't a total-failure error state, but one that should kick off a healing process. diff --git a/keychain/ckks/CKKSHealTLKSharesOperation.m b/keychain/ckks/CKKSHealTLKSharesOperation.m index 90413363..378cff06 100644 --- a/keychain/ckks/CKKSHealTLKSharesOperation.m +++ b/keychain/ckks/CKKSHealTLKSharesOperation.m @@ -23,6 +23,9 @@ #if OCTAGON +#import +#import + #import "keychain/ckks/CKKSKeychainView.h" #import "keychain/ckks/CKKSCurrentKeyPointer.h" #import "keychain/ckks/CKKSKey.h" @@ -140,7 +143,11 @@ recordIDsToDelete:recordIDsToDelete]; modifyRecordsOp.atomic = YES; modifyRecordsOp.longLived = NO; - modifyRecordsOp.qualityOfService = NSQualityOfServiceUserInitiated; // very important: get the TLKShares off-device ASAP + + // very important: get the TLKShares off-device ASAP + modifyRecordsOp.configuration.automaticallyRetryNetworkFailures = NO; + modifyRecordsOp.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + modifyRecordsOp.group = self.ckoperationGroup; ckksnotice("ckksshare", ckks, "Operation group is %@", self.ckoperationGroup); diff --git a/keychain/ckks/CKKSIncomingQueueOperation.m b/keychain/ckks/CKKSIncomingQueueOperation.m index b609c2e0..3f836700 100644 --- a/keychain/ckks/CKKSIncomingQueueOperation.m +++ b/keychain/ckks/CKKSIncomingQueueOperation.m @@ -106,25 +106,27 @@ NSError* error = nil; for(CKKSCurrentItemPointer* p in queueEntries) { - if ([CKKSManifest shouldSyncManifests]) { - if (![manifest validateCurrentItem:p withError:&error]) { - ckkserror("ckksincoming", ckks, "Unable to validate current item pointer (%@) against manifest (%@)", p, manifest); - if ([CKKSManifest shouldEnforceManifests]) { - return false; + @autoreleasepool { + if ([CKKSManifest shouldSyncManifests]) { + if (![manifest validateCurrentItem:p withError:&error]) { + ckkserror("ckksincoming", ckks, "Unable to validate current item pointer (%@) against manifest (%@)", p, manifest); + if ([CKKSManifest shouldEnforceManifests]) { + return false; + } } } - } - p.state = SecCKKSProcessedStateLocal; + p.state = SecCKKSProcessedStateLocal; - [p saveToDatabase:&error]; - ckksnotice("ckkspointer", ckks, "Saving new current item pointer: %@", p); - if(error) { - ckkserror("ckksincoming", ckks, "Error saving new current item pointer: %@ %@", error, p); - } + [p saveToDatabase:&error]; + ckksnotice("ckkspointer", ckks, "Saving new current item pointer: %@", p); + if(error) { + ckkserror("ckksincoming", ckks, "Error saving new current item pointer: %@ %@", error, p); + } - // Schedule a view change notification - [ckks.notifyViewChangedScheduler trigger]; + // Schedule a view change notification + [ckks.notifyViewChangedScheduler trigger]; + } } if(queueEntries.count > 0) { @@ -143,121 +145,123 @@ NSMutableArray* deletedRecordIDs = [[NSMutableArray alloc] init]; for(id entry in queueEntries) { - if(self.cancelled) { - ckksnotice("ckksincoming", ckks, "CKKSIncomingQueueOperation cancelled, quitting"); - return false; - } + @autoreleasepool { + if(self.cancelled) { + ckksnotice("ckksincoming", ckks, "CKKSIncomingQueueOperation cancelled, quitting"); + return false; + } - NSError* error = nil; - - CKKSIncomingQueueEntry* iqe = (CKKSIncomingQueueEntry*) entry; - ckksnotice("ckksincoming", ckks, "ready to process an incoming queue entry: %@ %@ %@", iqe, iqe.uuid, iqe.action); - - // Note that we currently unencrypt the item before deleting it, instead of just deleting it - // This finds the class, which is necessary for the deletion process. We could just try to delete - // across all classes, though... - NSMutableDictionary* attributes = [[CKKSItemEncrypter decryptItemToDictionary: iqe.item error:&error] mutableCopy]; - if(!attributes || error) { - if([ckks.lockStateTracker isLockedError:error]) { - NSError* localerror = nil; - ckkserror("ckksincoming", ckks, "Keychain is locked; can't decrypt IQE %@", iqe); - CKKSKey* key = [CKKSKey tryFromDatabase:iqe.item.parentKeyUUID zoneID:ckks.zoneID error:&localerror]; - if(localerror || ([key.keyclass isEqualToString:SecCKKSKeyClassA] && self.errorOnClassAFailure)) { - self.error = error; - } + NSError* error = nil; + + CKKSIncomingQueueEntry* iqe = (CKKSIncomingQueueEntry*) entry; + ckksnotice("ckksincoming", ckks, "ready to process an incoming queue entry: %@ %@ %@", iqe, iqe.uuid, iqe.action); + + // Note that we currently unencrypt the item before deleting it, instead of just deleting it + // This finds the class, which is necessary for the deletion process. We could just try to delete + // across all classes, though... + NSMutableDictionary* attributes = [[CKKSItemEncrypter decryptItemToDictionary: iqe.item error:&error] mutableCopy]; + if(!attributes || error) { + if([ckks.lockStateTracker isLockedError:error]) { + NSError* localerror = nil; + ckkserror("ckksincoming", ckks, "Keychain is locked; can't decrypt IQE %@", iqe); + CKKSKey* key = [CKKSKey tryFromDatabase:iqe.item.parentKeyUUID zoneID:ckks.zoneID error:&localerror]; + if(localerror || ([key.keyclass isEqualToString:SecCKKSKeyClassA] && self.errorOnClassAFailure)) { + self.error = error; + } - // If this isn't an error, make sure it gets processed later. - if([key.keyclass isEqualToString:SecCKKSKeyClassA] && !self.errorOnClassAFailure) { - self.pendingClassAEntries = true; - } + // If this isn't an error, make sure it gets processed later. + if([key.keyclass isEqualToString:SecCKKSKeyClassA] && !self.errorOnClassAFailure) { + self.pendingClassAEntries = true; + } - } else if ([error.domain isEqualToString:@"securityd"] && error.code == errSecItemNotFound) { - ckkserror("ckksincoming", ckks, "Coudn't find key in keychain; will attempt to poke key hierarchy: %@", error) - self.missingKey = true; + } else if ([error.domain isEqualToString:@"securityd"] && error.code == errSecItemNotFound) { + ckkserror("ckksincoming", ckks, "Coudn't find key in keychain; will attempt to poke key hierarchy: %@", error) + self.missingKey = true; - } else { - ckkserror("ckksincoming", ckks, "Couldn't decrypt IQE %@ for some reason: %@", iqe, error); - self.error = error; + } else { + ckkserror("ckksincoming", ckks, "Couldn't decrypt IQE %@ for some reason: %@", iqe, error); + self.error = error; + } + self.errorItemsProcessed += 1; + continue; } - self.errorItemsProcessed += 1; - continue; - } - // Add the UUID (which isn't stored encrypted) - [attributes setValue: iqe.item.uuid forKey: (__bridge NSString*) kSecAttrUUID]; + // Add the UUID (which isn't stored encrypted) + [attributes setValue: iqe.item.uuid forKey: (__bridge NSString*) kSecAttrUUID]; - // Add the PCS plaintext fields, if they exist - if(iqe.item.plaintextPCSServiceIdentifier) { - [attributes setValue: iqe.item.plaintextPCSServiceIdentifier forKey: (__bridge NSString*) kSecAttrPCSPlaintextServiceIdentifier]; - } - if(iqe.item.plaintextPCSPublicKey) { - [attributes setValue: iqe.item.plaintextPCSPublicKey forKey: (__bridge NSString*) kSecAttrPCSPlaintextPublicKey]; - } - if(iqe.item.plaintextPCSPublicIdentity) { - [attributes setValue: iqe.item.plaintextPCSPublicIdentity forKey: (__bridge NSString*) kSecAttrPCSPlaintextPublicIdentity]; - } - - // This item is also synchronizable (by definition) - [attributes setValue: @(YES) forKey: (__bridge NSString*) kSecAttrSynchronizable]; - - NSString* classStr = [attributes objectForKey: (__bridge NSString*) kSecClass]; - if(![classStr isKindOfClass: [NSString class]]) { - self.error = [NSError errorWithDomain:@"securityd" - code:errSecInternalError - userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Item did not have a reasonable class: %@", classStr]}]; - ckkserror("ckksincoming", ckks, "Synced item seems wrong: %@", self.error); - self.errorItemsProcessed += 1; - continue; - } + // Add the PCS plaintext fields, if they exist + if(iqe.item.plaintextPCSServiceIdentifier) { + [attributes setValue: iqe.item.plaintextPCSServiceIdentifier forKey: (__bridge NSString*) kSecAttrPCSPlaintextServiceIdentifier]; + } + if(iqe.item.plaintextPCSPublicKey) { + [attributes setValue: iqe.item.plaintextPCSPublicKey forKey: (__bridge NSString*) kSecAttrPCSPlaintextPublicKey]; + } + if(iqe.item.plaintextPCSPublicIdentity) { + [attributes setValue: iqe.item.plaintextPCSPublicIdentity forKey: (__bridge NSString*) kSecAttrPCSPlaintextPublicIdentity]; + } - const SecDbClass * classP = !classStr ? NULL : kc_class_with_name((__bridge CFStringRef) classStr); + // This item is also synchronizable (by definition) + [attributes setValue: @(YES) forKey: (__bridge NSString*) kSecAttrSynchronizable]; - if(!classP) { - ckkserror("ckksincoming", ckks, "unknown class in object: %@ %@", classStr, iqe); - iqe.state = SecCKKSStateError; - [iqe saveToDatabase:&error]; - if(error) { - ckkserror("ckksincoming", ckks, "Couldn't save errored IQE to database: %@", error); - self.error = error; + NSString* classStr = [attributes objectForKey: (__bridge NSString*) kSecClass]; + if(![classStr isKindOfClass: [NSString class]]) { + self.error = [NSError errorWithDomain:@"securityd" + code:errSecInternalError + userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Item did not have a reasonable class: %@", classStr]}]; + ckkserror("ckksincoming", ckks, "Synced item seems wrong: %@", self.error); + self.errorItemsProcessed += 1; + continue; } - self.errorItemsProcessed += 1; - continue; - } - if([iqe.action isEqualToString: SecCKKSActionAdd] || [iqe.action isEqualToString: SecCKKSActionModify]) { - BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests]; - BOOL manifestValidatesItem = [manifest validateItem:iqe.item withError:&error]; + const SecDbClass * classP = !classStr ? NULL : kc_class_with_name((__bridge CFStringRef) classStr); - if (!requireManifestValidation || manifestValidatesItem) { - [self _onqueueHandleIQEChange: iqe attributes:attributes class:classP]; - [newOrChangedRecords addObject:[iqe.item CKRecordWithZoneID:ckks.zoneID]]; - } - else { - ckkserror("ckksincoming", ckks, "could not validate incoming item against manifest with error: %@", error); - if (![self _onqueueUpdateIQE:iqe withState:SecCKKSStateUnauthenticated error:&error]) { - ckkserror("ckksincoming", ckks, "failed to save incoming item back to database in unauthenticated state with error: %@", error); - return false; + if(!classP) { + ckkserror("ckksincoming", ckks, "unknown class in object: %@ %@", classStr, iqe); + iqe.state = SecCKKSStateError; + [iqe saveToDatabase:&error]; + if(error) { + ckkserror("ckksincoming", ckks, "Couldn't save errored IQE to database: %@", error); + self.error = error; } self.errorItemsProcessed += 1; continue; } - } else if ([iqe.action isEqualToString: SecCKKSActionDelete]) { - BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests]; - BOOL manifestValidatesDelete = ![manifest itemUUIDExistsInManifest:iqe.uuid]; - - if (!requireManifestValidation || manifestValidatesDelete) { - // if the item does not exist in the latest manifest, we're good to delete it - [self _onqueueHandleIQEDelete: iqe class:classP]; - [deletedRecordIDs addObject:[[CKRecordID alloc] initWithRecordName:iqe.uuid zoneID:ckks.zoneID]]; - } - else { - // if the item DOES exist in the manifest, we can't trust the deletion - ckkserror("ckksincoming", ckks, "could not validate incoming item deletion against manifest"); - if (![self _onqueueUpdateIQE:iqe withState:SecCKKSStateUnauthenticated error:&error]) { - ckkserror("ckksincoming", ckks, "failed to save incoming item deletion back to database in unauthenticated state with error: %@", error); + if([iqe.action isEqualToString: SecCKKSActionAdd] || [iqe.action isEqualToString: SecCKKSActionModify]) { + BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests]; + BOOL manifestValidatesItem = [manifest validateItem:iqe.item withError:&error]; + + if (!requireManifestValidation || manifestValidatesItem) { + [self _onqueueHandleIQEChange: iqe attributes:attributes class:classP]; + [newOrChangedRecords addObject:[iqe.item CKRecordWithZoneID:ckks.zoneID]]; + } + else { + ckkserror("ckksincoming", ckks, "could not validate incoming item against manifest with error: %@", error); + if (![self _onqueueUpdateIQE:iqe withState:SecCKKSStateUnauthenticated error:&error]) { + ckkserror("ckksincoming", ckks, "failed to save incoming item back to database in unauthenticated state with error: %@", error); + return false; + } self.errorItemsProcessed += 1; - return false; + continue; + } + } else if ([iqe.action isEqualToString: SecCKKSActionDelete]) { + BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests]; + BOOL manifestValidatesDelete = ![manifest itemUUIDExistsInManifest:iqe.uuid]; + + if (!requireManifestValidation || manifestValidatesDelete) { + // if the item does not exist in the latest manifest, we're good to delete it + [self _onqueueHandleIQEDelete: iqe class:classP]; + [deletedRecordIDs addObject:[[CKRecordID alloc] initWithRecordName:iqe.uuid zoneID:ckks.zoneID]]; + } + else { + // if the item DOES exist in the manifest, we can't trust the deletion + ckkserror("ckksincoming", ckks, "could not validate incoming item deletion against manifest"); + if (![self _onqueueUpdateIQE:iqe withState:SecCKKSStateUnauthenticated error:&error]) { + ckkserror("ckksincoming", ckks, "failed to save incoming item deletion back to database in unauthenticated state with error: %@", error); + + self.errorItemsProcessed += 1; + return false; + } } } } @@ -437,7 +441,7 @@ } // Process other queues: CKKSCurrentItemPointers - ckksnotice("ckksincoming", ckks, "Processed %lu items in incoming queue (%lu errors)", self.successfulItemsProcessed, self.errorItemsProcessed); + ckksnotice("ckksincoming", ckks, "Processed %lu items in incoming queue (%lu errors)", (unsigned long)self.successfulItemsProcessed, (unsigned long)self.errorItemsProcessed); NSArray* newCIPs = [CKKSCurrentItemPointer remoteItemPointers:ckks.zoneID error:&error]; if(error || !newCIPs) { @@ -446,7 +450,7 @@ if (![self processNewCurrentItemPointers:newCIPs withManifest:ckks.latestManifest egoManifest:ckks.egoManifest]) { return false; } - ckksnotice("ckksincoming", ckks, "Processed %lu items in CIP queue", newCIPs.count); + ckksnotice("ckksincoming", ckks, "Processed %lu items in CIP queue", (unsigned long)newCIPs.count); } if(self.newOutgoingEntries) { diff --git a/keychain/ckks/CKKSItem.m b/keychain/ckks/CKKSItem.m index e8ab777e..88d9841b 100644 --- a/keychain/ckks/CKKSItem.m +++ b/keychain/ckks/CKKSItem.m @@ -428,7 +428,7 @@ plaintextPCSServiceIdentifier: (NSNumber*) pcsServiceIdentifier return @{@"UUID": self.uuid, @"ckzone":self.zoneID.zoneName}; } -- (NSDictionary*)sqlValues { +- (NSDictionary*)sqlValues { return @{@"UUID": self.uuid, @"parentKeyUUID": self.parentKeyUUID, @"ckzone": CKKSNilToNSNull(self.zoneID.zoneName), diff --git a/keychain/ckks/CKKSKey.m b/keychain/ckks/CKKSKey.m index a927bec6..441080b9 100644 --- a/keychain/ckks/CKKSKey.m +++ b/keychain/ckks/CKKSKey.m @@ -27,7 +27,7 @@ #import "CKKSKeychainView.h" #import "CKKSCurrentKeyPointer.h" #import "CKKSKey.h" -#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #include #include #include diff --git a/keychain/ckks/CKKSKeychainView.h b/keychain/ckks/CKKSKeychainView.h index 0aa9d38a..e1f7bf6a 100644 --- a/keychain/ckks/CKKSKeychainView.h +++ b/keychain/ckks/CKKSKeychainView.h @@ -65,7 +65,7 @@ NS_ASSUME_NONNULL_BEGIN @class CKKSOutgoingQueueEntry; @class CKKSZoneChangeFetcher; -@interface CKKSKeychainView : CKKSZone +@interface CKKSKeychainView : CKKSZone { CKKSZoneKeyState* _keyHierarchyState; } @@ -108,7 +108,6 @@ NS_ASSUME_NONNULL_BEGIN @property CKKSNewTLKOperation* lastNewTLKOperation; @property CKKSOutgoingQueueOperation* lastOutgoingQueueOperation; @property CKKSProcessReceivedKeysOperation* lastProcessReceivedKeysOperation; -@property CKKSFetchAllRecordZoneChangesOperation* lastRecordZoneChangesOperation; @property CKKSReencryptOutgoingItemsOperation* lastReencryptOutgoingItemsOperation; @property CKKSScanLocalItemsOperation* lastScanLocalItemsOperation; @property CKKSSynchronizeOperation* lastSynchronizeOperation; @@ -139,6 +138,7 @@ NS_ASSUME_NONNULL_BEGIN accountTracker:(CKKSCKAccountStateTracker*)accountTracker lockStateTracker:(CKKSLockStateTracker*)lockStateTracker reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker + changeFetcher:(CKKSZoneChangeFetcher*)fetcher savedTLKNotifier:(CKKSNearFutureScheduler*)savedTLKNotifier peerProvider:(id)peerProvider fetchRecordZoneChangesOperationClass:(Class)fetchRecordZoneChangesOperationClass @@ -194,6 +194,9 @@ NS_ASSUME_NONNULL_BEGIN // Schedules a process queueoperation to happen after the next device unlock. This may be Immediately, if the device is unlocked. - (void)processIncomingQueueAfterNextUnlock; +// This operation will complete directly after the next ProcessIncomingQueue, and should supply that IQO's result. Used mainly for testing; otherwise you'd just kick off a IQO directly. +- (CKKSResultOperation*)resultsOfNextProcessIncomingQueueOperation; + // Schedules an operation to update this device's state record in CloudKit // If rateLimit is true, the operation will abort if it's updated the record in the past 3 days - (CKKSUpdateDeviceStateOperation*)updateDeviceState:(bool)rateLimit @@ -257,9 +260,6 @@ NS_ASSUME_NONNULL_BEGIN - (CKKSDeviceStateEntry* _Nullable)_onqueueCurrentDeviceStateEntry:(NSError* __autoreleasing*)error; -// Called by the CKKSZoneChangeFetcher -- (bool)isFatalCKFetchError:(NSError*)error; - // Please don't use these unless you're an Operation in this package @property NSHashTable* incomingQueueOperations; @property NSHashTable* outgoingQueueOperations; diff --git a/keychain/ckks/CKKSKeychainView.m b/keychain/ckks/CKKSKeychainView.m index 9989cbd8..d603cf4a 100644 --- a/keychain/ckks/CKKSKeychainView.m +++ b/keychain/ckks/CKKSKeychainView.m @@ -64,6 +64,7 @@ #import "keychain/ckks/CKKSTLKShare.h" #import "keychain/ckks/CKKSHealTLKSharesOperation.h" #import "keychain/ckks/CKKSLocalSynchronizeOperation.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #include #include @@ -83,6 +84,7 @@ @property bool keyStateFetchRequested; @property bool keyStateFullRefetchRequested; @property bool keyStateProcessRequested; +@property bool trustedPeersSetChanged; @property bool keyStateCloudKitDeleteRequested; @property NSHashTable* cloudkitDeleteZoneOperations; @@ -100,6 +102,7 @@ @property CKKSNearFutureScheduler* outgoingQueueOperationScheduler; @property CKKSResultOperation* processIncomingQueueAfterNextUnlockOperation; +@property CKKSResultOperation* resultsOfNextIncomingQueueOperationOperation; @property NSMutableDictionary* pendingSyncCallbacks; @@ -124,6 +127,7 @@ accountTracker:(CKKSCKAccountStateTracker*) accountTracker lockStateTracker:(CKKSLockStateTracker*) lockStateTracker reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker + changeFetcher:(CKKSZoneChangeFetcher*)fetcher savedTLKNotifier:(CKKSNearFutureScheduler*) savedTLKNotifier peerProvider:(id)peerProvider fetchRecordZoneChangesOperationClass: (Class) fetchRecordZoneChangesOperationClass @@ -155,7 +159,9 @@ _outgoingQueueOperations = [NSHashTable weakObjectsHashTable]; _cloudkitDeleteZoneOperations = [NSHashTable weakObjectsHashTable]; _localResetOperations = [NSHashTable weakObjectsHashTable]; - _zoneChangeFetcher = [[CKKSZoneChangeFetcher alloc] initWithCKKSKeychainView: self]; + + _zoneChangeFetcher = fetcher; + [fetcher registerClient:self]; _notifierClass = notifierClass; _notifyViewChangedScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat: @"%@-notify-scheduler", self.zoneName] @@ -565,15 +571,23 @@ // If we're currently signed in, the reset operation will be handled by the CKKS key state machine, and a reset should end up in 'ready' if(accountStatus == CKKSAccountStatusAvailable) { - __block CKKSResultOperation* resetOperation = nil; - [self dispatchSyncWithAccountKeys:^bool { - self.keyStateLocalResetRequested = true; - resetOperation = [self createPendingResetLocalDataOperation]; - [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; - return true; + __weak __typeof(self) weakSelf = self; + CKKSGroupOperation* resetOperationGroup = [CKKSGroupOperation named:@"local-reset" withBlockTakingSelf:^(CKKSGroupOperation *strongOp) { + __strong __typeof(self) strongSelf = weakSelf; + + __block CKKSResultOperation* resetOperation = nil; + + [strongSelf dispatchSyncWithAccountKeys:^bool { + strongSelf.keyStateLocalResetRequested = true; + resetOperation = [strongSelf createPendingResetLocalDataOperation]; + [strongSelf _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; + return true; + }]; + + [strongOp dependOnBeforeGroupFinished:resetOperation]; }]; + [self scheduleOperationWithoutDependencies:resetOperationGroup]; - __weak __typeof(self) weakSelf = self; CKKSGroupOperation* viewReset = [CKKSGroupOperation named:@"local-data-reset" withBlockTakingSelf:^(CKKSGroupOperation *strongOp) { __strong __typeof(weakSelf) strongSelf = weakSelf; // Now that the local reset finished, wait for the key hierarchy state machine to churn @@ -584,7 +598,7 @@ [strongOp runBeforeGroupFinished:waitOp]; }]; - [viewReset addSuccessDependency:resetOperation]; + [viewReset addSuccessDependency:resetOperationGroup]; [self scheduleOperationWithoutDependencies:viewReset]; return viewReset; @@ -923,9 +937,7 @@ if(self.keyStateProcessRequested || [remoteKeys count] > 0) { // We've either received some remote keys from the last fetch, or someone has requested a reprocess. ckksnotice("ckkskey", self, "Kicking off a key reprocess based on request:%d and remote key count %lu", self.keyStateProcessRequested, (unsigned long)[remoteKeys count]); - [self _onqueueKeyHierarchyProcess]; - // Stay in state 'ready': this reprocess might not change anything. If it does, cleanup code elsewhere will - // reencode items that arrive during this ready + nextState = SecCKKSZoneKeyStateProcess; } else if(self.keyStateFullRefetchRequested) { // In ready, but someone has requested a full fetch. Kick it off. @@ -1040,9 +1052,16 @@ // We're in a hold state: waiting for the TLK bytes to arrive. if(self.keyStateProcessRequested) { - // Someone has requsted a reprocess! Run a ProcessReceivedKeysOperation. - ckksnotice("ckkskey", self, "Received a nudge that our TLK might be here! Starting operation to check."); - [self _onqueueKeyHierarchyProcess]; + // Someone has requsted a reprocess! Go to the correct state. + ckksnotice("ckkskey", self, "Received a nudge that our TLK might be here! Reprocessing."); + nextState = SecCKKSZoneKeyStateProcess; + + } else if(self.trustedPeersSetChanged) { + // Hmm, maybe this trust set change will cause us to recover this TLK (due to a previously-untrusted share becoming trusted). Worth a shot! + ckksnotice("ckkskey", self, "Received a nudge that the trusted peers set might have changed! Reprocessing."); + nextState = SecCKKSZoneKeyStateProcess; + self.trustedPeersSetChanged = false; + } else { // Should we nuke this zone? if([self _onqueueOtherDevicesReportHavingTLKs:keyset]) { @@ -1085,6 +1104,13 @@ self.keyStateMachineOperation = [[CKKSHealTLKSharesOperation alloc] initWithCKKSKeychainView:self ckoperationGroup:self.keyHierarchyOperationGroup]; + } else if([state isEqualToString:SecCKKSZoneKeyStateProcess]) { + ckksnotice("ckksshare", self, "Launching key state process"); + self.keyStateMachineOperation = [[CKKSProcessReceivedKeysOperation alloc] initWithCKKSKeychainView: self]; + + // Since we're starting a reprocess, this is answering all previous requests. + self.keyStateProcessRequested = false; + } else { ckkserror("ckks", self, "asked to advance state machine to unknown state: %@", state); self.keyHierarchyState = state; @@ -1435,7 +1461,7 @@ // Check keyset if(!set.tlk || !set.classA || !set.classC) { - ckkserror("ckkskey", self, "Error examining existing key hierarchy: %@", set); + ckkserror("ckkskey", self, "Error examining existing key hierarchy (missing at least one key): %@", set); if(error) { *error = set.error; } @@ -1586,7 +1612,7 @@ }]; self.keyStateMachineOperation.name = @"waiting-for-refetch"; - NSOperation* fetchOp = [self.zoneChangeFetcher requestSuccessfulResyncFetch: CKKSFetchBecauseKeyHierarchy]; + NSOperation* fetchOp = [self.zoneChangeFetcher requestSuccessfulFetchForManyReasons:[NSSet setWithObjects:CKKSFetchBecauseKeyHierarchy, CKKSFetchBecauseResync, nil]]; [self.keyStateMachineOperation addDependency: fetchOp]; self.keyStateMachineRefetched = true; @@ -1594,16 +1620,6 @@ self.keyStateFetchRequested = false; } - -- (void)_onqueueKeyHierarchyProcess { - dispatch_assert_queue(self.queue); - - self.keyStateMachineOperation = [[CKKSProcessReceivedKeysOperation alloc] initWithCKKSKeychainView: self]; - - // Since we're starting a reprocess, this is answering all previous requests. - self.keyStateProcessRequested = false; -} - - (void) handleKeychainEventDbConnection: (SecDbConnectionRef) dbconn added: (SecDbItemRef) added deleted: (SecDbItemRef) deleted @@ -2034,6 +2050,16 @@ } } +- (CKKSResultOperation*)resultsOfNextProcessIncomingQueueOperation { + if(self.resultsOfNextIncomingQueueOperationOperation && [self.resultsOfNextIncomingQueueOperationOperation isPending]) { + return self.resultsOfNextIncomingQueueOperationOperation; + } + + // Else, make a new one. + self.resultsOfNextIncomingQueueOperationOperation = [CKKSResultOperation named:[NSString stringWithFormat:@"wait-for-next-incoming-queue-operation-%@", self.zoneName] withBlock:^{}]; + return self.resultsOfNextIncomingQueueOperationOperation; +} + - (CKKSIncomingQueueOperation*)processIncomingQueue:(bool)failOnClassA { return [self processIncomingQueue:failOnClassA after: nil]; } @@ -2045,6 +2071,7 @@ if(after) { [incomingop addNullableDependency: after]; } + // check (again) for race condition; if the op has started we need to add another (for the dependency) if([incomingop isPending]) { incomingop.errorOnClassAFailure |= failOnClassA; @@ -2052,12 +2079,17 @@ } } - CKKSIncomingQueueOperation* op = [[CKKSIncomingQueueOperation alloc] initWithCKKSKeychainView:self errorOnClassAFailure:failOnClassA]; + CKKSIncomingQueueOperation* op = [[CKKSIncomingQueueOperation alloc] initWithCKKSKeychainView:self errorOnClassAFailure:failOnClassA]; op.name = @"incoming-queue-operation"; if(after != nil) { [op addSuccessDependency: after]; } + if(self.resultsOfNextIncomingQueueOperationOperation) { + [self.resultsOfNextIncomingQueueOperationOperation addSuccessDependency:op]; + [self scheduleOperation:self.resultsOfNextIncomingQueueOperationOperation]; + } + [self scheduleOperation: op]; return op; } @@ -2200,7 +2232,7 @@ osVersion:SecCKKSHostOSVersion() lastUnlockTime:lastUnlockDay circlePeerID:accountTracker.accountCirclePeerID - circleStatus:accountTracker.currentCircleStatus + circleStatus:accountTracker.currentCircleStatus.status keyState:self.keyHierarchyState currentTLKUUID:suggestedTLK.uuid currentClassAUUID:suggestedClassAKey.uuid @@ -2240,6 +2272,16 @@ return [self processIncomingQueue:false after:[self.zoneChangeFetcher requestSuccessfulFetch:because]]; } +- (CKKSResultOperation*)fetchAndProcessCKChangesDueToAPNS:(CKRecordZoneNotification*)notification { + if(!SecCKKSIsEnabled()) { + ckksinfo("ckks", self, "Skipping fetchAndProcessCKChanges due to disabled CKKS"); + return nil; + } + + // We fetched some changes; try to process them! + return [self processIncomingQueue:false after:[self.zoneChangeFetcher requestSuccessfulFetchDueToAPNS:notification]]; +} + // Lets the view know about a failed CloudKit write. If the error is "already have one of these records", it will // store the new records and kick off the new processing // @@ -2394,35 +2436,37 @@ - (bool)_onqueueCKRecordChanged:(CKRecord*)record resync:(bool)resync { dispatch_assert_queue(self.queue); - ckksinfo("ckksfetch", self, "Processing record modification(%@): %@", record.recordType, record); + @autoreleasepool { + ckksnotice("ckksfetch", self, "Processing record modification(%@): %@", record.recordType, record); - if([[record recordType] isEqual: SecCKRecordItemType]) { - [self _onqueueCKRecordItemChanged:record resync:resync]; - return true; - } else if([[record recordType] isEqual: SecCKRecordCurrentItemType]) { - [self _onqueueCKRecordCurrentItemPointerChanged:record resync:resync]; - return true; - } else if([[record recordType] isEqual: SecCKRecordIntermediateKeyType]) { - [self _onqueueCKRecordKeyChanged:record resync:resync]; - return true; - } else if ([[record recordType] isEqual: SecCKRecordTLKShareType]) { - [self _onqueueCKRecordTLKShareChanged:record resync:resync]; - return true; - } else if([[record recordType] isEqualToString: SecCKRecordCurrentKeyType]) { - [self _onqueueCKRecordCurrentKeyPointerChanged:record resync:resync]; - return true; - } else if ([[record recordType] isEqualToString:SecCKRecordManifestType]) { - [self _onqueueCKRecordManifestChanged:record resync:resync]; - return true; - } else if ([[record recordType] isEqualToString:SecCKRecordManifestLeafType]) { - [self _onqueueCKRecordManifestLeafChanged:record resync:resync]; - return true; - } else if ([[record recordType] isEqualToString:SecCKRecordDeviceStateType]) { - [self _onqueueCKRecordDeviceStateChanged:record resync:resync]; - return true; - } else { - ckkserror("ckksfetch", self, "unknown record type: %@ %@", [record recordType], record); - return false; + if([[record recordType] isEqual: SecCKRecordItemType]) { + [self _onqueueCKRecordItemChanged:record resync:resync]; + return true; + } else if([[record recordType] isEqual: SecCKRecordCurrentItemType]) { + [self _onqueueCKRecordCurrentItemPointerChanged:record resync:resync]; + return true; + } else if([[record recordType] isEqual: SecCKRecordIntermediateKeyType]) { + [self _onqueueCKRecordKeyChanged:record resync:resync]; + return true; + } else if ([[record recordType] isEqual: SecCKRecordTLKShareType]) { + [self _onqueueCKRecordTLKShareChanged:record resync:resync]; + return true; + } else if([[record recordType] isEqualToString: SecCKRecordCurrentKeyType]) { + [self _onqueueCKRecordCurrentKeyPointerChanged:record resync:resync]; + return true; + } else if ([[record recordType] isEqualToString:SecCKRecordManifestType]) { + [self _onqueueCKRecordManifestChanged:record resync:resync]; + return true; + } else if ([[record recordType] isEqualToString:SecCKRecordManifestLeafType]) { + [self _onqueueCKRecordManifestLeafChanged:record resync:resync]; + return true; + } else if ([[record recordType] isEqualToString:SecCKRecordDeviceStateType]) { + [self _onqueueCKRecordDeviceStateChanged:record resync:resync]; + return true; + } else { + ckkserror("ckksfetch", self, "unknown record type: %@ %@", [record recordType], record); + return false; + } } } @@ -3039,7 +3083,7 @@ - (void)notifyZoneChange: (CKRecordZoneNotification*) notification { ckksnotice("ckks", self, "received a zone change notification for %@ %@", self, notification); - [self fetchAndProcessCKChanges:CKKSFetchBecauseAPNS]; + [self fetchAndProcessCKChangesDueToAPNS:notification]; } - (void)superHandleCKLogin { @@ -3124,26 +3168,135 @@ }); } -#pragma mark - CKKSChangeFetcherErrorOracle +#pragma mark - CKKSChangeFetcherClient -- (bool) isFatalCKFetchError: (NSError*) error { +- (CKKSCloudKitFetchRequest*)participateInFetch +{ + __block CKKSCloudKitFetchRequest* request = [[CKKSCloudKitFetchRequest alloc] init]; + [self dispatchSync: ^bool { + if(self.accountStatus != CKKSAccountStatusAvailable) { + ckksnotice("ckksfetch", self, "Not participating in fetch: not logged in"); + request.participateInFetch = false; + return false; + } + + if(!self.zoneCreated) { + ckksnotice("ckksfetch", self, "Not participating in fetch: zone not created yet"); + request.participateInFetch = false; + return false; + } + + request.participateInFetch = true; + + if([self.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateNeedFullRefetch]) { + // We want to return a nil change tag (to force a resync) + ckksnotice("ckksfetch", self, "Beginning refetch"); + request.changeToken = nil; + } else { + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:self.zoneName]; + if(!ckse) { + ckkserror("ckksfetch", self, "couldn't fetch zone change token for %@", self.zoneName); + return false; + } + request.changeToken = ckse.changeToken; + } + return true; + }]; + + return request; +} + +- (void)changesFetched:(NSArray*)changedRecords + deletedRecordIDs:(NSArray*)deletedRecords + oldChangeToken:(CKServerChangeToken*)oldChangeToken + newChangeToken:(CKServerChangeToken*)newChangeToken +{ + [self dispatchSyncWithAccountKeys:^bool{ + // This is a resync if we already have a change token, but this fetch didn't have one + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: self.zoneName]; + bool resync = ckse.changeToken && (oldChangeToken == nil); + + for (CKRecord* record in changedRecords) { + [self _onqueueCKRecordChanged:record resync:resync]; + } + + for (CKKSCloudKitDeletion* deletion in deletedRecords) { + [self _onqueueCKRecordDeleted:deletion.recordID recordType:deletion.recordType resync:resync]; + } + + NSError* error = nil; + if(resync) { + // Scan through all CKMirrorEntries and determine if any exist that CloudKit didn't tell us about + ckksnotice("ckksresync", self, "Comparing local UUIDs against the CloudKit list"); + NSMutableArray* uuids = [[CKKSMirrorEntry allUUIDs:self.zoneID error:&error] mutableCopy]; + + for(NSString* uuid in uuids) { + CKRecord* record = nil; + CKRecordID* recordID = [[CKRecordID alloc] initWithRecordName:uuid zoneID:self.zoneID]; + for(CKRecord* r in changedRecords) { + if([r.recordID isEqual:recordID]) { + record = r; + break; + } + } + + if(record) { + ckksnotice("ckksresync", self, "UUID %@ is still in CloudKit; carry on.", uuid); + } else { + CKKSMirrorEntry* ckme = [CKKSMirrorEntry tryFromDatabase:uuid zoneID:self.zoneID error:&error]; + if(error != nil) { + ckkserror("ckksresync", self, "Couldn't read an item from the database, but it used to be there: %@ %@", uuid, error); + continue; + } + if(!ckme) { + ckkserror("ckksresync", self, "Couldn't read ckme(%@) from database; continuing", uuid); + continue; + } + + ckkserror("ckksresync", self, "BUG: Local item %@ not found in CloudKit, deleting", uuid); + [self _onqueueCKRecordDeleted:ckme.item.storedCKRecord.recordID recordType:ckme.item.storedCKRecord.recordType resync:resync]; + } + } + } + + error = nil; + + CKKSZoneStateEntry* state = [CKKSZoneStateEntry state:self.zoneName]; + state.lastFetchTime = [NSDate date]; // The last fetch happened right now! + state.changeToken = newChangeToken; + [state saveToDatabase:&error]; + if(error) { + ckkserror("ckksfetch", self, "Couldn't save new server change token: %@", error); + } + + // Might as well kick off a IQO! + [self processIncomingQueue:false]; + + ckksnotice("ckksfetch", self, "Finished processing changes for %@", self.zoneID); + + return true; + }]; +} + +// Return false if this is a 'fatal' error and we don't want another fetch to be tried +- (bool)notifyFetchError: (NSError*) error { __weak __typeof(self) weakSelf = self; - // Again, note that this handles exactly one zone. Mutli-zone errors are not supported. bool isChangeTokenExpiredError = false; if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorChangeTokenExpired)) { isChangeTokenExpiredError = true; } else if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorPartialFailure)) { NSDictionary* partialErrors = error.userInfo[CKPartialErrorsByItemIDKey]; - for(NSError* partialError in partialErrors.allValues) { - if([partialError.domain isEqualToString:CKErrorDomain] && (partialError.code == CKErrorChangeTokenExpired)) { + for(CKRecordZoneID* zoneID in partialErrors) { + NSError* partialError = partialErrors[zoneID]; + if([zoneID isEqual:self.zoneID] && [partialError.domain isEqualToString:CKErrorDomain] && (partialError.code == CKErrorChangeTokenExpired)) { isChangeTokenExpiredError = true; } } } if(isChangeTokenExpiredError) { - ckkserror("ckks", self, "Received notice that our change token is out of date. Resetting local data..."); + ckkserror("ckks", self, "Received notice that our change token is out of date (for %@). Resetting local data...", self.zoneID); CKKSResultOperation* resetOp = [self resetLocalData]; CKKSResultOperation* resetHandler = [CKKSResultOperation named:@"local-reset-handler" withBlock:^{ __strong __typeof(self) strongSelf = weakSelf; @@ -3161,7 +3314,7 @@ [resetHandler addDependency:resetOp]; [self scheduleOperation:resetHandler]; - return true; + return false; } bool isDeletedZoneError = false; @@ -3169,15 +3322,16 @@ isDeletedZoneError = true; } else if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorPartialFailure)) { NSDictionary* partialErrors = error.userInfo[CKPartialErrorsByItemIDKey]; - for(NSError* partialError in partialErrors.allValues) { - if([partialError.domain isEqualToString:CKErrorDomain] && ((partialError.code == CKErrorUserDeletedZone) || (partialError.code == CKErrorZoneNotFound))) { + for(CKRecordZoneID* zoneID in partialErrors) { + NSError* partialError = partialErrors[zoneID]; + if([self.zoneID isEqual:zoneID] && [partialError.domain isEqualToString:CKErrorDomain] && ((partialError.code == CKErrorUserDeletedZone) || (partialError.code == CKErrorZoneNotFound))) { isDeletedZoneError = true; } } } if(isDeletedZoneError) { - ckkserror("ckks", self, "Received notice that our zone does not exist. Resetting local data."); + ckkserror("ckks", self, "Received notice that our zone(%@) does not exist. Resetting local data.", self.zoneID); CKKSResultOperation* resetOp = [self resetLocalData]; CKKSResultOperation* resetHandler = [CKKSResultOperation named:@"reset-handler" withBlock:^{ __strong __typeof(self) strongSelf = weakSelf; @@ -3195,15 +3349,15 @@ [resetHandler addDependency:resetOp]; [self scheduleOperation:resetHandler]; - return true; + return false; } if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorBadContainer)) { ckkserror("ckks", self, "Received notice that our container does not exist. Nothing to do."); - return true; + return false; } - return false; + return true; } #pragma mark CKKSPeerUpdateListener @@ -3218,7 +3372,9 @@ // We might need to share the TLK to some new people, or we might now trust the TLKs we have. // The key state machine should handle that, so poke it. ckkserror("ckks", self, "Received update that the trust set has changed"); - [self keyStateMachineRequestProcess]; + + self.trustedPeersSetChanged = true; + [self.pokeKeyStateMachineScheduler trigger]; } #pragma mark - Test Support @@ -3359,7 +3515,6 @@ @"lastIncomingQueueOperation": stringify(self.lastIncomingQueueOperation), @"lastNewTLKOperation": stringify(self.lastNewTLKOperation), @"lastOutgoingQueueOperation": stringify(self.lastOutgoingQueueOperation), - @"lastRecordZoneChangesOperation": stringify(self.lastRecordZoneChangesOperation), @"lastProcessReceivedKeysOperation": stringify(self.lastProcessReceivedKeysOperation), @"lastReencryptOutgoingItemsOperation":stringify(self.lastReencryptOutgoingItemsOperation), @"lastScanLocalItemsOperation": stringify(self.lastScanLocalItemsOperation), diff --git a/keychain/ckks/CKKSLocalSynchronizeOperation.m b/keychain/ckks/CKKSLocalSynchronizeOperation.m index 88cc6a98..ef73c11f 100644 --- a/keychain/ckks/CKKSLocalSynchronizeOperation.m +++ b/keychain/ckks/CKKSLocalSynchronizeOperation.m @@ -29,6 +29,7 @@ #import "keychain/ckks/CKKSMirrorEntry.h" #import "keychain/ckks/CKKSIncomingQueueEntry.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #if OCTAGON diff --git a/keychain/ckks/CKKSManifest.m b/keychain/ckks/CKKSManifest.m index 7b2c78f5..3e8bd659 100644 --- a/keychain/ckks/CKKSManifest.m +++ b/keychain/ckks/CKKSManifest.m @@ -699,7 +699,7 @@ static NSUInteger LeafBucketIndexForUUID(NSString* uuid) return sqlValues; } -- (NSDictionary*)whereClauseToFindSelf +- (NSDictionary*)whereClauseToFindSelf { return @{ @"ckzone" : CKKSNilToNSNull(_zoneName), @"gencount" : [NSNumber numberWithUnsignedInteger:_generationCount], diff --git a/keychain/ckks/CKKSMirrorEntry.m b/keychain/ckks/CKKSMirrorEntry.m index 3609839e..6a4e4ec7 100644 --- a/keychain/ckks/CKKSMirrorEntry.m +++ b/keychain/ckks/CKKSMirrorEntry.m @@ -119,7 +119,7 @@ return [self.item whereClauseToFindSelf]; } -- (NSDictionary*)sqlValues { +- (NSDictionary*)sqlValues { NSMutableDictionary* values = [[self.item sqlValues] mutableCopy]; values[@"wascurrent"] = [NSNumber numberWithUnsignedLongLong:self.wasCurrent]; return values; diff --git a/keychain/ckks/CKKSNearFutureScheduler.h b/keychain/ckks/CKKSNearFutureScheduler.h index 1bc7294a..166830bf 100644 --- a/keychain/ckks/CKKSNearFutureScheduler.h +++ b/keychain/ckks/CKKSNearFutureScheduler.h @@ -69,6 +69,8 @@ NS_ASSUME_NONNULL_BEGIN // Don't trigger again until at least this much time has passed. - (void)waitUntil:(uint64_t)delay; +- (void)changeDelays:(dispatch_time_t)initialDelay continuingDelay:(dispatch_time_t)continuingDelay; + @end NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/CKKSNearFutureScheduler.m b/keychain/ckks/CKKSNearFutureScheduler.m index 583a900e..d562e058 100644 --- a/keychain/ckks/CKKSNearFutureScheduler.m +++ b/keychain/ckks/CKKSNearFutureScheduler.m @@ -93,6 +93,14 @@ return self; } +- (void)changeDelays:(dispatch_time_t)initialDelay continuingDelay:(dispatch_time_t)continuingDelay +{ + dispatch_sync(self.queue, ^{ + self.initialDelay = initialDelay; + self.continuingDelay = continuingDelay; + }); +} + - (CKKSResultOperation*)makeOperationDependency { CKKSResultOperation* op = [CKKSResultOperation named:[NSString stringWithFormat:@"nfs-%@", self.name] withBlock:^{}]; op.descriptionErrorCode = self.operationDependencyDescriptionCode; diff --git a/keychain/ckks/CKKSNewTLKOperation.m b/keychain/ckks/CKKSNewTLKOperation.m index 8af09132..4d35f5a1 100644 --- a/keychain/ckks/CKKSNewTLKOperation.m +++ b/keychain/ckks/CKKSNewTLKOperation.m @@ -28,6 +28,7 @@ #import "CKKSGroupOperation.h" #import "CKKSNearFutureScheduler.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #if OCTAGON @@ -253,7 +254,11 @@ modifyRecordsOp = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave recordIDsToDelete:recordIDsToDelete]; modifyRecordsOp.atomic = YES; modifyRecordsOp.longLived = NO; // The keys are only in memory; mark this explicitly not long-lived - modifyRecordsOp.qualityOfService = NSQualityOfServiceUserInitiated; // This needs to happen before CKKS is available for PCS/CloudKit use. + + // This needs to happen before CKKS is available for PCS/CloudKit use. + modifyRecordsOp.configuration.automaticallyRetryNetworkFailures = NO; + modifyRecordsOp.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + modifyRecordsOp.group = self.ckoperationGroup; ckksnotice("ckkstlk", ckks, "Operation group is %@", self.ckoperationGroup); diff --git a/keychain/ckks/CKKSOutgoingQueueEntry.m b/keychain/ckks/CKKSOutgoingQueueEntry.m index cff41eed..0868af4f 100644 --- a/keychain/ckks/CKKSOutgoingQueueEntry.m +++ b/keychain/ckks/CKKSOutgoingQueueEntry.m @@ -40,6 +40,7 @@ #import "CKKSItemEncrypter.h" #import "CKKSKey.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" @implementation CKKSOutgoingQueueEntry diff --git a/keychain/ckks/CKKSOutgoingQueueOperation.m b/keychain/ckks/CKKSOutgoingQueueOperation.m index d8869334..7da9132a 100644 --- a/keychain/ckks/CKKSOutgoingQueueOperation.m +++ b/keychain/ckks/CKKSOutgoingQueueOperation.m @@ -21,6 +21,11 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + +#import +#import + #import "CKKSKeychainView.h" #import "CKKSCurrentKeyPointer.h" #import "CKKSOutgoingQueueOperation.h" @@ -37,8 +42,6 @@ #include #import "CKKSPowerCollection.h" -#if OCTAGON - @interface CKKSOutgoingQueueOperation() @property CKModifyRecordsOperation* modifyRecordsOperation; @end @@ -76,7 +79,7 @@ return; } - [ckks dispatchSyncWithAccountKeys: ^bool{ + [ckks dispatchSync: ^bool{ ckks.lastOutgoingQueueOperation = self; if(self.cancelled) { ckksnotice("ckksoutgoing", ckks, "CKKSOutgoingQueueOperation cancelled, quitting"); @@ -237,15 +240,6 @@ return true; } - bool uploadingPCSEntries = false; - for(CKKSOutgoingQueueEntry* oqe in oqesModified) { - // PCS always sets these fields, and nothing else does - if(oqe.item.plaintextPCSPublicKey || oqe.item.plaintextPCSPublicIdentity || oqe.item.plaintextPCSServiceIdentifier) { - uploadingPCSEntries = true; - break; - } - } - self.itemsProcessed = recordsToSave.count; NSBlockOperation* modifyComplete = [[NSBlockOperation alloc] init]; @@ -443,10 +437,16 @@ return true; }]; - [strongSelf.operationQueue addOperation: modifyComplete]; // Kick off another queue process. We expect it to exit instantly, but who knows! - [strongCKKS processOutgoingQueue:strongSelf.ckoperationGroup]; + // If we think the network is iffy, though, wait for it to come back + CKKSResultOperation* possibleNetworkDependency = nil; + CKKSReachabilityTracker* reachabilityTracker = strongCKKS.reachabilityTracker; + if(ckerror && [reachabilityTracker isNetworkError:ckerror]) { + possibleNetworkDependency = reachabilityTracker.reachabilityDependency; + } + + [strongCKKS processOutgoingQueueAfter:possibleNetworkDependency ckoperationGroup:strongSelf.ckoperationGroup]; }; ckksinfo("ckksoutgoing", ckks, "Current keys to update: %@", currentKeysToSave); @@ -474,7 +474,11 @@ self.modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave.allValues recordIDsToDelete:recordIDsToDelete]; self.modifyRecordsOperation.atomic = TRUE; - self.modifyRecordsOperation.qualityOfService = uploadingPCSEntries ? NSQualityOfServiceUserInitiated : NSQualityOfServiceUtility; // PCS items are needed for CloudKit to work, so they might be user-initiated + + // Until Changes to discretionary-ness (explicit or derived from QoS) should be "live", all requests should be nondiscretionary + self.modifyRecordsOperation.configuration.automaticallyRetryNetworkFailures = NO; + self.modifyRecordsOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged; self.modifyRecordsOperation.group = self.ckoperationGroup; ckksnotice("ckksoutgoing", ckks, "QoS: %d; operation group is %@", (int)self.modifyRecordsOperation.qualityOfService, self.modifyRecordsOperation.group); diff --git a/keychain/ckks/CKKSProcessReceivedKeysOperation.m b/keychain/ckks/CKKSProcessReceivedKeysOperation.m index 01b78bce..c2debc1b 100644 --- a/keychain/ckks/CKKSProcessReceivedKeysOperation.m +++ b/keychain/ckks/CKKSProcessReceivedKeysOperation.m @@ -28,6 +28,7 @@ #import "CKKSKey.h" #import "CKKSProcessReceivedKeysOperation.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #if OCTAGON diff --git a/keychain/ckks/CKKSRateLimiter.m b/keychain/ckks/CKKSRateLimiter.m index fc16cef7..93ad4a4c 100644 --- a/keychain/ckks/CKKSRateLimiter.m +++ b/keychain/ckks/CKKSRateLimiter.m @@ -26,14 +26,6 @@ #import #import -#if !TARGET_OS_BRIDGE -#import -#import "keychain/analytics/awd/AWDMetricIds_Keychain.h" -#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.h" -#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h" -#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h" -#endif - typedef NS_ENUM(int, BucketType) { All, Group, @@ -44,11 +36,6 @@ typedef NS_ENUM(int, BucketType) { @property (readwrite) NSDictionary *config; @property NSMutableDictionary *buckets; @property NSDate *overloadUntil; -#if !TARGET_OS_BRIDGE -@property NSMutableArray *badnessData; -@property AWDServerConnection *awdConnection; -#define CKKSRateLimiterName @"ckks-original" -#endif @end @implementation CKKSRateLimiter @@ -81,11 +68,6 @@ typedef NS_ENUM(int, BucketType) { @250 , @"trimSize", @3600, @"trimTime", @1800, @"overloadDuration", nil]; -#if !TARGET_OS_BRIDGE - _badnessData = [[NSMutableArray alloc] initWithObjects:@0, @0, @0, @0, @0, @0, nil]; - _awdConnection = [[AWDServerConnection alloc] initWithComponentId:AWDComponentId_Keychain]; - [self setUpAwdMetrics]; -#endif } return self; } @@ -182,10 +164,6 @@ typedef NS_ENUM(int, BucketType) { badness = 4; } -#if !TARGET_OS_BRIDGE - self.badnessData[badness] = @([self.badnessData[badness] intValue] + 1); -#endif - *limitTime = sendTime; return badness; } @@ -208,12 +186,6 @@ typedef NS_ENUM(int, BucketType) { // Nothing to remove means everybody keeps being noisy. Tell them to go away. if ([toRemove count] == 0) { self.overloadUntil = [self.buckets[@"All"] dateByAddingTimeInterval:[self.config[@"overloadDuration"] intValue]]; -#if !TARGET_OS_BRIDGE - AWDKeychainCKKSRateLimiterOverload *metric = [AWDKeychainCKKSRateLimiterOverload new]; - metric.durationMsec = [self.overloadUntil timeIntervalSinceDate:time]; - metric.ratelimitertype = CKKSRateLimiterName; - AWDPostMetric(AWDComponentId_Keychain, metric); -#endif seccritical("RateLimiter overloaded until %@", self.overloadUntil); } else { self.overloadUntil = nil; @@ -270,32 +242,6 @@ typedef NS_ENUM(int, BucketType) { } } -#if !TARGET_OS_BRIDGE -- (void)setUpAwdMetrics { - [self.awdConnection registerQueriableMetric:AWDMetricId_Keychain_CKKSRateLimiterTopWriters callback:^(UInt32 metricId) { - AWDKeychainCKKSRateLimiterTopWriters *metric = [AWDKeychainCKKSRateLimiterTopWriters new]; - NSArray *offenders = [self topOffendingAccessGroups:3]; - if (offenders) { - for (NSString *offender in offenders) { - [metric addWriter:offender]; - } - } - metric.ratelimitertype = CKKSRateLimiterName; - AWDPostMetric(metricId, metric); - }]; - - [self.awdConnection registerQueriableMetric:AWDMetricId_Keychain_CKKSRateLimiterAggregatedScores callback:^(UInt32 metricId) { - AWDKeychainCKKSRateLimiterAggregatedScores *metric = [AWDKeychainCKKSRateLimiterAggregatedScores new]; - for (NSNumber *num in self.badnessData) { - [metric addData:[num unsignedIntValue]]; - } - metric.ratelimitertype = CKKSRateLimiterName; - AWDPostMetric(metricId, metric); - self.badnessData = [[NSMutableArray alloc] initWithObjects:@0, @0, @0, @0, @0, @0, nil]; - }]; -} -#endif - + (BOOL)supportsSecureCoding { return YES; } diff --git a/keychain/ckks/CKKSReachabilityTracker.h b/keychain/ckks/CKKSReachabilityTracker.h index b2c1c370..3b23dd2e 100644 --- a/keychain/ckks/CKKSReachabilityTracker.h +++ b/keychain/ckks/CKKSReachabilityTracker.h @@ -26,8 +26,10 @@ #import #import +@class CKKSResultOperation; + @interface CKKSReachabilityTracker : NSObject -@property NSOperation* reachablityDependency; +@property CKKSResultOperation* reachabilityDependency; @property (readonly) bool currentReachability; // get current reachability value w/o recheck - (instancetype)init; diff --git a/keychain/ckks/CKKSReachabilityTracker.m b/keychain/ckks/CKKSReachabilityTracker.m index 3086e568..0317a754 100644 --- a/keychain/ckks/CKKSReachabilityTracker.m +++ b/keychain/ckks/CKKSReachabilityTracker.m @@ -33,6 +33,7 @@ #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ckks/CKKSResultOperation.h" #import "keychain/ckks/CKKSReachabilityTracker.h" #import "keychain/ckks/CKKSAnalytics.h" @@ -99,13 +100,13 @@ callout(SCNetworkReachabilityRef reachability, return currentReachability; } --(void)_onQueueRunReachablityDependency +-(void)_onQueueRunreachabilityDependency { dispatch_assert_queue(self.queue); // We're have network now, or timer expired, either way, execute dependency - if (self.reachablityDependency) { - [self.operationQueue addOperation: self.reachablityDependency]; - self.reachablityDependency = nil; + if (self.reachabilityDependency) { + [self.operationQueue addOperation: self.reachabilityDependency]; + self.reachabilityDependency = nil; } if (self.timer) { dispatch_source_cancel(self.timer); @@ -116,22 +117,22 @@ callout(SCNetworkReachabilityRef reachability, -(void)_onQueueResetReachabilityDependency { dispatch_assert_queue(self.queue); - if(self.reachablityDependency == nil || ![self.reachablityDependency isPending]) { + if(self.reachabilityDependency == nil || ![self.reachabilityDependency isPending]) { __weak __typeof(self) weakSelf = self; - self.reachablityDependency = [NSBlockOperation blockOperationWithBlock: ^{ + secnotice("ckksnetwork", "Network unavailable"); + self.reachabilityDependency = [CKKSResultOperation named:@"network-available-dependency" withBlock: ^{ __typeof(self) strongSelf = weakSelf; if (strongSelf == nil) { return; } if (strongSelf.haveNetwork) { - secinfo("ckks", "Network available"); + secnotice("ckksnetwork", "Network available"); } else { - secinfo("ckks", "Network still not available, retrying after waiting %2.1f hours", + secnotice("ckksnetwork", "Network still not available, retrying after waiting %2.1f hours", ((float)(REACHABILITY_TIMEOUT/NSEC_PER_SEC)) / 3600); } }]; - self.reachablityDependency.name = @"network-available-dependency"; /* * Make sure we are not stuck forever and retry every REACHABILITY_TIMEOUT @@ -147,7 +148,7 @@ callout(SCNetworkReachabilityRef reachability, } if (strongSelf.timer) { [[CKKSAnalytics logger] noteEvent:CKKSEventReachabilityTimerExpired]; - [strongSelf _onQueueRunReachablityDependency]; + [strongSelf _onQueueRunreachabilityDependency]; } }); @@ -176,7 +177,7 @@ callout(SCNetworkReachabilityRef reachability, if(hadNetwork != self.haveNetwork) { if(self.haveNetwork) { // We're have network now - [self _onQueueRunReachablityDependency]; + [self _onQueueRunreachabilityDependency]; } else { [self _onQueueResetReachabilityDependency]; } diff --git a/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m b/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m index 397516af..410cfbf2 100644 --- a/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m +++ b/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m @@ -29,6 +29,7 @@ #import "keychain/ckks/CKKSReencryptOutgoingItemsOperation.h" #import "keychain/ckks/CKKSItemEncrypter.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #if OCTAGON diff --git a/keychain/ckks/CKKSResultOperation.m b/keychain/ckks/CKKSResultOperation.m index 94612530..559adb40 100644 --- a/keychain/ckks/CKKSResultOperation.m +++ b/keychain/ckks/CKKSResultOperation.m @@ -26,7 +26,7 @@ #import "keychain/ckks/CKKSResultOperation.h" #import "keychain/ckks/NSOperationCategories.h" #import "keychain/ckks/CKKSCondition.h" -#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #include @interface CKKSResultOperation() diff --git a/keychain/ckks/CKKSSIV.m b/keychain/ckks/CKKSSIV.m index 90ec111c..cba130bb 100644 --- a/keychain/ckks/CKKSSIV.m +++ b/keychain/ckks/CKKSSIV.m @@ -36,7 +36,7 @@ #include #include -#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" @implementation CKKSBaseAESSIVKey - (instancetype)init { @@ -109,7 +109,7 @@ if(len != CKKSWrappedKeySize) { @throw [NSException exceptionWithName:@"WrongKeySizeException" - reason:[NSString stringWithFormat: @"length (%lu) was not %d", len, CKKSWrappedKeySize] + reason:[NSString stringWithFormat: @"length (%lu) was not %d", (unsigned long)len, CKKSWrappedKeySize] userInfo:nil]; } if(self = [super initWithBytes: bytes len: len]) { @@ -121,7 +121,7 @@ if(self->size != CKKSWrappedKeySize) { @throw [NSException exceptionWithName:@"WrongKeySizeException" - reason:[NSString stringWithFormat: @"length (%lu) was not %d", self->size, CKKSWrappedKeySize] + reason:[NSString stringWithFormat: @"length (%lu) was not %d", (unsigned long)self->size, CKKSWrappedKeySize] userInfo:nil]; } } @@ -158,7 +158,7 @@ if(len != CKKSKeySize) { @throw [NSException exceptionWithName:@"WrongKeySizeException" - reason:[NSString stringWithFormat: @"length (%lu) was not %d", len, CKKSKeySize] + reason:[NSString stringWithFormat: @"length (%lu) was not %d", (unsigned long)len, CKKSKeySize] userInfo:nil]; } if(self = [super initWithBytes: bytes len: len]) { @@ -170,7 +170,7 @@ if(self->size != CKKSKeySize) { @throw [NSException exceptionWithName:@"WrongKeySizeException" - reason:[NSString stringWithFormat: @"length (%lu) was not %d", self->size, CKKSKeySize] + reason:[NSString stringWithFormat: @"length (%lu) was not %d", (unsigned long)self->size, CKKSKeySize] userInfo:nil]; } } diff --git a/keychain/ckks/CKKSScanLocalItemsOperation.m b/keychain/ckks/CKKSScanLocalItemsOperation.m index a60a5ff0..132c7dd5 100644 --- a/keychain/ckks/CKKSScanLocalItemsOperation.m +++ b/keychain/ckks/CKKSScanLocalItemsOperation.m @@ -254,7 +254,7 @@ // We're done checking local keychain for extra items, now let's make sure the mirror doesn't have extra items, either if (mirrorUUIDs.count > 0) { - ckksnotice("ckksscan", ckks, "keychain missing %lu items from mirror, proceeding with queue scanning", mirrorUUIDs.count); + ckksnotice("ckksscan", ckks, "keychain missing %lu items from mirror, proceeding with queue scanning", (unsigned long)mirrorUUIDs.count); [mirrorUUIDs minusSet:[NSSet setWithArray:[CKKSIncomingQueueEntry allUUIDs:ckks.zoneID error:&error]]]; if (error) { ckkserror("ckksscan", ckks, "unable to inspect incoming queue: %@", error); @@ -270,7 +270,7 @@ } if (mirrorUUIDs.count > 0) { - ckkserror("ckksscan", ckks, "BUG: keychain missing %lu items from mirror and/or queues: %@", mirrorUUIDs.count, mirrorUUIDs); + ckkserror("ckksscan", ckks, "BUG: keychain missing %lu items from mirror and/or queues: %@", (unsigned long)mirrorUUIDs.count, mirrorUUIDs); self.missingLocalItemsFound = mirrorUUIDs.count; [[CKKSAnalytics logger] logMetric:[NSNumber numberWithUnsignedInteger:mirrorUUIDs.count] withName:CKKSEventMissingLocalItemsFound]; diff --git a/keychain/ckks/CKKSSynchronizeOperation.m b/keychain/ckks/CKKSSynchronizeOperation.m index 16434514..85c6b41d 100644 --- a/keychain/ckks/CKKSSynchronizeOperation.m +++ b/keychain/ckks/CKKSSynchronizeOperation.m @@ -27,6 +27,7 @@ #import "CKKSFetchAllRecordZoneChangesOperation.h" #import "CKKSScanLocalItemsOperation.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #if OCTAGON @@ -94,9 +95,13 @@ [self dependOnBeforeGroupFinished:outgoingOp]; // Step 2 - CKKSFetchAllRecordZoneChangesOperation* fetchOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks - fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync] - ckoperationGroup:operationGroup]; + CKKSFetchAllRecordZoneChangesOperation* fetchOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithContainer:ckks.container + fetchClass:ckks.fetchRecordZoneChangesOperationClass + clients:@[ckks] + fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync] + apnsPushes:nil + forceResync:true + ckoperationGroup:operationGroup]; fetchOp.name = [NSString stringWithFormat: @"resync-step%u-fetch", self.restartCount * steps + 2]; [fetchOp addSuccessDependency: outgoingOp]; [self runBeforeGroupFinished: fetchOp]; @@ -110,9 +115,13 @@ // Now, get serious: // Step 4 - CKKSFetchAllRecordZoneChangesOperation* fetchAllOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks - fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync] - ckoperationGroup:operationGroup]; + CKKSFetchAllRecordZoneChangesOperation* fetchAllOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithContainer:ckks.container + fetchClass:ckks.fetchRecordZoneChangesOperationClass + clients:@[ckks] + fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync] + apnsPushes:nil + forceResync:true + ckoperationGroup:operationGroup]; fetchAllOp.resync = true; fetchAllOp.name = [NSString stringWithFormat: @"resync-step%u-fetchAll", self.restartCount * steps + 4]; [fetchAllOp addSuccessDependency: incomingOp]; diff --git a/keychain/ckks/CKKSTLKShare.m b/keychain/ckks/CKKSTLKShare.m index 20f7b6ff..53877108 100644 --- a/keychain/ckks/CKKSTLKShare.m +++ b/keychain/ckks/CKKSTLKShare.m @@ -28,6 +28,7 @@ #import "keychain/ckks/CKKSTLKShare.h" #import "keychain/ckks/CKKSPeer.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #import #import diff --git a/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m b/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m index 95efedba..ec3fc8b6 100644 --- a/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m +++ b/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m @@ -30,6 +30,7 @@ #import "keychain/ckks/CKKSUpdateCurrentItemPointerOperation.h" #import "keychain/ckks/CKKSManifest.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #include #include @@ -274,7 +275,10 @@ self.modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave.allValues recordIDsToDelete:nil]; self.modifyRecordsOperation.atomic = TRUE; - self.modifyRecordsOperation.qualityOfService = NSQualityOfServiceUserInitiated; // We're likely rolling a PCS identity, or creating a new one. User cares. + // We're likely rolling a PCS identity, or creating a new one. User cares. + self.modifyRecordsOperation.configuration.automaticallyRetryNetworkFailures = NO; + self.modifyRecordsOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged; self.modifyRecordsOperation.group = self.ckoperationGroup; diff --git a/keychain/ckks/CKKSViewManager.h b/keychain/ckks/CKKSViewManager.h index 317930a6..7a63416e 100644 --- a/keychain/ckks/CKKSViewManager.h +++ b/keychain/ckks/CKKSViewManager.h @@ -38,6 +38,7 @@ #import "keychain/ckks/CKKSPeer.h" #import "keychain/ckks/CKKSRateLimiter.h" #import "keychain/ckks/CloudKitDependencies.h" +#import "keychain/ckks/CKKSZoneChangeFetcher.h" #import "keychain/ot/OTDefines.h" NS_ASSUME_NONNULL_BEGIN @@ -50,6 +51,7 @@ NS_ASSUME_NONNULL_BEGIN @property CKKSCKAccountStateTracker* accountTracker; @property CKKSLockStateTracker* lockStateTracker; @property CKKSReachabilityTracker *reachabilityTracker; +@property CKKSZoneChangeFetcher* zoneChangeFetcher; @property bool initializeNewZones; // Signaled when SecCKKSInitialize is complete, as it's async and likes to fire after tests are complete diff --git a/keychain/ckks/CKKSViewManager.m b/keychain/ckks/CKKSViewManager.m index 44cadf3f..f3dea667 100644 --- a/keychain/ckks/CKKSViewManager.m +++ b/keychain/ckks/CKKSViewManager.m @@ -30,6 +30,7 @@ #import "keychain/ckks/CKKSNotifier.h" #import "keychain/ckks/CKKSCondition.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #import "keychain/ot/OTDefines.h" @@ -128,6 +129,10 @@ [_lockStateTracker addLockStateObserver:self]; _reachabilityTracker = [[CKKSReachabilityTracker alloc] init]; + _zoneChangeFetcher = [[CKKSZoneChangeFetcher alloc] initWithContainer:_container + fetchClass:fetchRecordZoneChangesOperationClass + reachabilityTracker:_reachabilityTracker]; + _operationQueue = [[NSOperationQueue alloc] init]; // Backwards from how we'd like, but it's the best way to have weak pointers to CKKSPeerUpdateListener. @@ -234,8 +239,9 @@ [values setValue:@(fuzzyDaysSinceKSR) forKey:[NSString stringWithFormat:@"%@-daysSinceLastKeystateReady", viewName]]; BOOL hasTLKs = [view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateReady] || [view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock]; - BOOL syncedClassARecently = fuzzyDaysSinceClassASync < 7; - BOOL syncedClassCRecently = fuzzyDaysSinceClassCSync < 7; + /* only synced recently if between [0...7, ie withing 7 days */ + BOOL syncedClassARecently = fuzzyDaysSinceClassASync >= 0 && fuzzyDaysSinceClassASync < 7; + BOOL syncedClassCRecently = fuzzyDaysSinceClassCSync >= 0 && fuzzyDaysSinceClassCSync < 7; BOOL incomingQueueIsErrorFree = view.lastIncomingQueueOperation.error == nil; BOOL outgoingQueueIsErrorFree = view.lastOutgoingQueueOperation.error == nil; @@ -370,6 +376,7 @@ dispatch_once_t globalZoneStateQueueOnce; accountTracker: self.accountTracker lockStateTracker: self.lockStateTracker reachabilityTracker: self.reachabilityTracker + changeFetcher:self.zoneChangeFetcher savedTLKNotifier: self.savedTLKNotifier peerProvider:self fetchRecordZoneChangesOperationClass: self.fetchRecordZoneChangesOperationClass @@ -480,10 +487,12 @@ dispatch_once_t globalZoneStateQueueOnce; CKKSKeychainView* view = [self findView: keyViewName]; if(!SecCKKSTestDisableKeyNotifications()) { - ckksnotice("ckks", view, "Potential new key material from %@ (source %lu)", keyViewName, txionSource); + ckksnotice("ckks", view, "Potential new key material from %@ (source %lu)", + keyViewName, (unsigned long)txionSource); [view keyStateMachineRequestProcess]; } else { - ckksnotice("ckks", view, "Ignoring potential new key material from %@ (source %lu)", keyViewName, txionSource); + ckksnotice("ckks", view, "Ignoring potential new key material from %@ (source %lu)", + keyViewName, (unsigned long)txionSource); } return; } @@ -667,6 +676,7 @@ dispatch_once_t globalZoneStateQueueOnce; secnotice("ckks", "Received a %@ request for all zones: %@", opName, actualViews); } } + actualViews = [actualViews sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"zoneName" ascending:YES]]]; return actualViews; } @@ -697,7 +707,14 @@ dispatch_once_t globalZoneStateQueueOnce; [self.operationQueue addOperation: op]; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" - (void)rpcResetCloudKit:(NSString*)viewName reply: (void(^)(NSError* result)) reply { + [self rpcResetCloudKit:viewName reason:@"unknown" reply:reply]; +} +#pragma clang diagnostic pop + +- (void)rpcResetCloudKit:(NSString*)viewName reason:(NSString *)reason reply:(void(^)(NSError* result)) reply { NSError* localError = nil; NSArray* actualViews = [self views:viewName operation:@"CloudKit reset" error:&localError]; if(localError) { @@ -716,8 +733,9 @@ dispatch_once_t globalZoneStateQueueOnce; }]; for(CKKSKeychainView* view in actualViews) { - ckksnotice("ckksreset", view, "Beginning CloudKit reset for %@", view); - [op addSuccessDependency:[view resetCloudKitZone:[CKOperationGroup CKKSGroupWithName:@"api-reset"]]]; + NSString *operationGroupName = [NSString stringWithFormat:@"api-reset-%@", reason]; + ckksnotice("ckksreset", view, "Beginning CloudKit reset for %@: %@", view, reason); + [op addSuccessDependency:[view resetCloudKitZone:[CKOperationGroup CKKSGroupWithName:operationGroupName]]]; } [op timeout:120*NSEC_PER_SEC]; diff --git a/keychain/ckks/CKKSZone.m b/keychain/ckks/CKKSZone.m index 40c32544..7d47c88d 100644 --- a/keychain/ckks/CKKSZone.m +++ b/keychain/ckks/CKKSZone.m @@ -29,6 +29,7 @@ #import "CloudKitDependencies.h" #import "keychain/ckks/CKKSCKAccountStateTracker.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #import #import @@ -182,11 +183,6 @@ self.zoneCreated = zoneCreated; self.zoneSubscribed = zoneSubscribed; - // Zone setups and teardowns are due to either 1) first CKKS launch or 2) the user logging in to iCloud. - // Therefore, they're QoS UserInitiated. - self.zoneSetupOperation.queuePriority = NSOperationQueuePriorityNormal; - self.zoneSetupOperation.qualityOfService = NSQualityOfServiceUserInitiated; - ckksnotice("ckkszone", self, "Setting up zone %@", self.zoneName); __weak __typeof(self) weakSelf = self; @@ -240,8 +236,8 @@ if(!zoneCreated) { ckksnotice("ckkszone", strongSelf, "Creating CloudKit zone '%@'", strongSelf.zoneName); CKDatabaseOperation* zoneCreationOperation = [[strongSelf.modifyRecordZonesOperationClass alloc] initWithRecordZonesToSave: @[strongSelf.zone] recordZoneIDsToDelete: nil]; - zoneCreationOperation.queuePriority = NSOperationQueuePriorityNormal; - zoneCreationOperation.qualityOfService = NSQualityOfServiceUserInitiated; + zoneCreationOperation.configuration.automaticallyRetryNetworkFailures = NO; + zoneCreationOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; zoneCreationOperation.database = strongSelf.database; zoneCreationOperation.name = @"zone-creation-operation"; zoneCreationOperation.group = strongSelf.zoneSetupOperationGroup ?: [CKOperationGroup CKKSGroupWithName:@"zone-creation"];; @@ -274,7 +270,7 @@ }; if (strongSelf.zoneCreateNetworkFailure) { - [zoneCreationOperation addNullableDependency:reachabilityTracker.reachablityDependency]; + [zoneCreationOperation addNullableDependency:reachabilityTracker.reachabilityDependency]; strongSelf.zoneCreateNetworkFailure = false; } ckksnotice("ckkszone", strongSelf, "Adding CKKSModifyRecordZonesOperation: %@ %@", zoneCreationOperation, zoneCreationOperation.dependencies); @@ -296,8 +292,8 @@ CKDatabaseOperation* zoneSubscriptionOperation = [[strongSelf.modifySubscriptionsOperationClass alloc] initWithSubscriptionsToSave: @[subscription] subscriptionIDsToDelete: nil]; - zoneSubscriptionOperation.queuePriority = NSOperationQueuePriorityNormal; - zoneSubscriptionOperation.qualityOfService = NSQualityOfServiceUserInitiated; + zoneSubscriptionOperation.configuration.automaticallyRetryNetworkFailures = NO; + zoneSubscriptionOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; zoneSubscriptionOperation.database = strongSelf.database; zoneSubscriptionOperation.name = @"zone-subscription-operation"; @@ -333,7 +329,7 @@ }; if (strongSelf.zoneSubscriptionNetworkFailure) { - [zoneSubscriptionOperation addNullableDependency:reachabilityTracker.reachablityDependency]; + [zoneSubscriptionOperation addNullableDependency:reachabilityTracker.reachabilityDependency]; strongSelf.zoneSubscriptionNetworkFailure = false; } [zoneSubscriptionOperation addNullableDependency:modifyRecordZonesCompleteOperation]; @@ -370,8 +366,8 @@ // Step 2: Try to delete the zone CKDatabaseOperation* zoneDeletionOperation = [[self.modifyRecordZonesOperationClass alloc] initWithRecordZonesToSave: nil recordZoneIDsToDelete: @[self.zoneID]]; - zoneDeletionOperation.queuePriority = NSOperationQueuePriorityNormal; - zoneDeletionOperation.qualityOfService = NSQualityOfServiceUserInitiated; + zoneDeletionOperation.configuration.automaticallyRetryNetworkFailures = NO; + zoneDeletionOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; zoneDeletionOperation.database = self.database; zoneDeletionOperation.group = ckoperationGroup; diff --git a/keychain/ckks/CKKSZoneChangeFetcher.h b/keychain/ckks/CKKSZoneChangeFetcher.h index 52f083be..80cdc654 100644 --- a/keychain/ckks/CKKSZoneChangeFetcher.h +++ b/keychain/ckks/CKKSZoneChangeFetcher.h @@ -25,27 +25,10 @@ #import #import #import "keychain/ckks/CKKSResultOperation.h" +#import "keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h" NS_ASSUME_NONNULL_BEGIN -/* Fetch Reasons */ -@protocol SecCKKSFetchBecause -@end -typedef NSString CKKSFetchBecause; -extern CKKSFetchBecause* const CKKSFetchBecauseAPNS; -extern CKKSFetchBecause* const CKKSFetchBecauseAPIFetchRequest; -extern CKKSFetchBecause* const CKKSFetchBecauseCurrentItemFetchRequest; -extern CKKSFetchBecause* const CKKSFetchBecauseInitialStart; -extern CKKSFetchBecause* const CKKSFetchBecauseSecuritydRestart; -extern CKKSFetchBecause* const CKKSFetchBecausePreviousFetchFailed; -extern CKKSFetchBecause* const CKKSFetchBecauseKeyHierarchy; -extern CKKSFetchBecause* const CKKSFetchBecauseTesting; -extern CKKSFetchBecause* const CKKSFetchBecauseResync; - -@protocol CKKSChangeFetcherErrorOracle -- (bool)isFatalCKFetchError:(NSError*)error; -@end - /* * This class implements a CloudKit-fetch-with-retry. * In the case of network or other failures, it'll issue retries. @@ -53,23 +36,34 @@ extern CKKSFetchBecause* const CKKSFetchBecauseResync; */ @class CKKSKeychainView; +@class CKKSReachabilityTracker; +@class CKKSNearFutureScheduler; @interface CKKSZoneChangeFetcher : NSObject +@property (readonly) Class fetchRecordZoneChangesOperationClass; +@property (readonly) CKContainer* container; +@property CKKSReachabilityTracker* reachabilityTracker; -@property (nullable, weak) CKKSKeychainView* ckks; @property (readonly) NSError* lastCKFetchError; -@property CKRecordZoneID* zoneID; - (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks; +- (instancetype)initWithContainer:(CKContainer*)container + fetchClass:(Class)fetchRecordsOperationClass + reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker; + +- (void)registerClient:(id)client; - (CKKSResultOperation*)requestSuccessfulFetch:(CKKSFetchBecause*)why; -- (CKKSResultOperation*)requestSuccessfulResyncFetch:(CKKSFetchBecause*)why; +- (CKKSResultOperation*)requestSuccessfulFetchForManyReasons:(NSSet*)why; +- (CKKSResultOperation*)requestSuccessfulFetchDueToAPNS:(CKRecordZoneNotification*)notification; // We don't particularly care what this does, as long as it finishes - (void)holdFetchesUntil:(CKKSResultOperation* _Nullable)holdOperation; - (void)cancel; + +// I don't recommend using these unless you're a test. +@property CKKSNearFutureScheduler* fetchScheduler; @end NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/CKKSZoneChangeFetcher.m b/keychain/ckks/CKKSZoneChangeFetcher.m index bf1737bf..95edf9d0 100644 --- a/keychain/ckks/CKKSZoneChangeFetcher.m +++ b/keychain/ckks/CKKSZoneChangeFetcher.m @@ -32,6 +32,8 @@ #import "keychain/ckks/CKKSKeychainView.h" #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" +#import "keychain/categories/NSError+UsefulConstructors.h" CKKSFetchBecause* const CKKSFetchBecauseAPNS = (CKKSFetchBecause*) @"apns"; CKKSFetchBecause* const CKKSFetchBecauseAPIFetchRequest = (CKKSFetchBecause*) @"api"; @@ -47,49 +49,79 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; #pragma mark - CKKSZoneChangeFetchDependencyOperation @interface CKKSZoneChangeFetchDependencyOperation : CKKSResultOperation @property CKKSZoneChangeFetcher* owner; +@property NSMutableArray* chainDependents; +- (void)chainDependency:(CKKSZoneChangeFetchDependencyOperation*)newDependency; @end @implementation CKKSZoneChangeFetchDependencyOperation +- (instancetype)init { + if((self = [super init])) { + _chainDependents = [NSMutableArray array]; + } + return self; +} + - (NSError* _Nullable)descriptionError { return [NSError errorWithDomain:CKKSResultDescriptionErrorDomain code:CKKSResultDescriptionPendingSuccessfulFetch description:@"Fetch failed" underlying:self.owner.lastCKFetchError]; } + +- (void)chainDependency:(CKKSZoneChangeFetchDependencyOperation*)newDependency { + [self addSuccessDependency:newDependency]; + + // There's no need to build a chain more than two links long. Move all our children up to depend on the new dependency. + for(CKKSZoneChangeFetchDependencyOperation* op in self.chainDependents) { + [newDependency.chainDependents addObject:op]; + [op addSuccessDependency:newDependency]; + [op removeDependency:self]; + } + [self.chainDependents removeAllObjects]; +} @end #pragma mark - CKKSZoneChangeFetcher @interface CKKSZoneChangeFetcher () @property NSString* name; +@property NSOperationQueue* operationQueue; @property dispatch_queue_t queue; @property NSError* lastCKFetchError; +@property NSMapTable>* clientMap; + @property CKKSFetchAllRecordZoneChangesOperation* currentFetch; @property CKKSResultOperation* currentProcessResult; @property NSMutableSet* currentFetchReasons; +@property NSMutableSet* apnsPushes; @property bool newRequests; // true if there's someone pending on successfulFetchDependency -@property bool newResyncRequests; // true if someone asked for a refetch operation -@property CKKSResultOperation* successfulFetchDependency; - -@property CKKSNearFutureScheduler* fetchScheduler; +@property CKKSZoneChangeFetchDependencyOperation* successfulFetchDependency; @property CKKSResultOperation* holdOperation; @end @implementation CKKSZoneChangeFetcher -- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks { +- (instancetype)initWithContainer:(CKContainer*)container + fetchClass:(Class)fetchRecordZoneChangesOperationClass + reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker +{ if((self = [super init])) { - _ckks = ckks; - _zoneID = ckks.zoneID; + _container = container; + _fetchRecordZoneChangesOperationClass = fetchRecordZoneChangesOperationClass; + _reachabilityTracker = reachabilityTracker; _currentFetchReasons = [[NSMutableSet alloc] init]; + _apnsPushes = [[NSMutableSet alloc] init]; + + _clientMap = [NSMapTable strongToWeakObjectsMapTable]; - _name = [NSString stringWithFormat:@"zone-change-fetcher-%@", _zoneID.zoneName]; + _name = @"zone-change-fetcher"; _queue = dispatch_queue_create([_name UTF8String], DISPATCH_QUEUE_SERIAL); + _operationQueue = [[NSOperationQueue alloc] init]; _successfulFetchDependency = [self createSuccesfulFetchDependency]; _newRequests = false; @@ -101,7 +133,7 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; dispatch_time_t continuingDelay = (SecCKKSReduceRateLimiting() ? 2 * NSEC_PER_SEC : 30 * NSEC_PER_SEC); __weak __typeof(self) weakSelf = self; - _fetchScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat:@"zone-change-fetch-scheduler-%@", self.zoneID.zoneName] + _fetchScheduler = [[CKKSNearFutureScheduler alloc] initWithName:@"zone-change-fetch-scheduler" initialDelay:initialDelay continuingDelay:continuingDelay keepProcessAlive:false @@ -124,21 +156,52 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; } } +- (void)registerClient:(id)client +{ + @synchronized(self.clientMap) { + [self.clientMap setObject:client forKey:client.zoneID]; + } +} + + - (CKKSResultOperation*)requestSuccessfulFetch:(CKKSFetchBecause*)why { - return [self requestSuccessfulFetch:why resync:false]; + return [self requestSuccessfulFetchForManyReasons:[NSSet setWithObject:why]]; +} + +- (CKKSResultOperation*)requestSuccessfulFetchForManyReasons:(NSSet*)why +{ + return [self requestSuccessfulFetchForManyReasons:why apns:nil]; } -- (CKKSResultOperation*)requestSuccessfulResyncFetch:(CKKSFetchBecause*)why { - return [self requestSuccessfulFetch:why resync:true]; +- (CKKSResultOperation*)requestSuccessfulFetchDueToAPNS:(CKRecordZoneNotification*)notification +{ + return [self requestSuccessfulFetchForManyReasons:[NSSet setWithObject:CKKSFetchBecauseAPNS] apns:notification]; } -- (CKKSResultOperation*)requestSuccessfulFetch:(CKKSFetchBecause*)why resync:(bool)resync { +- (CKKSResultOperation*)requestSuccessfulFetchForManyReasons:(NSSet*)why apns:(CKRecordZoneNotification*)notification +{ __block CKKSResultOperation* dependency = nil; dispatch_sync(self.queue, ^{ dependency = self.successfulFetchDependency; self.newRequests = true; - self.newResyncRequests |= resync; - [self.currentFetchReasons addObject: why]; + [self.currentFetchReasons unionSet:why]; + if(notification) { + [self.apnsPushes addObject:notification]; + + if(notification.ckksPushTracingEnabled) { + // Report that we saw this notification before doing anything else + secnotice("ckksfetch", "Submitting initial CKEventMetric due to notification %@", notification); + + CKEventMetric *metric = [[CKEventMetric alloc] initWithEventName:@"APNSPushMetrics"]; + metric.isPushTriggerFired = true; + metric[@"push_token_uuid"] = notification.ckksPushTracingUUID; + metric[@"push_received_date"] = notification.ckksPushReceivedDate; + metric[@"push_event_name"] = @"CKKS APNS Push Received"; + + [self.container submitEventMetric:metric]; + } + + } [self.fetchScheduler trigger]; }); @@ -161,36 +224,43 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; __weak __typeof(self) weakSelf = self; - CKKSResultOperation* dependency = self.successfulFetchDependency; - - CKKSKeychainView* ckks = self.ckks; // take a strong reference - if(!ckks) { - secerror("ckksfetcher: received a null CKKSKeychainView pointer; strange."); - return; - } + CKKSZoneChangeFetchDependencyOperation* dependency = self.successfulFetchDependency; - ckksnotice("ckksfetcher", self.zoneID, "Starting a new fetch for %@", self.zoneID.zoneName); + secnotice("ckksfetcher", "Starting a new fetch"); NSMutableSet* lastFetchReasons = self.currentFetchReasons; self.currentFetchReasons = [[NSMutableSet alloc] init]; - if(self.newResyncRequests) { - [lastFetchReasons addObject:CKKSFetchBecauseResync]; - } + + NSMutableSet* lastAPNSPushes = self.apnsPushes; + self.apnsPushes = [[NSMutableSet alloc] init]; CKOperationGroup* operationGroup = [CKOperationGroup CKKSGroupWithName: [[lastFetchReasons sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES]]] componentsJoinedByString:@","]]; - CKKSFetchAllRecordZoneChangesOperation* fetchAllChanges = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks - fetchReasons:lastFetchReasons - ckoperationGroup:operationGroup]; + NSMutableArray>* clients = [NSMutableArray array]; + @synchronized(self.clientMap) { + for(id client in [self.clientMap objectEnumerator]) { + if(client != nil) { + [clients addObject:client]; + } + } + } + + if(clients.count == 0u) { + // Nothing to do, really. + } + + CKKSFetchAllRecordZoneChangesOperation* fetchAllChanges = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithContainer:self.container + fetchClass:self.fetchRecordZoneChangesOperationClass + clients:clients + fetchReasons:lastFetchReasons + apnsPushes:lastAPNSPushes + forceResync:false + ckoperationGroup:operationGroup]; + if ([lastFetchReasons containsObject:CKKSFetchBecauseNetwork]) { - [fetchAllChanges addNullableDependency: ckks.reachabilityTracker.reachablityDependency]; // wait on network, if its unavailable + [fetchAllChanges addNullableDependency: self.reachabilityTracker.reachabilityDependency]; // wait on network, if its unavailable } [fetchAllChanges addNullableDependency: self.holdOperation]; - fetchAllChanges.resync = self.newResyncRequests; - self.newResyncRequests = false; - - // Can't fetch until the zone is setup. - [fetchAllChanges addNullableDependency:ckks.zoneSetupOperation]; self.currentProcessResult = [CKKSResultOperation operationWithBlock: ^{ __strong __typeof(self) strongSelf = weakSelf; @@ -199,18 +269,12 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; return; } - CKKSKeychainView* blockckks = strongSelf.ckks; // take a strong reference - if(!blockckks) { - secerror("ckksfetcher: Received a null CKKSKeychainView pointer; strange."); - return; - } - dispatch_sync(strongSelf.queue, ^{ self.lastCKFetchError = fetchAllChanges.error; if(!fetchAllChanges.error) { // success! notify the listeners. - [blockckks scheduleOperation: dependency]; + [self.operationQueue addOperation: dependency]; // Did new people show up and want another fetch? if(strongSelf.newRequests) { @@ -218,34 +282,45 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; } } else { // The operation errored. Chain the dependency on the current one... - [dependency addSuccessDependency: strongSelf.successfulFetchDependency]; - [blockckks scheduleOperation: dependency]; + [dependency chainDependency:strongSelf.successfulFetchDependency]; + [strongSelf.operationQueue addOperation: dependency]; + + // Check in with clients: should we keep fetching for them? + bool attemptAnotherFetch = false; + @synchronized(self.clientMap) { + for(CKRecordZoneID* zoneID in fetchAllChanges.fetchedZoneIDs) { + id client = [self.clientMap objectForKey:zoneID]; + if(client) { + attemptAnotherFetch |= [client notifyFetchError:fetchAllChanges.error]; + } + } + } - if([blockckks isFatalCKFetchError: fetchAllChanges.error]) { - ckkserror("ckksfetcher", strongSelf.zoneID, "Notified that %@ is a fatal error. Not restarting fetch.", fetchAllChanges.error); + if(!attemptAnotherFetch) { + secerror("ckksfetcher: All clients thought %@ is a fatal error. Not restarting fetch.", fetchAllChanges.error); return; } - // And in a bit, try the fetch again. NSNumber* delaySeconds = fetchAllChanges.error.userInfo[CKErrorRetryAfterKey]; if([fetchAllChanges.error.domain isEqual: CKErrorDomain] && delaySeconds) { - ckksnotice("ckksfetcher", strongSelf.zoneID, "Fetch failed with rate-limiting error, restarting in %@ seconds: %@", delaySeconds, fetchAllChanges.error); + secnotice("ckksfetcher", "Fetch failed with rate-limiting error, restarting in %@ seconds: %@", delaySeconds, fetchAllChanges.error); [strongSelf.fetchScheduler waitUntil: NSEC_PER_SEC * [delaySeconds unsignedLongValue]]; } else { - ckksnotice("ckksfetcher", strongSelf.zoneID, "Fetch failed with error, restarting soon: %@", fetchAllChanges.error); + secnotice("ckksfetcher", "Fetch failed with error, restarting soon: %@", fetchAllChanges.error); } // Add the failed fetch reasons to the new fetch reasons [strongSelf.currentFetchReasons unionSet:lastFetchReasons]; + [strongSelf.apnsPushes unionSet:lastAPNSPushes]; + // If its a network error, make next try depend on network availability - if ([blockckks.reachabilityTracker isNetworkError:fetchAllChanges.error]) { + if ([self.reachabilityTracker isNetworkError:fetchAllChanges.error]) { [strongSelf.currentFetchReasons addObject:CKKSFetchBecauseNetwork]; } else { [strongSelf.currentFetchReasons addObject:CKKSFetchBecausePreviousFetchFailed]; } strongSelf.newRequests = true; - strongSelf.newResyncRequests |= fetchAllChanges.resync; [strongSelf.fetchScheduler trigger]; } }); @@ -253,10 +328,10 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; self.currentProcessResult.name = @"zone-change-fetcher-worker"; [self.currentProcessResult addDependency: fetchAllChanges]; - [ckks scheduleOperation: self.currentProcessResult]; + [self.operationQueue addOperation:self.currentProcessResult]; self.currentFetch = fetchAllChanges; - [ckks scheduleOperation: self.currentFetch]; + [self.operationQueue addOperation:self.currentFetch]; // creata a new fetch dependency, for all those who come in while this operation is executing self.newRequests = false; @@ -265,18 +340,7 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; -(CKKSZoneChangeFetchDependencyOperation*)createSuccesfulFetchDependency { CKKSZoneChangeFetchDependencyOperation* dep = [[CKKSZoneChangeFetchDependencyOperation alloc] init]; - __weak __typeof(dep) weakDep = dep; - - // Since these dependencies might chain, when one runs, break the chain. - [dep addExecutionBlock:^{ - __strong __typeof(dep) strongDep = weakDep; - // Remove all dependencies - NSArray* deps = [strongDep.dependencies copy]; - for(NSOperation* op in deps) { - [strongDep removeDependency: op]; - } - }]; dep.name = @"successful-fetch-dependency"; dep.descriptionErrorCode = CKKSResultDescriptionPendingSuccessfulFetch; dep.owner = self; diff --git a/keychain/ckks/CKKSZoneStateEntry.m b/keychain/ckks/CKKSZoneStateEntry.m index 060a9960..14e0fc00 100644 --- a/keychain/ckks/CKKSZoneStateEntry.m +++ b/keychain/ckks/CKKSZoneStateEntry.m @@ -154,7 +154,7 @@ return @{@"ckzone": self.ckzone}; } -- (NSDictionary*) sqlValues { +- (NSDictionary*) sqlValues { NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; return @{@"ckzone": self.ckzone, diff --git a/keychain/ckks/CloudKitCategories.h b/keychain/ckks/CloudKitCategories.h index 9ba1d850..01132680 100644 --- a/keychain/ckks/CloudKitCategories.h +++ b/keychain/ckks/CloudKitCategories.h @@ -34,21 +34,11 @@ NS_ASSUME_NONNULL_BEGIN @end @interface NSError (CKKS) - -// More useful constructor -+ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description; - -+ (instancetype)errorWithDomain:(NSErrorDomain)domain - code:(NSInteger)code - description:(NSString*)description - underlying:(NSError* _Nullable)underlying; - // Returns true if this is a CloudKit error where // 1) An atomic write failed // 2) Every single suberror is either CKErrorServerRecordChanged or CKErrorUnknownItem - (bool)ckksIsCKErrorRecordChangedError; @end - // Ensure we don't print addresses @interface CKAccountInfo (CKKS) - (NSString*)description; diff --git a/keychain/ckks/CloudKitCategories.m b/keychain/ckks/CloudKitCategories.m index c4185f4a..5f82c453 100644 --- a/keychain/ckks/CloudKitCategories.m +++ b/keychain/ckks/CloudKitCategories.m @@ -37,20 +37,6 @@ @implementation NSError (CKKS) -+ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description { - return [NSError errorWithDomain:domain code:code description:description underlying:nil]; -} - -+ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description underlying:(NSError*)underlying { - // Obj-C throws a fit if there's nulls in dictionaries, so we can't use a dictionary literal here. - // Use the null-assignment semantics of NSMutableDictionary to make a dictionary either with either, both, or neither key. - NSMutableDictionary* mut = [[NSMutableDictionary alloc] init]; - mut[NSLocalizedDescriptionKey] = description; - mut[NSUnderlyingErrorKey] = underlying; - - return [NSError errorWithDomain:domain code:code userInfo:mut]; -} - -(bool) ckksIsCKErrorRecordChangedError { NSDictionary* partialErrors = self.userInfo[CKPartialErrorsByItemIDKey]; if([self.domain isEqualToString:CKErrorDomain] && self.code == CKErrorPartialFailure && partialErrors) { diff --git a/keychain/ckks/CloudKitDependencies.h b/keychain/ckks/CloudKitDependencies.h index 75ea2414..6b37c555 100644 --- a/keychain/ckks/CloudKitDependencies.h +++ b/keychain/ckks/CloudKitDependencies.h @@ -42,6 +42,7 @@ NS_ASSUME_NONNULL_BEGIN @property NSOperationQueuePriority queuePriority; @property NSQualityOfService qualityOfService; @property (nonatomic, strong, nullable) CKOperationGroup* group; +@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration; @property (nonatomic, copy, nullable) void (^modifyRecordZonesCompletionBlock) (NSArray* _Nullable savedRecordZones, NSArray* _Nullable deletedRecordZoneIDs, NSError* _Nullable operationError); @@ -64,6 +65,7 @@ NS_ASSUME_NONNULL_BEGIN @property NSOperationQueuePriority queuePriority; @property NSQualityOfService qualityOfService; @property (nonatomic, strong, nullable) CKOperationGroup* group; +@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration; @property (nonatomic, copy, nullable) void (^modifySubscriptionsCompletionBlock) (NSArray* _Nullable savedSubscriptions, NSArray* _Nullable deletedSubscriptionIDs, NSError* _Nullable operationError); @@ -77,10 +79,11 @@ NS_ASSUME_NONNULL_BEGIN @protocol CKKSFetchRecordZoneChangesOperation + (instancetype)alloc; - (instancetype)initWithRecordZoneIDs:(NSArray*)recordZoneIDs - optionsByRecordZoneID:(nullable NSDictionary*)optionsByRecordZoneID; + configurationsByRecordZoneID:(nullable NSDictionary*)configurationsByRecordZoneID; +@property (nonatomic, strong, nullable) CKDatabase *database; @property (nonatomic, copy, nullable) NSArray* recordZoneIDs; -@property (nonatomic, copy, nullable) NSDictionary* optionsByRecordZoneID; +@property (nonatomic, copy, nullable) NSDictionary* configurationsByRecordZoneID; @property (nonatomic, assign) BOOL fetchAllChanges; @property (nonatomic, copy, nullable) void (^recordChangedBlock)(CKRecord* record); @@ -95,10 +98,13 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy, nullable) void (^fetchRecordZoneChangesCompletionBlock)(NSError* _Nullable operationError); @property (nonatomic, strong, nullable) CKOperationGroup* group; +@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration; + +@property (nonatomic, copy) NSString *operationID; +@property (nonatomic, readonly, strong, nullable) CKOperationConfiguration *resolvedConfiguration; @end @interface CKFetchRecordZoneChangesOperation () -; @end /* CKFetchRecordsOperation */ @@ -107,6 +113,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init; - (instancetype)initWithRecordIDs:(NSArray*)recordIDs; +@property (nonatomic, strong, nullable) CKDatabase *database; @property (nonatomic, copy, nullable) NSArray* recordIDs; @property (nonatomic, copy, nullable) NSArray* desiredKeys; @property (nonatomic, copy, nullable) CKOperationConfiguration* configuration; diff --git a/keychain/ckks/RateLimiter.h b/keychain/ckks/RateLimiter.h index da51fc15..9d8f1f5c 100644 --- a/keychain/ckks/RateLimiter.h +++ b/keychain/ckks/RateLimiter.h @@ -92,9 +92,6 @@ NS_ASSUME_NONNULL_END MAType - - topOffendersPropertyIndex - groups diff --git a/keychain/ckks/RateLimiter.m b/keychain/ckks/RateLimiter.m index fbbc5ec7..67a5ac81 100644 --- a/keychain/ckks/RateLimiter.m +++ b/keychain/ckks/RateLimiter.m @@ -26,24 +26,12 @@ #import "sec_action.h" #import // For clarity. Also included in debugging.h -#if !TARGET_OS_BRIDGE -#import -#import "keychain/analytics/awd/AWDMetricIds_Keychain.h" -#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.h" -#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h" -#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h" -#endif - @interface RateLimiter() @property (readwrite, nonatomic) NSDictionary *config; @property (nonatomic) NSArray *> *groups; @property (nonatomic) NSDate *lastJudgment; @property (nonatomic) NSDate *overloadUntil; @property (nonatomic) NSString *assetType; -#if !TARGET_OS_BRIDGE -@property (nonatomic) NSMutableArray *badnessData; -@property (nonatomic) AWDServerConnection *awdConnection; -#endif @end @implementation RateLimiter @@ -54,7 +42,6 @@ _config = config; _assetType = nil; [self reset]; - [self setUpAwdMetrics]; } return self; } @@ -69,7 +56,6 @@ } _assetType = nil; [self reset]; - [self setUpAwdMetrics]; } return self; } @@ -94,12 +80,6 @@ _overloadUntil = [coder decodeObjectOfClass:[NSDate class] forKey:@"RLoverLoadedUntil"]; _lastJudgment = [coder decodeObjectOfClass:[NSDate class] forKey:@"RLlastJudgment"]; _assetType = [coder decodeObjectOfClass:[NSString class] forKey:@"RLassetType"]; -#if !TARGET_OS_BRIDGE - _badnessData = [coder decodeObjectOfClasses:[NSSet setWithObjects: [NSArray class], - [NSNumber class], - nil] - forKey:@"RLbadnessData"]; -#endif if (!_assetType) { // This list of types might be wrong. Be careful. _config = [coder decodeObjectOfClasses:[NSSet setWithObjects: [NSMutableArray class], @@ -110,7 +90,6 @@ nil] forKey:@"RLconfig"]; } - [self setUpAwdMetrics]; } return self; } @@ -159,9 +138,6 @@ } if (badness != RateLimiterBadnessClear) { -#if !TARGET_OS_BRIDGE - self.badnessData[badness] = @(self.badnessData[badness].intValue + 1); -#endif return badness; } @@ -191,9 +167,6 @@ } } -#if !TARGET_OS_BRIDGE - self.badnessData[badness] = @(self.badnessData[badness].intValue + 1); -#endif *limitTime = badness == RateLimiterBadnessClear ? nil : resultTime; self.lastJudgment = time; return badness; @@ -237,10 +210,6 @@ self.groups = newgroups; self.lastJudgment = [NSDate distantPast]; // will cause extraneous trim on first judgment but on empty groups self.overloadUntil = nil; -#if !TARGET_OS_BRIDGE - // Corresponds to the number of RateLimiterBadness enum values - self.badnessData = [[NSMutableArray alloc] initWithObjects:@0, @0, @0, @0, @0, nil]; -#endif } - (void)trim:(NSDate *)time { @@ -260,11 +229,6 @@ (unsigned long)[self stateSize], [self.config[@"general"][@"maxStateSize"] unsignedLongValue], self.overloadUntil); -#if !TARGET_OS_BRIDGE - AWDKeychainCKKSRateLimiterOverload *metric = [AWDKeychainCKKSRateLimiterOverload new]; - metric.ratelimitertype = self.config[@"general"][@"name"]; - AWDPostMetric(AWDComponentId_Keychain, metric); -#endif } else { self.overloadUntil = nil; } @@ -310,9 +274,6 @@ if (!_assetType) { [coder encodeObject:_config forKey:@"RLconfig"]; } -#if !TARGET_OS_BRIDGE - [coder encodeObject:_badnessData forKey:@"RLbadnessData"]; -#endif } + (BOOL)supportsSecureCoding { @@ -334,31 +295,4 @@ return [[[contenders keysSortedByValueUsingSelector:@selector(compare:)] reverseObjectEnumerator] allObjects]; } -- (void)setUpAwdMetrics { -#if !TARGET_OS_BRIDGE - self.awdConnection = [[AWDServerConnection alloc] initWithComponentId:AWDComponentId_Keychain]; - - [self.awdConnection registerQueriableMetric:AWDMetricId_Keychain_CKKSRateLimiterTopWriters callback:^(UInt32 metricId) { - AWDKeychainCKKSRateLimiterTopWriters *metric = [AWDKeychainCKKSRateLimiterTopWriters new]; - NSArray *offenders = [self topOffenders:3]; - for (NSString *offender in offenders) { - [metric addWriter:offender]; - } - metric.ratelimitertype = self.config[@"general"][@"name"]; - AWDPostMetric(metricId, metric); - }]; - - [self.awdConnection registerQueriableMetric:AWDMetricId_Keychain_CKKSRateLimiterAggregatedScores callback:^(UInt32 metricId) { - AWDKeychainCKKSRateLimiterAggregatedScores *metric = [AWDKeychainCKKSRateLimiterAggregatedScores new]; - for (NSNumber *num in self.badnessData) { - [metric addData:[num unsignedIntValue]]; - } - metric.ratelimitertype = self.config[@"general"][@"name"]; - AWDPostMetric(metricId, metric); - // Corresponds to the number of RateLimiterBadness enum values - self.badnessData = [[NSMutableArray alloc] initWithObjects:@0, @0, @0, @0, @0, nil]; - }]; -#endif -} - @end diff --git a/keychain/ckks/tests/CKKSAPSHandlingTests.m b/keychain/ckks/tests/CKKSAPSHandlingTests.m new file mode 100644 index 00000000..9245595f --- /dev/null +++ b/keychain/ckks/tests/CKKSAPSHandlingTests.m @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2018 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@ + */ + +#if OCTAGON + +#import +#import +#import +#import +#import +#import + +#import "keychain/ckks/tests/CloudKitMockXCTest.h" +#import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSAPSReceiver.h" +#import "keychain/ckks/CKKSKey.h" +#import "keychain/ckks/CKKSPeer.h" +#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CloudKitCategories.h" + +#import "keychain/ckks/tests/MockCloudKit.h" +#import "keychain/ckks/tests/CKKSTests.h" +#import "keychain/ot/OTDefines.h" + +#import "keychain/ckks/tests/CKKSAPSReceiverTests.h" + +@interface CKKSAPSHandlingTests : CloudKitKeychainSyncingTestsBase +@property CKRecordZoneID* manateeZoneID; +@property CKKSKeychainView* manateeView; +@property FakeCKZone* manateeZone; +@property (readonly) ZoneKeys* manateeZoneKeys; +@end + + +@implementation CKKSAPSHandlingTests +// We really just want two views here +- (NSSet*)managedViewList { + return [NSSet setWithObjects:@"keychain", @"Manatee", nil]; +} + +- (void)setUp { + [super setUp]; + + // Wait for the ViewManager to be brought up + XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:20*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize"); + + self.manateeZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Manatee" ownerName:CKCurrentUserDefaultName]; + [self.ckksZones addObject:self.manateeZoneID]; + self.manateeZone = [[FakeCKZone alloc] initZone: self.manateeZoneID]; + self.zones[self.manateeZoneID] = self.manateeZone; + self.manateeView = [[CKKSViewManager manager] findView:@"Manatee"]; + [self.ckksViews addObject:self.manateeView]; + XCTAssertNotNil(self.manateeView, "CKKSViewManager created the Manatee view"); +} + +- (void)tearDown { + // If the test didn't already do this, allow each zone to spin up + self.accountStatus = CKAccountStatusNoAccount; + [self startCKKSSubsystem]; + + [self.manateeView halt]; + [self.manateeView waitUntilAllOperationsAreFinished]; + self.manateeView = nil; + + [super tearDown]; +} + +- (void)testSendPushMetricUponRequest { + for(CKRecordZoneID* zoneID in self.ckksZones) { + [self putFakeKeyHierarchyInCloudKit:zoneID]; + [self saveTLKMaterialToKeychain:zoneID]; + [self expectCKKSTLKSelfShareUpload:zoneID]; + } + + [self startCKKSSubsystem]; + + for(CKKSKeychainView* view in self.ckksViews) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should enter 'ready' for view %@", view); + } + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + CKRecord* keychainRecord = [self createFakeRecord:self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"keychain-view"]; + [self.keychainZone addToZone: keychainRecord]; + + // Manatee gets one too! + CKRecord* manateeRecord = [self createFakeRecord:self.manateeZoneID recordName:@"7B598D31-F9C5-481E-98AC-000000000000" withAccount:@"manatee-view"]; + [self.manateeZone addToZone:manateeRecord]; + + // Trigger a notification just for keychain zone. Both keychain and Manatee should process their incoming queues, and receive their items. + CKKSResultOperation* keychainProcessOp = [self.keychainView resultsOfNextProcessIncomingQueueOperation]; + XCTAssertNotNil(keychainProcessOp, "Should have gotten a promise operation from Keychain"); + CKKSResultOperation* manateeProcessOp = [self.manateeView resultsOfNextProcessIncomingQueueOperation]; + XCTAssertNotNil(manateeProcessOp, "Should have gotten a promise operation from Manatee"); + + // But if something goes wrong, don't block the whole test. Only way to do that is to make more operations, since there's no guarantee that the process ops above will ever be added + // to a queue (and thus become 'finished') + CKKSResultOperation* keychainProcessTimeoutOp = [CKKSResultOperation named:@"keychain-timeout" withBlock:^{}]; + [keychainProcessTimeoutOp timeout:20*NSEC_PER_SEC]; + [keychainProcessTimeoutOp addSuccessDependency:keychainProcessOp]; + [self.operationQueue addOperation:keychainProcessTimeoutOp]; + + CKKSResultOperation* manateeProcessTimeoutOp = [CKKSResultOperation named:@"manatee-timeout" withBlock:^{}]; + [manateeProcessTimeoutOp timeout:20*NSEC_PER_SEC]; + [manateeProcessTimeoutOp addSuccessDependency:manateeProcessOp]; + [self.operationQueue addOperation:manateeProcessTimeoutOp]; + + APSIncomingMessage* apsMessage = [CKKSAPSReceiverTests messageForZoneID:self.keychainZoneID]; + NSUUID* nsuuid = [NSUUID UUID]; + uuid_t uuid = {0}; + [nsuuid getUUIDBytes:(unsigned char*)&uuid]; + NSData* uuidData = [NSData dataWithBytes:&uuid length:sizeof(uuid)]; + + apsMessage.tracingUUID = uuidData; + apsMessage.tracingEnabled = YES; + + // Inject a message at the APS layer + // Because we can only make APS receivers once iCloud tells us the push environment after sign-in, we can't use our normal injection strategy, and fell back on global state. + CKKSAPSReceiver* apsReceiver = [CKKSAPSReceiver receiverForEnvironment:self.apsEnvironment + namedDelegatePort:SecCKKSAPSNamedPort + apsConnectionClass:[FakeAPSConnection class]]; + XCTAssertNotNil(apsReceiver, "Should have gotten an APS receiver"); + + // Also, CKKS should handle this in one single fetch + self.silentFetchesAllowed = false; + [self expectCKFetch]; + + // Expect two metric pushes, one from receiving the push and one from after we finish the fetch + // AFAICT there's no way to introspect a metric object to ensure we did it right + OCMExpect([self.mockContainerExpectations submitEventMetric:[OCMArg any]]); + OCMExpect([self.mockContainerExpectations submitEventMetric:[OCMArg any]]); + + // Launch! + [apsReceiver connection:nil didReceiveIncomingMessage:apsMessage]; + + OCMVerifyAllWithDelay(self.mockContainerExpectations, 16); + + // Now, wait for both views to run their processing + [keychainProcessTimeoutOp waitUntilFinished]; + XCTAssertNil(keychainProcessTimeoutOp.error, "Shouldn't have been any error processing incoming queue (keychain)"); + + [manateeProcessTimeoutOp waitUntilFinished]; + XCTAssertNil(manateeProcessTimeoutOp.error, "Shouldn't have been any error processing incoming queue (manatee)"); + + [self findGenericPassword:@"keychain-view" expecting:errSecSuccess]; + [self findGenericPassword:@"manatee-view" expecting:errSecSuccess]; +} + +- (void)testDoNotSendPushMetricWithoutRequest { + for(CKRecordZoneID* zoneID in self.ckksZones) { + [self putFakeKeyHierarchyInCloudKit:zoneID]; + [self saveTLKMaterialToKeychain:zoneID]; + [self expectCKKSTLKSelfShareUpload:zoneID]; + } + + [self startCKKSSubsystem]; + + for(CKKSKeychainView* view in self.ckksViews) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should enter 'ready' for view %@", view); + } + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + CKRecord* keychainRecord = [self createFakeRecord:self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"keychain-view"]; + [self.keychainZone addToZone: keychainRecord]; + + // Trigger a notification just for keychain zone. Both keychain and Manatee should process their incoming queues, and receive their items. + CKKSResultOperation* keychainProcessOp = [self.keychainView resultsOfNextProcessIncomingQueueOperation]; + XCTAssertNotNil(keychainProcessOp, "Should have gotten a promise operation from Keychain"); + + // But if something goes wrong, don't block the whole test. Only way to do that is to make more operations, since there's no guarantee that the process ops above will ever be added + // to a queue (and thus become 'finished') + CKKSResultOperation* keychainProcessTimeoutOp = [CKKSResultOperation named:@"keychain-timeout" withBlock:^{}]; + [keychainProcessTimeoutOp timeout:20*NSEC_PER_SEC]; + [keychainProcessTimeoutOp addSuccessDependency:keychainProcessOp]; + [self.operationQueue addOperation:keychainProcessTimeoutOp]; + + APSIncomingMessage* apsMessage = [CKKSAPSReceiverTests messageForZoneID:self.keychainZoneID]; + NSUUID* nsuuid = [NSUUID UUID]; + uuid_t uuid = {0}; + [nsuuid getUUIDBytes:(unsigned char*)&uuid]; + NSData* uuidData = [NSData dataWithBytes:&uuid length:sizeof(uuid)]; + + apsMessage.tracingUUID = uuidData; + apsMessage.tracingEnabled = NO; + + // Inject a message at the APS layer + // Because we can only make APS receivers once iCloud tells us the push environment after sign-in, we can't use our normal injection strategy, and fell back on global state. + CKKSAPSReceiver* apsReceiver = [CKKSAPSReceiver receiverForEnvironment:self.apsEnvironment + namedDelegatePort:SecCKKSAPSNamedPort + apsConnectionClass:[FakeAPSConnection class]]; + XCTAssertNotNil(apsReceiver, "Should have gotten an APS receiver"); + + // Also, CKKS should handle this in one single fetch + self.silentFetchesAllowed = false; + [self expectCKFetch]; + + // Any metric push is verboten + OCMReject([self.mockContainerExpectations submitEventMetric:[OCMArg any]]); + + // Launch! + [apsReceiver connection:nil didReceiveIncomingMessage:apsMessage]; + OCMVerifyAllWithDelay(self.mockContainerExpectations, 16); + + // Now, wait for both views to run their processing + [keychainProcessTimeoutOp waitUntilFinished]; + XCTAssertNil(keychainProcessTimeoutOp.error, "Shouldn't have been any error processing incoming queue (keychain)"); + + [self findGenericPassword:@"keychain-view" expecting:errSecSuccess]; +} + +@end + +#endif diff --git a/KeychainSyncingOverIDSProxy/IDSPersistentState.h b/keychain/ckks/tests/CKKSAPSReceiverTests.h similarity index 64% rename from KeychainSyncingOverIDSProxy/IDSPersistentState.h rename to keychain/ckks/tests/CKKSAPSReceiverTests.h index ce5da2d4..d6cc6bf5 100644 --- a/KeychainSyncingOverIDSProxy/IDSPersistentState.h +++ b/keychain/ckks/tests/CKKSAPSReceiverTests.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,22 +21,12 @@ * @APPLE_LICENSE_HEADER_END@ */ -// -// IDSPersistentState.h -// +#if OCTAGON -#import - -@interface KeychainSyncingOverIDSProxyPersistentState : NSObject -{ -} - -+ (id)read:(NSURL *)path error:(NSError **)error; -+ (BOOL)write:(NSURL *)path data:(id)plist error:(NSError **)error; -+ (NSString *)dictionaryDescription: (NSDictionary *)state; -+ (NSMutableDictionary *)idsState; -+ (void)setUnhandledMessages: (NSDictionary *)unhandledMessages; -+ (NSURL *)registrationFileURL; +@interface CKKSAPSReceiverTests : XCTestCase +@property CKRecordZoneID* testZoneID; ++ (APSIncomingMessage*)messageForZoneID:(CKRecordZoneID*)zoneID; @end +#endif diff --git a/keychain/ckks/tests/CKKSAPSReceiverTests.m b/keychain/ckks/tests/CKKSAPSReceiverTests.m index 6daee17d..94731dd6 100644 --- a/keychain/ckks/tests/CKKSAPSReceiverTests.m +++ b/keychain/ckks/tests/CKKSAPSReceiverTests.m @@ -27,6 +27,7 @@ #import #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSAPSReceiver.h" +#import "keychain/ckks/tests/CKKSAPSReceiverTests.h" #import "keychain/ckks/tests/MockCloudKit.h" #import "keychain/ckks/CKKSCondition.h" @@ -61,14 +62,9 @@ @end - -@interface CKKSAPSReceiverTests : XCTestCase -@property CKRecordZoneID* testZoneID; -@end - @implementation CKKSAPSReceiverTests -- (APSIncomingMessage*)messageForZoneID:(CKRecordZoneID*)zoneID { ++ (APSIncomingMessage*)messageForZoneID:(CKRecordZoneID*)zoneID { // reverse engineered from source code. Ugly. NSMutableDictionary* zoneInfo = [[NSMutableDictionary alloc] init]; @@ -89,7 +85,7 @@ self.testZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"testzone" ownerName:CKCurrentUserDefaultName]; // Make sure our helpers work properly - APSIncomingMessage* message = [self messageForZoneID:self.testZoneID]; + APSIncomingMessage* message = [CKKSAPSReceiverTests messageForZoneID:self.testZoneID]; XCTAssertNotNil(message, "Should have received a APSIncomingMessage"); CKNotification* notification = [CKNotification notificationFromRemoteNotificationDictionary:message.userInfo]; @@ -126,7 +122,7 @@ CKKSCondition* registered = [apsr registerReceiver:anr forZoneID:self.testZoneID]; XCTAssertEqual(0, [registered wait:1*NSEC_PER_SEC], "Registration should have completed within a second"); - APSIncomingMessage* message = [self messageForZoneID:self.testZoneID]; + APSIncomingMessage* message = [CKKSAPSReceiverTests messageForZoneID:self.testZoneID]; XCTAssertNotNil(message, "Should have received a APSIncomingMessage"); [apsr connection:apsr.apsConnection didReceiveIncomingMessage:message]; @@ -164,8 +160,8 @@ XCTAssertEqual(0, [registered wait:1*NSEC_PER_SEC], "Registration should have completed within a second"); XCTAssertEqual(0, [registered2 wait:1*NSEC_PER_SEC], "Registration should have completed within a second"); - [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[self messageForZoneID:self.testZoneID]]; - [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[self messageForZoneID:otherZoneID]]; + [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[CKKSAPSReceiverTests messageForZoneID:self.testZoneID]]; + [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[CKKSAPSReceiverTests messageForZoneID:otherZoneID]]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -177,7 +173,7 @@ XCTAssertNotNil(apsr, "Should have received a CKKSAPSReceiver"); // Receives a notification for the test zone - APSIncomingMessage* message = [self messageForZoneID:self.testZoneID]; + APSIncomingMessage* message = [CKKSAPSReceiverTests messageForZoneID:self.testZoneID]; XCTAssertNotNil(message, "Should have received a APSIncomingMessage"); [apsr connection:apsr.apsConnection didReceiveIncomingMessage:message]; diff --git a/keychain/ckks/tests/CKKSCloudKitTests.m b/keychain/ckks/tests/CKKSCloudKitTests.m index b91df343..2702077a 100644 --- a/keychain/ckks/tests/CKKSCloudKitTests.m +++ b/keychain/ckks/tests/CKKSCloudKitTests.m @@ -39,6 +39,7 @@ #import "keychain/ckks/CKKSMirrorEntry.h" #import "keychain/ckks/CKKSItemEncrypter.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #import "keychain/ckks/tests/MockCloudKit.h" @interface CKKSCloudKitTests : XCTestCase @@ -177,11 +178,12 @@ } - (NSMutableDictionary *)fetchRemoteItems { - CKFetchRecordZoneChangesOptions *options = [CKFetchRecordZoneChangesOptions new]; + CKFetchRecordZoneChangesConfiguration *options = [CKFetchRecordZoneChangesConfiguration new]; options.previousServerChangeToken = nil; - CKFetchRecordZoneChangesOperation *op = [[CKFetchRecordZoneChangesOperation alloc] initWithRecordZoneIDs:@[self.zoneID] optionsByRecordZoneID:@{self.zoneID : options}]; - op.qualityOfService = NSQualityOfServiceUserInitiated; + CKFetchRecordZoneChangesOperation *op = [[CKFetchRecordZoneChangesOperation alloc] initWithRecordZoneIDs:@[self.zoneID] configurationsByRecordZoneID:@{self.zoneID : options}]; + op.configuration.automaticallyRetryNetworkFailures = NO; + op.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; op.configuration.container = self.container; __block NSMutableDictionary *data = [NSMutableDictionary new]; @@ -215,8 +217,8 @@ dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); // These are new, fresh zones for each test. There should not be old keys yet. - if (synckeys != 3) {XCTFail(@"Unexpected number of synckeys: %lu", synckeys);} - if (currkeys != 3) {XCTFail(@"Unexpected number of current keys: %lu", currkeys);} + if (synckeys != 3) {XCTFail(@"Unexpected number of synckeys: %lu", (unsigned long)synckeys);} + if (currkeys != 3) {XCTFail(@"Unexpected number of current keys: %lu", (unsigned long)currkeys);} self.remoteItems = data; return data; @@ -273,7 +275,8 @@ - (BOOL)uploadRecords:(NSArray*)records { CKModifyRecordsOperation *op = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:records recordIDsToDelete:nil]; - op.qualityOfService = NSQualityOfServiceUserInitiated; + op.configuration.automaticallyRetryNetworkFailures = NO; + op.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; op.configuration.container = self.container; dispatch_semaphore_t sema = dispatch_semaphore_create(0); diff --git a/keychain/ckks/tests/CKKSDeviceStateUploadTests.m b/keychain/ckks/tests/CKKSDeviceStateUploadTests.m index a7bfeb28..5148b6e7 100644 --- a/keychain/ckks/tests/CKKSDeviceStateUploadTests.m +++ b/keychain/ckks/tests/CKKSDeviceStateUploadTests.m @@ -85,7 +85,7 @@ [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDeviceStateUploadRateLimited { @@ -126,7 +126,7 @@ runAfterModification:nil]; CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [op waitUntilFinished]; // Check that an immediate rate-limited retry doesn't upload anything @@ -140,7 +140,7 @@ checkModifiedRecord:nil runAfterModification:nil]; op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [op waitUntilFinished]; // And now, if the update is old enough, that'll work too @@ -178,7 +178,7 @@ checkModifiedRecord:nil runAfterModification:nil]; op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 12); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [op waitUntilFinished]; } @@ -190,7 +190,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword:@"password" account:@"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Check that an immediate rate-limited retry doesn't upload anything CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; @@ -236,7 +236,7 @@ // And allow the key state to progress [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDeviceStateUploadWaitsForKeyHierarchyWaitForTLK { @@ -280,8 +280,8 @@ // And allow the key state to progress [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDeviceStateReceive { @@ -368,7 +368,7 @@ return false; }]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDeviceStateUploadBadKeyState { @@ -377,7 +377,7 @@ [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); __weak __typeof(self) weakSelf = self; @@ -410,7 +410,7 @@ [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDeviceStateUploadWaitForUnlockKeyState { @@ -432,7 +432,7 @@ "last unlock date (%@) similar to threeDaysAgo (%@)", self.lockStateTracker.lastUnlockTime, threeDaysAgo); [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:8*NSEC_PER_SEC], "CKKS entered waitforunlock"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], "CKKS entered waitforunlock"); __weak __typeof(self) weakSelf = self; [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} @@ -464,7 +464,7 @@ [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDeviceStateUploadBadKeyStateAfterRestart { @@ -473,12 +473,12 @@ [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); // And restart CKKS... self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); __weak __typeof(self) weakSelf = self; @@ -511,12 +511,12 @@ [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDeviceStateUploadBadCircleState { - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; // This test has stuff in CloudKit, but no TLKs. @@ -524,7 +524,7 @@ [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered logged out"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered logged out"); XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateLoggedOut, "CKKS thinks it's logged out"); __weak __typeof(self) weakSelf = self; @@ -556,7 +556,7 @@ runAfterModification:nil]; CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [op waitUntilFinished]; XCTAssertNil(op.error, "No error uploading 'out of circle' device state"); @@ -573,7 +573,7 @@ [self startCKKSSubsystem]; // we should be stuck in fetch - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetch] wait:8*NSEC_PER_SEC], "Key state should become fetch"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetch] wait:20*NSEC_PER_SEC], "Key state should become fetch"); __weak __typeof(self) weakSelf = self; [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} @@ -612,7 +612,7 @@ XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateFetch, "CKKS re-entered fetch"); [self releaseCloudKitFetchHold]; - OCMVerifyAllWithDelay(self.mockDatabase, 16); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } diff --git a/keychain/ckks/tests/CKKSLoggerTests.m b/keychain/ckks/tests/CKKSLoggerTests.m index 4a83cc8d..610d8a68 100644 --- a/keychain/ckks/tests/CKKSLoggerTests.m +++ b/keychain/ckks/tests/CKKSLoggerTests.m @@ -107,8 +107,10 @@ static NSString* tablePath = nil; [[NSFileManager defaultManager] setAttributes:@{NSFilePosixPermissions : @(400), NSFileImmutable : @(YES)} ofItemAtPath:tablePath error:&error]; XCTAssertNil(error, @"encountered error setting database file attributes: %@", error); XCTAssertNoThrow([sqlTable openWithError:&error]); - XCTAssertNotNil(error, @"failed to generate error when opening file without permissions"); - error = nil; + XCTAssertNil(error, @"encounterd error when opening file without permissions: %@", error); + + XCTAssertFalse([sqlTable executeSQL:@"insert or replace into test (test_column) VALUES (1)"], + @"writing to read-only database succeeded"); [[NSFileManager defaultManager] setAttributes:originalAttributes ofItemAtPath:tablePath error:&error]; XCTAssertNil(error, @"encountered error setting database file attributes back to original attributes: %@", error); diff --git a/keychain/ckks/tests/CKKSManifestTests.m b/keychain/ckks/tests/CKKSManifestTests.m index e427957b..fbd7f991 100644 --- a/keychain/ckks/tests/CKKSManifestTests.m +++ b/keychain/ckks/tests/CKKSManifestTests.m @@ -117,7 +117,7 @@ [self.keychainView waitForKeyHierarchyReadiness]; // Wait for uploads to happen - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; int tlkshares = 1; int extraDeviceStates = 1; @@ -166,7 +166,7 @@ NSArray* knownItems = [self mirrorItemsForExistingItems]; [self addGenericPassword:@"data" account:@"unknown_account"]; [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; NSArray* newItems = [self mirrorItemsForExistingItems]; @@ -242,7 +242,7 @@ [self addGenericPassword:@"data" account:@"GenerationCountIncrease"]; [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; NSInteger postUpdateGenerationCount = [[CKKSEgoManifest tryCurrentEgoManifestForZone:self.keychainZoneID.zoneName] generationCount]; diff --git a/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m b/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m index 107af38b..a0df21e4 100644 --- a/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m +++ b/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m @@ -470,6 +470,33 @@ [self waitForExpectations: @[first] timeout:0.5]; } +- (void)testChangeDelay { + XCTestExpectation *first = [self expectationWithDescription:@"FutureScheduler fired (one)"]; + first.assertForOverFulfill = NO; + + XCTestExpectation *second = [self expectationWithDescription:@"FutureScheduler fired (two)"]; + second.expectedFulfillmentCount = 2; + second.assertForOverFulfill = YES; + + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_SEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ + [first fulfill]; + [second fulfill]; + }]; + + [scheduler changeDelays:100*NSEC_PER_MSEC continuingDelay:100*NSEC_PER_MSEC]; + [scheduler trigger]; + + [self waitForExpectations: @[first] timeout:0.4]; + + [scheduler trigger]; + [scheduler trigger]; + [scheduler trigger]; + + [self waitForExpectations: @[second] timeout:0.4]; +} + @end #endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CKKSSOSTests.m b/keychain/ckks/tests/CKKSSOSTests.m index c1032239..ace52343 100644 --- a/keychain/ckks/tests/CKKSSOSTests.m +++ b/keychain/ckks/tests/CKKSSOSTests.m @@ -86,6 +86,11 @@ @property FakeCKZone* applepayZone; @property (readonly) ZoneKeys* applepayZoneKeys; +@property CKRecordZoneID* homeZoneID; +@property CKKSKeychainView* homeView; +@property FakeCKZone* homeZone; +@property (readonly) ZoneKeys* homeZoneKeys; + @end @implementation CloudKitKeychainSyncingSOSIntegrationTests @@ -105,12 +110,13 @@ SecCKKSTestSetDisableSOS(false); // Wait for the ViewManager to be brought up - XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:4*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize"); + XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:20*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize"); self.engramZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Engram" ownerName:CKCurrentUserDefaultName]; self.engramZone = [[FakeCKZone alloc] initZone: self.engramZoneID]; self.zones[self.engramZoneID] = self.engramZone; self.engramView = [[CKKSViewManager manager] findView:@"Engram"]; + [self.ckksViews addObject:self.engramView]; XCTAssertNotNil(self.engramView, "CKKSViewManager created the Engram view"); [self.ckksZones addObject:self.engramZoneID]; @@ -118,6 +124,7 @@ self.manateeZone = [[FakeCKZone alloc] initZone: self.manateeZoneID]; self.zones[self.manateeZoneID] = self.manateeZone; self.manateeView = [[CKKSViewManager manager] findView:@"Manatee"]; + [self.ckksViews addObject:self.manateeView]; XCTAssertNotNil(self.manateeView, "CKKSViewManager created the Manatee view"); [self.ckksZones addObject:self.manateeZoneID]; @@ -125,6 +132,7 @@ self.autoUnlockZone = [[FakeCKZone alloc] initZone: self.autoUnlockZoneID]; self.zones[self.autoUnlockZoneID] = self.autoUnlockZone; self.autoUnlockView = [[CKKSViewManager manager] findView:@"AutoUnlock"]; + [self.ckksViews addObject:self.autoUnlockView]; XCTAssertNotNil(self.autoUnlockView, "CKKSViewManager created the AutoUnlock view"); [self.ckksZones addObject:self.autoUnlockZoneID]; @@ -132,6 +140,7 @@ self.healthZone = [[FakeCKZone alloc] initZone: self.healthZoneID]; self.zones[self.healthZoneID] = self.healthZone; self.healthView = [[CKKSViewManager manager] findView:@"Health"]; + [self.ckksViews addObject:self.healthView]; XCTAssertNotNil(self.healthView, "CKKSViewManager created the Health view"); [self.ckksZones addObject:self.healthZoneID]; @@ -139,8 +148,16 @@ self.applepayZone = [[FakeCKZone alloc] initZone: self.healthZoneID]; self.zones[self.applepayZoneID] = self.applepayZone; self.applepayView = [[CKKSViewManager manager] findView:@"ApplePay"]; + [self.ckksViews addObject:self.applepayView]; XCTAssertNotNil(self.applepayView, "CKKSViewManager created the ApplePay view"); [self.ckksZones addObject:self.applepayZoneID]; + + self.homeZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Home" ownerName:CKCurrentUserDefaultName]; + self.homeZone = [[FakeCKZone alloc] initZone: self.healthZoneID]; + 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]; } + (void)tearDown { @@ -174,6 +191,10 @@ [self.applepayView waitUntilAllOperationsAreFinished]; self.applepayView = nil; + [self.homeView halt]; + [self.homeView waitUntilAllOperationsAreFinished]; + self.homeView = nil; + [super tearDown]; } @@ -191,6 +212,47 @@ } } +-(void)testAllViewsMakeNewKeyHierarchies { + // Test starts with nothing anywhere + + // Due to our new cross-zone fetch system, CKKS should only issue one fetch for all zones + // Since the tests can sometimes be slow, slow down the fetcher to normal speed + [self.injectedManager.zoneChangeFetcher.fetchScheduler changeDelays:2*NSEC_PER_SEC continuingDelay:30*NSEC_PER_SEC]; + self.silentFetchesAllowed = false; + [self expectCKFetch]; + + [self startCKKSSubsystem]; + + // All zones should upload a key hierarchy + for(CKRecordZoneID* zoneID in self.ckksZones) { + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:zoneID]; + } + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + for(CKKSKeychainView* view in self.ckksViews) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should enter 'ready' for view %@", view); + } +} + +-(void)testAllViewsAcceptExistingKeyHierarchies { + for(CKRecordZoneID* zoneID in self.ckksZones) { + [self putFakeKeyHierarchyInCloudKit:zoneID]; + [self saveTLKMaterialToKeychain:zoneID]; + [self expectCKKSTLKSelfShareUpload:zoneID]; + } + + [self.injectedManager.zoneChangeFetcher.fetchScheduler changeDelays:2*NSEC_PER_SEC continuingDelay:30*NSEC_PER_SEC]; + self.silentFetchesAllowed = false; + [self expectCKFetch]; + + [self startCKKSSubsystem]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + for(CKKSKeychainView* view in self.ckksViews) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should enter 'ready' for view %@", view); + } +} + -(void)testAddEngramManateeItems { [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. @@ -214,7 +276,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.manateeZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me-manatee" viewHint:(NSString*) kSecAttrViewHintManatee]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectations:@[manateeChanged] timeout:1]; [self waitForExpectations:@[pcsChanged] timeout:1]; } @@ -233,7 +295,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.autoUnlockZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintAutoUnlock]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectations:@[autoUnlockChanged] timeout:1]; [self waitForExpectations:@[pcsChanged] timeout:0.2]; } @@ -252,7 +314,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.healthZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintHealth]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectations:@[healthChanged] timeout:1]; [self waitForExpectations:@[pcsChanged] timeout:0.2]; } @@ -271,11 +333,29 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.applepayZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintApplePay]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectations:@[applepayChanged] timeout:1]; [self waitForExpectations:@[pcsChanged] timeout:0.2]; } +-(void)testAddHomeItems { + [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. + + [self startCKKSSubsystem]; + + XCTestExpectation* homeChanged = [self expectChangeForView:self.homeZoneID.zoneName]; + // Home is NOT a 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.homeZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintHome]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForExpectations:@[homeChanged] timeout:1]; + [self waitForExpectations:@[pcsChanged] timeout:0.2]; +} -(void)testAddOtherViewHintItem { [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. @@ -287,7 +367,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me-password" viewHint:(NSString*) kSOSViewAutofillPasswords]; sleep(1); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testReceiveItemInView { @@ -359,6 +439,9 @@ [self.applepayZoneKeys.tlk loadKeyMaterialFromKeychain:&error]; XCTAssertNil(error, "No error loading ApplePay tlk from piggy contents"); + + [self.homeZoneKeys.tlk loadKeyMaterialFromKeychain:&error]; + XCTAssertNil(error, "No error loading Home tlk from piggy contents"); } -(NSString*)fileForStorage @@ -383,7 +466,7 @@ [self waitForKeyHierarchyReadinesses]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); /* * Pull data from keychain and view manager @@ -418,7 +501,7 @@ XCTAssertNotNil(result, "Initial not set"); NSArray *copiedTLKs = result[@"tlks"]; XCTAssertNotNil(copiedTLKs, "tlks not set"); - XCTAssertEqual([copiedTLKs count], [tlks count], "tlks count not same"); + XCTAssertEqual([copiedTLKs count], 5u, "piggybacking should have gotten 5 TLKs across (but we have more than that elsewhere)"); NSArray *copiediCloudidentities = result[@"idents"]; XCTAssertNotNil(copiediCloudidentities, "idents not set"); @@ -456,12 +539,19 @@ @"v_Data" : [NSData dataWithBytes:key length:sizeof(key)], @"auth" : @YES, }, + @{ + @"acct" : @"66666666", + @"srvr" : @"Home", + @"v_Data" : [NSData dataWithBytes:key length:sizeof(key)], + @"auth" : @YES, + }, ]; NSArray* sortedTLKs = SOSAccountSortTLKS(tlks); XCTAssertNotNil(sortedTLKs, "sortedTLKs not set"); - NSArray *expectedOrder = @[ @"11111111", @"22222222", @"33333333", @"44444444", @"55555555"]; + // Home gets sorted into the middle, as the other Health and Manatee TLKs aren't 'authoritative' + NSArray *expectedOrder = @[ @"11111111", @"22222222", @"33333333", @"66666666", @"44444444", @"55555555"]; [sortedTLKs enumerateObjectsUsingBlock:^(NSDictionary *tlk, NSUInteger idx, BOOL * _Nonnull stop) { NSString *uuid = tlk[@"acct"]; XCTAssertEqualObjects(uuid, expectedOrder[idx], "wrong order"); @@ -488,7 +578,7 @@ [self.manateeView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Verify that there are three local keys, and three local current key records __weak __typeof(self) weakSelf = self; @@ -533,6 +623,7 @@ [self putFakeDeviceStatusInCloudKit: self.autoUnlockZoneID]; [self putFakeDeviceStatusInCloudKit: self.healthZoneID]; [self putFakeDeviceStatusInCloudKit: self.applepayZoneID]; + [self putFakeDeviceStatusInCloudKit: self.homeZoneID]; } -(void)putFakeKeyHierachiesInCloudKit{ @@ -541,6 +632,7 @@ [self putFakeKeyHierarchyInCloudKit: self.autoUnlockZoneID]; [self putFakeKeyHierarchyInCloudKit: self.healthZoneID]; [self putFakeKeyHierarchyInCloudKit: self.applepayZoneID]; + [self putFakeKeyHierarchyInCloudKit: self.homeZoneID]; } -(void)saveTLKsToKeychain{ [self saveTLKMaterialToKeychain:self.engramZoneID]; @@ -548,6 +640,7 @@ [self saveTLKMaterialToKeychain:self.autoUnlockZoneID]; [self saveTLKMaterialToKeychain:self.healthZoneID]; [self saveTLKMaterialToKeychain:self.applepayZoneID]; + [self saveTLKMaterialToKeychain:self.homeZoneID]; } -(void)deleteTLKMaterialsFromKeychain{ [self deleteTLKMaterialFromKeychain: self.engramZoneID]; @@ -555,6 +648,7 @@ [self deleteTLKMaterialFromKeychain: self.autoUnlockZoneID]; [self deleteTLKMaterialFromKeychain: self.healthZoneID]; [self deleteTLKMaterialFromKeychain: self.applepayZoneID]; + [self deleteTLKMaterialFromKeychain: self.homeZoneID]; } -(void)waitForKeyHierarchyReadinesses { @@ -563,6 +657,7 @@ [self.autoUnlockView waitForKeyHierarchyReadiness]; [self.healthView waitForKeyHierarchyReadiness]; [self.applepayView waitForKeyHierarchyReadiness]; + [self.homeView waitForKeyHierarchyReadiness]; } -(void)testAcceptExistingAndUsePiggyKeyHierarchy { @@ -577,9 +672,9 @@ [self startCKKSSubsystem]; // The CKKS subsystem should not try to write anything to the CloudKit database. - XCTAssertEqual(0, [self.manateeView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:400*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqual(0, [self.manateeView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now, save the TLKs to the keychain (to simulate them coming in later via piggybacking). for(CKRecordZoneID* zoneID in self.ckksZones) { @@ -593,7 +688,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.manateeZoneID checkItem: [self checkClassCBlock:self.manateeZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me-manatee" viewHint:(id)kSecAttrViewHintManatee]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.manateeZoneID checkItem: [self checkClassABlock:self.manateeZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -603,7 +698,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } @end diff --git a/keychain/ckks/tests/CKKSServerValidationRecoveryTests.m b/keychain/ckks/tests/CKKSServerValidationRecoveryTests.m index ad867df6..acc1818d 100644 --- a/keychain/ckks/tests/CKKSServerValidationRecoveryTests.m +++ b/keychain/ckks/tests/CKKSServerValidationRecoveryTests.m @@ -77,7 +77,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; XCTAssertEqualObjects(newClassAKey, self.keychainZone.currentDatabase[self.keychainZoneKeys.currentClassAPointer.storedCKRecord.recordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class A key reference"); @@ -110,7 +110,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; XCTAssertEqualObjects(newClassCKey, self.keychainZone.currentDatabase[self.keychainZoneKeys.currentClassCPointer.storedCKRecord.recordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class C key reference"); @@ -133,7 +133,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Break the key hierarchy [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -148,13 +148,13 @@ // CKKS should then fix the pointers and give itself a new TLK share record, but not update any keys [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:1 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self.keychainView notifyZoneChange:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And then upload the item as usual [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me-2"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; XCTAssertEqualObjects(newClassCKey, self.keychainZone.currentDatabase[self.keychainZoneKeys.currentClassCPointer.storedCKRecord.recordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class C key reference"); @@ -179,11 +179,13 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); - // Break the key hierarchy + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should have arrived at ready"); + [self waitForCKModifications]; + + // Break the key hierarchy. The TLK will arrive via SOS later in this test. [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; - [self saveTLKMaterialToKeychain:self.keychainZoneID]; CKReference* newClassCKey = self.keychainZone.currentDatabase[classCPointerRecordID][SecCKRecordParentKeyRefKey]; CKRecord* classCPointer = self.keychainZone.currentDatabase[classCPointerRecordID]; @@ -206,14 +208,16 @@ // It should not try to modify the pointers again, but it should give itself the new TLK [self expectCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID]; [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + + [self saveTLKMaterialToKeychain:self.keychainZoneID]; [self.keychainView notifyZoneChange:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And then use the 'new' key as it should [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me-2"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; XCTAssertEqualObjects(newClassCKey, self.keychainZone.currentDatabase[classCPointerRecordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class C key reference"); @@ -240,7 +244,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Now, break the class C pointer, but don't tell CKKS @@ -261,7 +265,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me-2"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; XCTAssertEqualObjects(newClassCKey, self.keychainZone.currentDatabase[classCPointerRecordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class C key reference"); diff --git a/keychain/ckks/tests/CKKSTLKSharingTests.m b/keychain/ckks/tests/CKKSTLKSharingTests.m index 3bda9247..2a381983 100644 --- a/keychain/ckks/tests/CKKSTLKSharingTests.m +++ b/keychain/ckks/tests/CKKSTLKSharingTests.m @@ -38,6 +38,7 @@ #import "keychain/ckks/CKKSTLKShare.h" #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #import "keychain/ckks/tests/MockCloudKit.h" #import "keychain/ckks/tests/CKKSTests.h" @@ -151,9 +152,9 @@ // The CKKS subsystem should accept the keys, and share the TLK back to itself [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Verify that there are three local keys, and three local current key records __weak __typeof(self) weakSelf = self; @@ -198,9 +199,9 @@ return TRUE; }]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Verify that there are three local keys, and three local current key records __weak __typeof(self) weakSelf = self; @@ -239,7 +240,7 @@ // CKKS should enter 'waitfortlk' without crashing [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:10*NSEC_PER_SEC], "Key state should become waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk"); } - (void)testAcceptExistingTLKSharedKeyHierarchyAndUse { @@ -258,7 +259,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -268,7 +269,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testNewTLKSharesHaveChangeTags { @@ -284,9 +285,9 @@ // The CKKS subsystem should accept the keys, and share the TLK back to itself [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Verify that making a new share will have the old share's change tag @@ -331,8 +332,8 @@ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); // The CKKS subsystem should not try to write anything to the CloudKit database while it's accepting the keys - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Make another share, but from an untrusted peer to some other peer. local shouldn't necessarily care. @@ -402,7 +403,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -412,7 +413,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testReceiveTLKShareWhileLocked { @@ -429,7 +430,7 @@ [self startCKKSSubsystem]; // The CKKS subsystem should not try to write anything to the CloudKit database, but it should enter waitforunlock - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:10*NSEC_PER_SEC], "Key state should become waitforunlock"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], "Key state should become waitforunlock"); // Now unlock things. We expect a TLKShare upload. [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; @@ -437,8 +438,8 @@ self.aksLockState = false; [self.lockStateTracker recheck]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testUploadTLKSharesForExistingHierarchy { @@ -449,7 +450,7 @@ [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testUploadTLKSharesForExistingHierarchyOnRestart { @@ -460,8 +461,8 @@ [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Now, delete all the TLK Shares, so CKKS will upload them again @@ -484,8 +485,8 @@ [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID]; self.keychainView = [self.injectedManager restartZone: self.keychainZoneID.zoneName]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); } - (void)testHandleExternalSharedTLKRoll { @@ -496,7 +497,7 @@ [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Now the external peer rolls the TLK and updates the shares @@ -509,8 +510,8 @@ // Trigger a notification [self.keychainView notifyZoneChange:nil]; [self.keychainView waitForFetchAndIncomingQueueProcessing]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // We expect a single record to be uploaded. @@ -518,7 +519,7 @@ checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me-rolled-key"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testUploadTLKSharesForExternalTLKRollWithoutShares { @@ -529,7 +530,7 @@ [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now, an old (Tigris) peer rolls the TLK, but doesn't share it // CKKS should get excited and throw 3 new share records up @@ -544,15 +545,15 @@ // Trigger a notification [self.keychainView notifyZoneChange:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); // We expect a single record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me-rolled-key"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromTLKShareUploadFailure { @@ -567,8 +568,8 @@ }]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); } - (void)testFillInMissingPeerShares { @@ -588,7 +589,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -598,7 +599,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDontAcceptTLKFromUntrustedPeer { @@ -639,13 +640,13 @@ // The CKKS subsystem should now accept the key, and share the TLK back to itself [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); // And use it as well [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testSendNewTLKSharesOnTrustSetAddition { @@ -659,14 +660,14 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Cool! New peer arrives! [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self.currentPeers addObject:self.remotePeer1]; [self.injectedManager sendTrustedPeerSetChangedUpdate]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // step 2: add a new peer who already has a share; no share should be created @@ -689,12 +690,12 @@ [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now, lock. self.aksLockState = true; @@ -705,17 +706,17 @@ [self.injectedManager sendTrustedPeerSetChangedUpdate]; // CKKS should notice that it has things to do... - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); // And do them. [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; self.aksLockState = false; [self.lockStateTracker recheck]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // and return to ready - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); } - (void)testAddItemDuringNewTLKSharesOnTrustSetAddition { @@ -726,7 +727,7 @@ [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Hold the TLK share modification @@ -736,7 +737,7 @@ [self.currentPeers addObject:self.remotePeer1]; [self.injectedManager sendTrustedPeerSetChangedUpdate]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // While CloudKit is hanging the write, add an item [self addGenericPassword: @"data" account: @"account-delete-me"]; @@ -746,7 +747,7 @@ checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self releaseCloudKitModificationHold]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testSendNewTLKSharesOnTrustSetRemoval { @@ -768,8 +769,8 @@ // CKKS should become very upset, and enter waitfortlk. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:4000*NSEC_PER_SEC], "Key state should become waitfortlk"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testSendNewTLKShareToPeerOnPeerEncryptionKeyChange { @@ -781,8 +782,8 @@ [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:3 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:1000*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); // Remote peer rolls its encryption key... [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID @@ -797,10 +798,10 @@ self.remotePeer1.encryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; [self.injectedManager sendTrustedPeerSetChangedUpdate]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); } - (void)testRecoverFromBrokenSignatureOnTLKShareDuetoSignatureKeyChange { @@ -821,8 +822,8 @@ [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:10*NSEC_PER_SEC], "Key state should become waitfortlk"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk"); // Remote peer discovers its error and sends a new TLKShare! CKKS should recover and share itself a TLKShare [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID @@ -837,9 +838,9 @@ [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; [self.keychainView notifyZoneChange:nil]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; } @@ -857,8 +858,8 @@ // The CKKS subsystem should accept the keys, and share the TLK back to itself [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:100*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); // Remote peer rolls its signing key, but hasn't updated its TLKShare. We should send it one. [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID @@ -873,10 +874,10 @@ self.remotePeer1.signingKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; [self.injectedManager sendTrustedPeerSetChangedUpdate]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); } - (void)testSendNewTLKShareToPeerOnDisappearanceOfPeerKeys { @@ -888,8 +889,8 @@ // The CKKS subsystem should accept the keys, and share the TLK back to itself [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:100*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); // Now, peer 1 updates its keys (to be nil). Local peer should re-send TLKShares to peer2. @@ -907,10 +908,10 @@ [self.currentPeers addObject:brokenRemotePeer1]; [self.injectedManager sendTrustedPeerSetChangedUpdate]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); } - (void)testSendNewTLKShareToPeerOnDisappearanceOfPeerSigningKey { @@ -924,8 +925,8 @@ // The CKKS subsystem should accept the keys, and share the TLK back to itself [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:100*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); // Now, peer 1 updates its signing key (to be nil). Local peer should re-send TLKShares to peer1 and peer2. // Both should be sent because both peers don't have a signed TLKShare that gives them the TLK @@ -956,11 +957,11 @@ [self.currentPeers addObject:brokenRemotePeer1]; [self.injectedManager sendTrustedPeerSetChangedUpdate]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self waitForExpectations:@[peer1Share, peer2Share] timeout:5]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); } - (void)testSendNewTLKShareToSelfOnSelfKeyChanges { @@ -974,8 +975,8 @@ // The CKKS subsystem should accept the keys, and share the TLK back to itself [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); // Local peer rolls its encryption key (and loses the old ones) [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID @@ -994,8 +995,8 @@ self.pastSelfPeers = [NSMutableSet set]; [self.injectedManager sendSelfPeerChangedUpdate]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); // Now, local peer loses and rolls its signing key (and loses the old one) [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID @@ -1014,8 +1015,8 @@ self.pastSelfPeers = [NSMutableSet set]; [self.injectedManager sendSelfPeerChangedUpdate]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); } - (void)testDoNotResetCloudKitZoneFromWaitForTLKDueToRecentTLKShare { @@ -1037,7 +1038,7 @@ self.keychainZone.flag = true; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false"); } @@ -1064,7 +1065,7 @@ self.keychainZone.flag = true; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false"); // And ensure it doesn't go on to 'reset' @@ -1094,11 +1095,11 @@ self.keychainZone.flag = true; [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:3 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*NSEC_PER_SEC], @"Key state should become 'resetzone'"); // Then we should reset. - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); // And the zone should have been cleared and re-made XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); @@ -1120,9 +1121,9 @@ // CKKS subsystem should realize that it can't read the shares it has, and enter waitfortlk [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:10*NSEC_PER_SEC], "Key state should become 'waitfortlk'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become 'waitfortlk'"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Fetching status should be quick @@ -1131,7 +1132,7 @@ XCTAssertNil(error, "should be no error fetching status for keychain"); [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:1.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; // But, if by some miracle those keys come back, CKKS should be able to recover // It'll also upload itself a TLK share @@ -1141,9 +1142,9 @@ self.currentSelfPeerError = nil; [self.injectedManager sendSelfPeerChangedUpdate]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:100*NSEC_PER_SEC], "Key state should become 'ready''"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become 'ready''"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; } diff --git a/keychain/ckks/tests/CKKSTests+API.m b/keychain/ckks/tests/CKKSTests+API.m index 43e2160a..7d316458 100644 --- a/keychain/ckks/tests/CKKSTests+API.m +++ b/keychain/ckks/tests/CKKSTests+API.m @@ -32,6 +32,8 @@ #include #import +#import "keychain/categories/NSError+UsefulConstructors.h" + #import "keychain/ckks/tests/CloudKitMockXCTest.h" #import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" #import "keychain/ckks/CKKS.h" @@ -100,10 +102,10 @@ }), @"_SecItemAddAndNotifyOnSync succeeded"); // Verify that the item was written to CloudKit - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // In real code, you'd need to wait for the _SecItemAddAndNotifyOnSync callback to succeed before proceeding - [self waitForExpectations:@[syncExpectation] timeout:8.0]; + [self waitForExpectations:@[syncExpectation] timeout:20]; return (NSDictionary*) CFBridgingRelease(result); } @@ -235,7 +237,7 @@ self.silentFetchesAllowed = false; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.loggedOut wait:2*NSEC_PER_SEC], "CKKS should positively log out"); + XCTAssertEqual(0, [self.keychainView.loggedOut wait:20*NSEC_PER_SEC], "CKKS should positively log out"); NSMutableDictionary* query = [@{ (id)kSecClass : (id)kSecClassGenericPassword, @@ -284,7 +286,7 @@ // And now, allow CKKS to discover we're logged out [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.loggedOut wait:2*NSEC_PER_SEC], "CKKS should positively log out"); + XCTAssertEqual(0, [self.keychainView.loggedOut wait:20*NSEC_PER_SEC], "CKKS should positively log out"); [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -299,7 +301,7 @@ [self holdCloudKitFetches]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.loggedIn wait:2*NSEC_PER_SEC], "CKKS should log in"); + XCTAssertEqual(0, [self.keychainView.loggedIn wait:20*NSEC_PER_SEC], "CKKS should log in"); [self.keychainView.zoneSetupOperation waitUntilFinished]; NSMutableDictionary* query = [@{ @@ -322,15 +324,15 @@ }), @"_SecItemAddAndNotifyOnSync succeeded"); // We should be in the 'fetch' state, but no further - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetch] wait:100*NSEC_PER_MSEC], @"Should have reached key state 'fetch', but no further"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetch] wait:20*NSEC_PER_SEC], @"Should have reached key state 'fetch', but no further"); // When we release the fetch, the callback should still fire and the item should upload [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self releaseCloudKitFetchHold]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], @"Should have reached key state 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Should have reached key state 'ready'"); // Verify that the item was written to CloudKit - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -368,7 +370,7 @@ XCTAssertEqual(errSecSuccess, SecItemAdd((__bridge CFDictionaryRef) query, NULL), @"SecItemAdd succeeded"); // Verify that the item is written to CloudKit - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); CFTypeRef item = NULL; query[(id)kSecValueData] = nil; @@ -424,7 +426,7 @@ XCTAssertEqual(errSecSuccess, SecItemAdd((__bridge CFDictionaryRef) query, NULL), @"SecItemAdd succeeded"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; query[(id)kSecValueData] = nil; @@ -452,7 +454,7 @@ PCSPublicIdentity:newPublicIdentity]]; XCTAssertEqual(errSecSuccess, SecItemUpdate((__bridge CFDictionaryRef) query, (__bridge CFDictionaryRef) update), @"SecItemUpdate succeeded"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); CFTypeRef item = NULL; query[(id)kSecValueData] = nil; @@ -509,7 +511,7 @@ XCTAssertEqual(errSecSuccess, SecItemAdd((__bridge CFDictionaryRef) query, NULL), @"SecItemAdd succeeded"); - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Find the item record in CloudKit. Since we're using kSecAttrDeriveSyncIDFromItemAttributes, @@ -679,7 +681,7 @@ PCSPublicIdentity:publicIdentity]]; [self updateGenericPassword:@"different password" account:@"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; CKRecord* newRecord = self.keychainZone.currentDatabase[recordID]; @@ -701,7 +703,7 @@ // We expect a single record to be uploaded [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // After the local reset, we expect: a fetch, then nothing self.silentFetchesAllowed = false; @@ -712,9 +714,9 @@ XCTAssertNil(result, "no error resetting local"); [resetExpectation fulfill]; }]; - [self waitForExpectations:@[resetExpectation] timeout:8.0]; + [self waitForExpectations:@[resetExpectation] timeout:20]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; [self addGenericPassword:@"asdf" @@ -723,12 +725,12 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } -(void)testResetLocalWhileLoggedOut { // We're "logged in to" cloudkit but not in circle. - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; self.silentFetchesAllowed = false; @@ -760,7 +762,7 @@ [resetExpectation fulfill]; }]; - [self waitForExpectations:@[resetExpectation] timeout:1.0]; + [self waitForExpectations:@[resetExpectation] timeout:20]; [self.keychainView dispatchSync: ^bool{ CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:self.keychainView.zoneName]; @@ -771,7 +773,7 @@ // Now log in, and see what happens! It should re-fetch, pick up the old key hierarchy, and use it [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; self.silentFetchesAllowed = true; - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem:[self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -781,7 +783,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } -(void)testResetLocalMultipleTimes { @@ -794,11 +796,11 @@ [self startCKKSSubsystem]; // We expect a single record to be uploaded - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // We're going to request a bunch of CloudKit resets, but hold them from finishing @@ -826,9 +828,9 @@ // After the reset(s), we expect no uploads. Let the resets flow! [self releaseCloudKitFetchHold]; [self waitForExpectations:@[resetExpectation0, resetExpectation1, resetExpectation2] timeout:20]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID checkItem:[self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -838,7 +840,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } -(void)testResetCloudKitZone { @@ -855,7 +857,7 @@ // We expect a single record to be uploaded [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // After the reset, we expect a key hierarchy upload, and then the class C item upload @@ -863,14 +865,14 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"]; - [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { + [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) { XCTAssertNil(result, "no error resetting cloudkit"); secnotice("ckks", "Received a resetCloudKit callback"); [resetExpectation fulfill]; }]; - [self waitForExpectations:@[resetExpectation] timeout:8.0]; + [self waitForExpectations:@[resetExpectation] timeout:20]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; [self addGenericPassword:@"asdf" @@ -879,7 +881,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testResetCloudKitZoneDuringWaitForTLK { @@ -896,11 +898,11 @@ // No records should be uploaded [self addGenericPassword: @"data" account: @"account-delete-me"]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS should have entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS should have entered waitfortlk"); // Restart CKKS to really get in the spirit of waitfortlk (and get a pending processOutgoingQueue operation going) self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); CKKSOutgoingQueueOperation* outgoingOp = [self.keychainView processOutgoingQueue:nil]; XCTAssertTrue([outgoingOp isPending], "outgoing queue processing should be on hold"); @@ -912,14 +914,14 @@ checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"]; - [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { + [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) { XCTAssertNil(result, "no error resetting cloudkit"); [resetExpectation fulfill]; }]; - [self waitForExpectations:@[resetExpectation] timeout:8.0]; + [self waitForExpectations:@[resetExpectation] timeout:20]; XCTAssertTrue([outgoingOp isCancelled], "old stuck ProcessOutgoingQueue should be cancelled"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And adding another item works too [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -929,7 +931,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } /* @@ -947,11 +949,11 @@ // No records should be uploaded [self addGenericPassword: @"data" account: @"account-delete-me"]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS should have entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS should have entered waitfortlk"); // Restart CKKS to really get in the spirit of waitfortlk (and get a pending processOutgoingQueue operation going) self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); CKKSOutgoingQueueOperation* outgoingOp = [self.keychainView processOutgoingQueue:nil]; XCTAssertTrue([outgoingOp isPending], "outgoing queue processing should be on hold"); @@ -967,10 +969,10 @@ XCTAssertNil(result, "no error resetting local"); [resetExpectation fulfill]; }]; - [self waitForExpectations:@[resetExpectation] timeout:8.0]; + [self waitForExpectations:@[resetExpectation] timeout:20]; XCTAssertTrue([outgoingOp isCancelled], "old stuck ProcessOutgoingQueue should be cancelled"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And adding another item works too [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -980,14 +982,14 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); }*/ -(void)testResetCloudKitZoneWhileLoggedOut { self.silentZoneDeletesAllowed = true; // We're "logged in to" cloudkit but not in circle. - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; self.silentFetchesAllowed = false; @@ -1004,23 +1006,23 @@ XCTAssertNotNil(self.keychainZone.currentDatabase[ckr.recordID], "An item exists in the fake zone"); XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"]; - [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { + [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) { XCTAssertNil(result, "no error resetting cloudkit"); secnotice("ckks", "Received a resetCloudKit callback"); [resetExpectation fulfill]; }]; - [self waitForExpectations:@[resetExpectation] timeout:1.0]; + [self waitForExpectations:@[resetExpectation] timeout:20]; XCTAssertNil(self.keychainZone.currentDatabase, "No zone anymore!"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now log in, and see what happens! It should create the zone again and upload a whole new key hierarchy self.silentFetchesAllowed = true; - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem:[self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; [self addGenericPassword:@"asdf" @@ -1029,7 +1031,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testResetCloudKitZoneMultipleTimes { @@ -1044,11 +1046,11 @@ [self startCKKSSubsystem]; // We expect a single record to be uploaded - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // We're going to request a bunch of CloudKit resets, but hold them from finishing @@ -1057,17 +1059,17 @@ XCTestExpectation* resetExpectation0 = [self expectationWithDescription: @"reset callback(0) occurs"]; XCTestExpectation* resetExpectation1 = [self expectationWithDescription: @"reset callback(1) occurs"]; XCTestExpectation* resetExpectation2 = [self expectationWithDescription: @"reset callback(2) occurs"]; - [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { + [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) { XCTAssertNil(result, "should receive no error resetting cloudkit"); secnotice("ckksreset", "Received a resetCloudKit(0) callback"); [resetExpectation0 fulfill]; }]; - [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { + [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) { XCTAssertNil(result, "should receive no error resetting cloudkit"); secnotice("ckksreset", "Received a resetCloudKit(1) callback"); [resetExpectation1 fulfill]; }]; - [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { + [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) { XCTAssertNil(result, "should receive no error resetting cloudkit"); secnotice("ckksreset", "Received a resetCloudKit(2) callback"); [resetExpectation2 fulfill]; @@ -1081,9 +1083,9 @@ // And let the resets flow [self releaseCloudKitFetchHold]; [self waitForExpectations:@[resetExpectation0, resetExpectation1, resetExpectation2] timeout:20]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID checkItem:[self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -1093,14 +1095,14 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRPCFetchAndProcessWhileCloudKitNotResponding { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); [self holdCloudKitFetches]; XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; @@ -1114,16 +1116,16 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:20.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; [self releaseCloudKitFetchHold]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRPCFetchAndProcessWhileCloudKitErroring { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); [self.keychainZone failNextFetchWith:[[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorRequestRateLimited @@ -1146,8 +1148,8 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:20.0]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectations:@[callbackOccurs] timeout:20]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRPCFetchAndProcessWhileInWaitForTLK { @@ -1155,7 +1157,7 @@ [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; [self.ckksControl rpcFetchAndProcessChanges:nil reply:^(NSError * _Nullable error) { @@ -1168,8 +1170,8 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:20.0]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectations:@[callbackOccurs] timeout:20]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRPCTLKMissingWhenMissing { @@ -1178,7 +1180,7 @@ [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; @@ -1187,9 +1189,9 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:5.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRPCTLKMissingWhenFound { @@ -1199,7 +1201,7 @@ [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready''"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready''"); XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; @@ -1208,9 +1210,9 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:5.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRPCKnownBadStateWhenTLKsMissing { @@ -1219,7 +1221,7 @@ [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; @@ -1228,9 +1230,9 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:5.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRPCKnownBadStateWhenInWaitForUnlock { @@ -1240,7 +1242,7 @@ [self startCKKSSubsystem]; // Wait for the key hierarchy state machine to get stuck waiting for the unlock dependency. No uploads should occur. - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:8*NSEC_PER_SEC], @"Key state should get stuck in waitforunlock"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], @"Key state should get stuck in waitforunlock"); XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; @@ -1249,9 +1251,9 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:5.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } @@ -1262,7 +1264,7 @@ [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready''"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready''"); XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; @@ -1271,9 +1273,9 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:5.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRpcStatus { @@ -1282,8 +1284,8 @@ [self startCKKSSubsystem]; // Let things shake themselves out. - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should return to 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should return to 'ready'"); [self waitForCKModifications]; XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; @@ -1300,7 +1302,7 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:5.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; } - (void)testRpcStatusWaitsForAccountDetermination { @@ -1327,7 +1329,7 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:8.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; } - (void)testRpcStatusIsFastDuringError { @@ -1337,7 +1339,7 @@ // Let CKKS come up; it should enter 'error' [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateError] wait:8*NSEC_PER_SEC], "CKKS entered 'error'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateError] wait:20*NSEC_PER_SEC], "CKKS entered 'error'"); // Fire off the status RPC; it should return immediately XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; @@ -1354,7 +1356,7 @@ [callbackOccurs fulfill]; }]; - [self waitForExpectations:@[callbackOccurs] timeout:1.0]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; } @end diff --git a/keychain/ckks/tests/CKKSTests+Coalesce.m b/keychain/ckks/tests/CKKSTests+Coalesce.m index 7ee14611..b4964441 100644 --- a/keychain/ckks/tests/CKKSTests+Coalesce.m +++ b/keychain/ckks/tests/CKKSTests+Coalesce.m @@ -48,7 +48,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testCoalesceAddModifyModifyItem { @@ -64,7 +64,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testCoalesceAddModifyDeleteItem { @@ -79,7 +79,7 @@ // We expect no uploads. [self startCKKSSubsystem]; [self.keychainView waitUntilAllOperationsAreFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testCoalesceDeleteAddItem { @@ -92,7 +92,7 @@ // We expect a single record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Okay, now the delete/add. Note that this is not a coalescing operation, since the new item @@ -112,7 +112,7 @@ checkModifiedRecord:nil runAfterModification:nil]; self.keychainView.operationQueue.suspended = NO; - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } @end diff --git a/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m b/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m index 9d302e19..d89f20a1 100644 --- a/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m +++ b/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m @@ -99,7 +99,7 @@ // And ensure that global queries do. [self expectCKFetch]; [self fetchCurrentPointerExpectingError:true]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); SecResetLocalSecuritydXPCFakeEntitlements(); } @@ -171,7 +171,7 @@ [setCurrentExpectation fulfill]; }); TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectations:@[keychainChanged] timeout:8]; [self waitForCKModifications]; @@ -252,7 +252,7 @@ XCTAssertNil(error, "No error setting current item"); [otherSetCurrentExpectation fulfill]; }); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectations:@[keychainChanged] timeout:8]; [self waitForCKModifications]; @@ -279,7 +279,7 @@ [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); [self fetchCurrentPointerExpectingError:false]; @@ -299,7 +299,7 @@ [setCurrentExpectation fulfill]; }); TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self waitForExpectationsWithTimeout:8.0 handler:nil]; @@ -320,7 +320,7 @@ [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); [self fetchCurrentPointerExpectingError:false]; @@ -370,11 +370,10 @@ [setCurrentExpectation fulfill]; }); TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices); - OCMVerifyAllWithDelay(self.mockDatabase, 8); - [self waitForExpectations:@[keychainChanged] timeout:8]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; - [self waitForExpectationsWithTimeout:8.0 handler:nil]; + [self waitForExpectations:@[setCurrentExpectation] timeout:8]; SecResetLocalSecuritydXPCFakeEntitlements(); } @@ -391,7 +390,7 @@ // Entirely signed out of iCloud. all current record writes should fail. self.accountStatus = CKAccountStatusNoAccount; - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; self.silentFetchesAllowed = false; @@ -464,7 +463,7 @@ }), @"_SecItemAddAndNotifyOnSync succeeded"); // We don't expect this callback to fire, so give it a second or so - [self waitForExpectations:@[syncExpectation] timeout:2.0]; + [self waitForExpectations:@[syncExpectation] timeout:20]; NSDictionary* result = CFBridgingRelease(cfresult); @@ -486,7 +485,7 @@ [setCurrentExpectation fulfill]; }); - [self waitForExpectations:@[setCurrentExpectation] timeout:8.0]; + [self waitForExpectations:@[setCurrentExpectation] timeout:20]; SecResetLocalSecuritydXPCFakeEntitlements(); } @@ -741,7 +740,7 @@ XCTAssertNotNil(error, "Should have received an error setting current item (because of conflict)"); [setCurrentExpectation fulfill]; }); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self waitForExpectationsWithTimeout:8.0 handler:nil]; @@ -812,7 +811,7 @@ XCTAssertNil(error, "No error setting current item"); [setCurrentExpectation fulfill]; }); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectationsWithTimeout:8.0 handler:nil]; [self waitForCKModifications]; @@ -894,7 +893,7 @@ XCTAssertNotNil(error, "Error setting current item when the write fails"); [setCurrentExpectation fulfill]; }); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectationsWithTimeout:8.0 handler:nil]; @@ -962,7 +961,7 @@ XCTAssertNil(error, "No error setting current item"); [setCurrentExpectation fulfill]; }); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self waitForExpectationsWithTimeout:8.0 handler:nil]; @@ -975,7 +974,7 @@ (id)kSecAttrAccount:@"testaccount", (id)kSecAttrSynchronizable : (id)kCFBooleanTrue, }), "Should receive no error deleting item"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now, fetch the current pointer: we should get an error [self fetchCurrentPointerExpectingError:false]; @@ -1017,7 +1016,7 @@ XCTAssertNil(error, "No error setting current item"); [setCurrentExpectation fulfill]; }); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self waitForExpectationsWithTimeout:8.0 handler:nil]; @@ -1037,7 +1036,7 @@ [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready"); [self.keychainView waitUntilAllOperationsAreFinished]; // Before CKKS can add the item, shove a conflicting one into CloudKit @@ -1116,7 +1115,7 @@ [setCurrentExpectation fulfill]; }); - [self waitForExpectations:@[setCurrentExpectation] timeout:8.0]; + [self waitForExpectations:@[setCurrentExpectation] timeout:20]; // Now, release the incoming queue processing and retry the failure [self.operationQueue addOperation:self.keychainView.holdIncomingQueueOperation]; @@ -1132,7 +1131,7 @@ [setCurrentExpectation fulfill]; }); - [self waitForExpectations:@[setCurrentExpectation] timeout:8.0]; + [self waitForExpectations:@[setCurrentExpectation] timeout:20]; // Reissue a fetch and find the new persistent ref and sha1 for the item at this UUID [self.keychainView waitForFetchAndIncomingQueueProcessing]; @@ -1173,7 +1172,7 @@ [newSetCurrentExpectation fulfill]; }); - [self waitForExpectations:@[newSetCurrentExpectation] timeout:8.0]; + [self waitForExpectations:@[newSetCurrentExpectation] timeout:20]; SecResetLocalSecuritydXPCFakeEntitlements(); } diff --git a/keychain/ckks/tests/CKKSTests.m b/keychain/ckks/tests/CKKSTests.m index f19886a2..ad6f2966 100644 --- a/keychain/ckks/tests/CKKSTests.m +++ b/keychain/ckks/tests/CKKSTests.m @@ -51,6 +51,7 @@ #import "keychain/ckks/CKKSAnalytics.h" #import "keychain/ckks/CKKSHealKeyHierarchyOperation.h" #import "keychain/ckks/CKKSZoneChangeFetcher.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #import "keychain/ckks/tests/MockCloudKit.h" @@ -69,7 +70,7 @@ [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:4*NSEC_PER_SEC], @"Key state should have arrived at ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should have arrived at ready"); } - (void)testAddItem { @@ -79,11 +80,11 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should have arrived at ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should have arrived at ready"); [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testActiveTLKS { @@ -96,7 +97,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); NSDictionary* tlks = [[CKKSViewManager manager] activeTLKs]; @@ -111,15 +112,15 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me-2"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me-3"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testAddItemWithoutUUID { @@ -140,7 +141,7 @@ // We then expect an upload of the added item [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testModifyItem { @@ -153,12 +154,12 @@ // We expect a single record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And then modified. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self updateGenericPassword: @"otherdata" account:account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testModifyItemImmediately { @@ -172,7 +173,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"data"]]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Right now, the write in CloudKit is pending. Make the local modification... [self updateGenericPassword: @"otherdata" account:account]; @@ -182,7 +183,7 @@ checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"otherdata"]]; [self releaseCloudKitModificationHold]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testModifyItemPrimaryKey { @@ -195,12 +196,12 @@ // We expect a single record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And then modified. Since we're changing the "primary key", we expect to delete the old record and upload a new one. [self expectCKModifyItemRecords:1 deletedRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID checkItem:nil]; [self updateAccountOfGenericPassword: @"new-account-delete-me" account:account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testModifyItemDuringReencrypt { @@ -214,7 +215,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"data"]]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Right now, the write in CloudKit is pending. Make the local modification... [self updateGenericPassword: @"otherdata" account:account]; @@ -247,7 +248,7 @@ [self.operationQueue addOperation: self.keychainView.holdOutgoingQueueOperation]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self.keychainView waitUntilAllOperationsAreFinished]; [self waitForCKModifications]; } @@ -263,7 +264,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"data"]]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Right now, the write in CloudKit is pending. Make the local modification... [self updateGenericPassword: @"otherdata" account:account]; @@ -288,7 +289,7 @@ [self updateGenericPassword: @"third" account:account]; // Item should upload. - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Run the reencrypt items operation to completion. [self.operationQueue addOperation: self.keychainView.holdReencryptOutgoingItemsOperation]; @@ -309,7 +310,7 @@ [self failNextCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Right now, the write in CloudKit is pending. Make the local modification... [self updateGenericPassword: @"otherdata" account:account]; @@ -322,7 +323,7 @@ [self releaseCloudKitModificationHold]; // Item should upload. - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self.keychainView waitUntilAllOperationsAreFinished]; [self waitForCKModifications]; @@ -363,7 +364,7 @@ self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testOutgoingQueueRecoverFromNetworkFailure { @@ -379,7 +380,7 @@ [self failNextCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID blockAfterReject:nil withError:greyMode]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And then schedule the retried update [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID @@ -388,7 +389,7 @@ // The cloudkit operation finishes, letting the next OQO proceed (and set up uploading the new item) [self releaseCloudKitModificationHold]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self.keychainView waitUntilAllOperationsAreFinished]; [self waitForCKModifications]; @@ -402,12 +403,12 @@ // We expect a single record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // We expect a single record to be deleted. [self expectCKDeleteItemRecords: 1 zoneID:self.keychainZoneID]; [self deleteGenericPassword:@"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDeleteItemImmediatelyAfterModify { @@ -419,7 +420,7 @@ // We expect a single record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now, hold the modify [self holdCloudKitModifications]; @@ -429,7 +430,7 @@ checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"otherdata"]]; [self updateGenericPassword: @"otherdata" account:account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Right now, the write in CloudKit is pending. Make the local deletion... [self deleteGenericPassword:account]; @@ -438,7 +439,7 @@ [self expectCKDeleteItemRecords:1 zoneID:self.keychainZoneID]; [self releaseCloudKitModificationHold]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testDeleteItemAfterFetchAfterModify { @@ -450,7 +451,7 @@ // We expect a single record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now, hold the modify //[self holdCloudKitModifications]; @@ -460,7 +461,7 @@ checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"otherdata"]]; [self updateGenericPassword: @"otherdata" account:account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Right now, the write in CloudKit is pending. Place a hold on outgoing queue processing // Place a hold on processing the outgoing queue. @@ -482,7 +483,7 @@ [self.operationQueue addOperation:blockOutgoing]; [outgoingQueueOperation waitUntilFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } @@ -572,7 +573,7 @@ // Trigger a notification (with hilariously fake data) [self.keychainView notifyZoneChange:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 6); + OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(errSecSuccess, SecItemCopyMatching((__bridge CFDictionaryRef) query, &item), "item should exist now"); [self waitForCKModifications]; @@ -778,7 +779,7 @@ // Allow the outgoing queue operation to proceed [self.operationQueue addOperation:self.keychainView.holdOutgoingQueueOperation]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self.keychainView waitUntilAllOperationsAreFinished]; [self checkGenericPassword:@"data" account:@"account-delete-me"]; @@ -848,7 +849,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self updateGenericPassword:@"different password" account:@"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; CKRecord* newRecord = self.keychainZone.currentDatabase[recordID]; @@ -918,7 +919,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self updateGenericPassword:@"different password" account:@"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; CKRecord* newRecord = self.keychainZone.currentDatabase[recordID]; @@ -938,7 +939,7 @@ [self expectCKModifyItemRecords: SecCKKSOutgoingQueueItemsAtOnce currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self expectCKModifyItemRecords: 50 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; - OCMVerifyAllWithDelay(self.mockDatabase, 160); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testUploadInitialKeyHierarchy { @@ -948,7 +949,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testUploadInitialKeyHierarchyAfterLockedStart { @@ -959,7 +960,7 @@ [self startCKKSSubsystem]; // Wait for the key hierarchy state machine to get stuck waiting for the unlock dependency. No uploads should occur. - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:8*NSEC_PER_SEC], @"Key state should get stuck in waitforunlock"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], @"Key state should get stuck in waitforunlock"); // After unlock, the key hierarchy should be created. [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; @@ -967,13 +968,13 @@ self.aksLockState = false; [self.lockStateTracker recheck]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // We expect a single class C record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testLockImmediatelyAfterUploadingInitialKeyHierarchy { @@ -996,8 +997,8 @@ [self startCKKSSubsystem]; // Should enter 'ready' - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now, lock and allow fetches again self.aksLockState = true; @@ -1007,20 +1008,20 @@ CKKSResultOperation* op = [self.keychainView.zoneChangeFetcher requestSuccessfulFetch:CKKSFetchBecauseTesting]; [op waitUntilFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Wait for CKKS to shake itself out... [self.keychainView waitForOperationsOfClass:[CKKSProcessReceivedKeysOperation class]]; // Should be in ReadyPendingUnlock - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); // We expect a single class C record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testReceiveKeyHierarchyAfterLockedStart { @@ -1031,7 +1032,7 @@ [self startCKKSSubsystem]; // Wait for the key hierarchy state machine to get stuck waiting for the unlock dependency. No uploads should occur. - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetchComplete] wait:8*NSEC_PER_SEC], @"Key state should get stuck in fetchcomplete"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetchComplete] wait:20*NSEC_PER_SEC], @"Key state should get stuck in fetchcomplete"); // Now, another device comes along and creates the hierarchy; we download it; and it and sends us the TLK [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -1049,7 +1050,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testLoadKeyHierarchyAfterLockedStart { @@ -1062,7 +1063,7 @@ [self startCKKSSubsystem]; // Wait for the key hierarchy state machine to get stuck waiting for the unlock dependency. No uploads should occur. - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); self.aksLockState = false; [self.lockStateTracker recheck]; @@ -1071,7 +1072,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testUploadAndUseKeyHierarchy { @@ -1089,14 +1090,14 @@ CFTypeRef item = NULL; XCTAssertEqual(errSecItemNotFound, SecItemCopyMatching((__bridge CFDictionaryRef) query, &item), "item should not exist"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // We expect a single class C record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // now, expect a single class A record to be uploaded [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -1109,7 +1110,7 @@ (id)kSecAttrSynchronizable : (id)kCFBooleanTrue, (id)kSecValueData : (id) [@"asdf" dataUsingEncoding:NSUTF8StringEncoding], }, NULL), @"Adding class A item"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testUploadInitialKeyHierarchyTriggersBackup { @@ -1122,7 +1123,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); OCMVerifyAllWithDelay(self.mockCKKSViewManager, 10); } @@ -1138,11 +1139,11 @@ [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*NSEC_PER_SEC], @"Key state should become 'resetzone'"); // But then, it'll fire off the reset and reach 'ready' - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); // And the zone should have been cleared and re-made XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); @@ -1168,11 +1169,11 @@ [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*NSEC_PER_SEC], @"Key state should become 'resetzone'"); // But then, it'll fire off the reset and reach 'ready' - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); // And the zone should have been cleared and re-made XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); @@ -1205,11 +1206,11 @@ [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*NSEC_PER_SEC], @"Key state should become 'resetzone'"); // But then, it'll fire off the reset and reach 'ready' - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); // And the zone should have been cleared and re-made XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); @@ -1234,7 +1235,7 @@ self.keychainZone.flag = true; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false"); } @@ -1250,7 +1251,7 @@ self.keychainZone.flag = true; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false"); // And ensure it doesn't go on to 'reset' @@ -1278,11 +1279,11 @@ self.keychainZone.flag = true; [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*NSEC_PER_SEC], @"Key state should become 'resetzone'"); // Then we should reset. - OCMVerifyAllWithDelay(self.mockDatabase, 8); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); // And the zone should have been cleared and re-made XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); @@ -1299,9 +1300,9 @@ [self startCKKSSubsystem]; // The CKKS subsystem should only upload its TLK share - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], "Key state should have become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Verify that there are three local keys, and three local current key records __weak __typeof(self) weakSelf = self; @@ -1331,7 +1332,7 @@ self.keychainZone.flag = true; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:5*NSEC_PER_SEC], "Key state should have become waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should have become waitfortlk"); // Now, save the TLK to the keychain (to simulate it coming in later via SOS). We'll create a TLK share for ourselves. [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; @@ -1339,12 +1340,12 @@ // Wait for the key hierarchy to sort itself out, to make it easier on this test; see testOnboardOldItemsWithExistingKeyHierarchy for the other test. // The CKKS subsystem should write its TLK share, but nothing else - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], "Key state should have become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready"); // We expect a single record to be uploaded for each key class [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; [self addGenericPassword:@"asdf" @@ -1353,27 +1354,24 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertTrue(self.keychainZone.flag, "Keychain zone shouldn't have been reset"); } - (void)testAcceptExistingKeyHierarchyDespiteLocked { // Test starts with no keys in CKKS database, but one in our fake CloudKit. // Test also begins with the TLK having arrived in the local keychain (via SOS) - // However, the CKKSKeychainView's "_onqueueWithAccountKeysCheckTLK" method should return a keychain error the first time through, indicating that the keybag is locked + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; [self saveTLKMaterialToKeychain:self.keychainZoneID]; self.aksLockState = true; [self.lockStateTracker recheck]; - id partialKVMock = OCMPartialMock(self.keychainView); - OCMExpect([partialKVMock _onqueueWithAccountKeysCheckTLK: [OCMArg any] error: [OCMArg setTo:[[NSError alloc] initWithDomain:@"securityd" code:errSecInteractionNotAllowed userInfo:nil]]]).andReturn(false); - // Spin up CKKS subsystem. [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(partialKVMock, 4); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], "Key state should have become waitforunlock"); // CKKS will give itself a TLK Share [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; @@ -1382,8 +1380,8 @@ self.aksLockState = false; [self.lockStateTracker recheck]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], "Key state should have become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 4); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready"); // Verify that there are three local keys, and three local current key records __weak __typeof(self) weakSelf = self; @@ -1403,8 +1401,6 @@ return false; }]; - - [partialKVMock stopMocking]; } - (void)testReceiveClassCWhileALocked { @@ -1413,7 +1409,7 @@ [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); [self.keychainView waitForFetchAndIncomingQueueProcessing]; [self findGenericPassword:@"classCItem" expecting:errSecItemNotFound]; @@ -1433,7 +1429,7 @@ }]; // And ensure we end up back in 'readypendingunlock': we have the keys, we're just locked now [self.keychainView waitForOperationsOfClass:[CKKSProcessReceivedKeysOperation class]]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"classCItem" key:self.keychainZoneKeys.classC]]; [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-FFFF-FFFF-FFFF-5A507ACB2D85" withAccount:@"classAItem" key:self.keychainZoneKeys.classA]]; @@ -1461,7 +1457,7 @@ [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); // 'Lock' the keybag self.aksLockState = true; @@ -1470,12 +1466,12 @@ [self.keychainView halt]; self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); self.aksLockState = false; [self.lockStateTracker recheck]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); } - (void)testExternalKeyRoll { @@ -1488,7 +1484,7 @@ [self startCKKSSubsystem]; // The CKKS subsystem should not try to write anything to the CloudKit database. - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); __weak __typeof(self) weakSelf = self; @@ -1497,7 +1493,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -1516,7 +1512,7 @@ return true; }]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); // Verify that there are six local keys, and three local current key records [self.keychainView dispatchSync: ^bool{ @@ -1555,7 +1551,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me-rolled-key"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testAcceptKeyConflictAndUploadReencryptedItem { @@ -1572,7 +1568,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -1584,7 +1580,7 @@ [self expectCKAtomicModifyItemRecordsUpdateFailure: self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me-rolled-key"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under rolled class C key in hierarchy"]]; @@ -1592,7 +1588,7 @@ [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; [self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testAcceptKeyConflictAndUploadReencryptedItems { @@ -1610,7 +1606,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -1623,7 +1619,7 @@ [self expectCKAtomicModifyItemRecordsUpdateFailure: self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me-rolled-key"]; [self addGenericPassword: @"data" account: @"account-delete-me-rolled-key-2"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords:2 currentKeyPointerRecords:1 zoneID:self.keychainZoneID checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under rolled class C key in hierarchy"]]; @@ -1632,7 +1628,7 @@ [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; [self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromRequestKeyRefetchWithoutRolling { @@ -1646,7 +1642,7 @@ // Items should upload. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -1660,8 +1656,8 @@ return true; }]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], "Key state should have returned to ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have returned to ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromIncrementedCurrentKeyPointerEtag { @@ -1677,7 +1673,7 @@ // Items should upload. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -1694,7 +1690,7 @@ [self expectCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID]; [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me-2"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverMultipleItemsFromIncrementedCurrentKeyPointerEtag { @@ -1709,7 +1705,7 @@ // Items should upload. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -1733,7 +1729,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me-3"]; [self.operationQueue addOperation: self.keychainView.holdOutgoingQueueOperation]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testOnboardOldItemsCreatingKeyHierarchy { @@ -1756,7 +1752,7 @@ [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testOnboardOldItemsWithExistingKeyHierarchy { @@ -1766,7 +1762,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me"]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testOnboardOldItemsWithExistingKeyHierarchyExtantTLK { @@ -1790,7 +1786,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testOnboardOldItemsWithExistingKeyHierarchyLateTLK { @@ -1811,7 +1807,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:5*NSEC_PER_SEC], "Key state should have become waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should have become waitfortlk"); // Now, save the TLK to the keychain (to simulate it coming in via SOS). [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; @@ -1820,7 +1816,7 @@ // We expect a single record to be uploaded. [self expectCKModifyItemRecords: 2 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertTrue(self.keychainZone.flag, "Keychain zone shouldn't have been reset"); } @@ -1850,7 +1846,7 @@ [self startCKKSSubsystem]; // Wait for uploads to happen - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // One TLK share record XCTAssertEqual(self.keychainZone.currentDatabase.count, SYSTEM_DB_RECORD_COUNT+passwordCount+1, "Have SYSTEM_DB_RECORD_COUNT+passwordCount+1 objects in cloudkit"); @@ -2001,7 +1997,7 @@ [self expectCKModifyItemRecords:2 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self.keychainView waitForFetchAndIncomingQueueProcessing]; @@ -2039,7 +2035,7 @@ [self holdCloudKitModifications]; [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; [self addGenericPassword:@"data" account:@"third"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // For the fourth, add a new record but prevent incoming queue processing self.keychainView.holdIncomingQueueOperation = [CKKSResultOperation named:@"hold-incoming" withBlock:^{}]; @@ -2058,7 +2054,7 @@ [self releaseCloudKitModificationHold]; [self.operationQueue addOperation:self.keychainView.holdIncomingQueueOperation]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; // And ensure that all four items are present again @@ -2081,7 +2077,7 @@ [self startCKKSSubsystem]; // Wait for uploads to happen - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Local resyncs shouldn't fetch clouds. @@ -2120,7 +2116,7 @@ [self startCKKSSubsystem]; // Wait for uploads to happen - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // o no @@ -2175,7 +2171,7 @@ // We expect a single record to be uploaded to the 'keychain' view [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // We expect a single record to be uploaded to the 'atv' view [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:appleTVZoneID]; @@ -2185,7 +2181,7 @@ access:(id)kSecAttrAccessibleAfterFirstUnlock expecting:errSecSuccess message:@"AppleTV view-hinted object"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); OCMVerifyAllWithDelay(self.mockCKKSViewManager, 10); } @@ -2199,7 +2195,7 @@ // We expect a single record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Bring up a new zone: we expect a key hierarchy and an item. [self.injectedManager findOrCreateView:(id)kSecAttrViewHintAppleTV]; @@ -2213,17 +2209,17 @@ access:(id)kSecAttrAccessibleAfterFirstUnlock expecting:errSecSuccess message:@"AppleTV view-hinted object"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // We expect a single record to be deleted from the ATV zone [self expectCKDeleteItemRecords: 1 zoneID:appleTVZoneID]; [self deleteGenericPassword:@"tvaccount"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now we expect a single record to be deleted from the test zone [self expectCKDeleteItemRecords: 1 zoneID:self.keychainZoneID]; [self deleteGenericPassword:@"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRestartWithoutRefetch { @@ -2235,7 +2231,7 @@ [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Tear down the CKKS object and disallow fetches [self.keychainView halt]; @@ -2243,7 +2239,7 @@ self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Okay, cool, rad, now let's set the date to be very long ago and check that there's positively a fetch [self.keychainView halt]; @@ -2265,7 +2261,7 @@ [self expectCKFetch]; self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromZoneCreationFailure { @@ -2280,12 +2276,12 @@ [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertNil(self.zones[self.keychainZoneID].creationError, "Creation error was unset (and so CKKS probably dealt with the error"); } @@ -2301,12 +2297,12 @@ [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertNil(self.zones[self.keychainZoneID].subscriptionError, "Subscription error was unset (and so CKKS probably dealt with the error"); } @@ -2325,12 +2321,12 @@ [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertFalse(self.zones[self.keychainZoneID].flag, "Zone flag was reset"); XCTAssertNil(self.zones[self.keychainZoneID].subscriptionError, "Subscription error was unset (and so CKKS probably dealt with the error"); @@ -2354,11 +2350,11 @@ [self startCKKSSubsystem]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // CKKS should recreate the syncable TLK. [self checkNSyncableTLKsInKeychain: 1]; @@ -2386,11 +2382,11 @@ self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // CKKS should recreate the syncable TLK. [self checkNSyncableTLKsInKeychain: 1]; @@ -2409,11 +2405,11 @@ [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // A network failure creating new TLKs shouldn't delete the 'failed' syncable one. [self checkNSyncableTLKsInKeychain: 2]; @@ -2431,7 +2427,7 @@ // The first TLK write should fail, and then our fake TLKs should be there in CloudKit. // It shouldn't write anything back up to CloudKit. - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now the TLKs arrive from the other device... [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; @@ -2440,7 +2436,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // A race failure creating new TLKs should delete the old syncable one. [self checkNSyncableTLKsInKeychain: 1]; @@ -2467,7 +2463,7 @@ [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromNoCurrentKeyPointers { @@ -2488,9 +2484,9 @@ // The CKKS subsystem should figure out the issue, and fix it. [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromBadChangeTag { @@ -2522,7 +2518,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 16); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // CKKS should then happily use the keys in CloudKit [self createClassCItemAndWaitForUpload:self.keychainZoneID account:@"account-delete-me"]; @@ -2541,7 +2537,7 @@ checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self.keychainView waitUntilAllOperationsAreFinished]; @@ -2565,7 +2561,7 @@ checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"datadata" account: @"account-no-keys"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // We expect a single class A record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID @@ -2576,7 +2572,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromDeletedKeysReceive { @@ -2619,9 +2615,9 @@ [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have returned to ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have returned to ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; CKRecord* ckr = [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"account0"]; @@ -2643,7 +2639,7 @@ [self.keychainView waitForFetchAndIncomingQueueProcessing]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should return to 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should return to 'ready'"); [self.keychainView waitForFetchAndIncomingQueueProcessing]; // Do this again, to allow for non-atomic key state machinery switching @@ -2667,9 +2663,9 @@ [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have returned to ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have returned to ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; @@ -2708,9 +2704,9 @@ [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have returned to ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have returned to ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; @@ -2764,9 +2760,9 @@ // The CKKS subsystem should figure out the issue, and fix it (while uploading itself a TLK Share) [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromIncorrectCurrentTLKPointer { @@ -2799,9 +2795,9 @@ // The CKKS subsystem should figure out the issue, and fix it (while uploading itself a TLK Share) [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:80*NSEC_PER_SEC], "Key state should have become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; XCTAssertEqualObjects(self.keychainZoneKeys.currentTLKPointer, @@ -2834,7 +2830,7 @@ // We expect a single record to be uploaded [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 12); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; [self addGenericPassword:@"asdf" @@ -2843,7 +2839,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromCloudKitFetchNetworkFailAfterReady { @@ -2853,7 +2849,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered ready"); XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateReady, "CKKS entered ready"); // Network is unavailable @@ -2888,7 +2884,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitializing] wait:8*NSEC_PER_SEC], "CKKS entered initializing"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitializing] wait:20*NSEC_PER_SEC], "CKKS entered initializing"); XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateInitializing, "CKKS entered initializing"); // Now, save the TLK to the keychain (to simulate it coming in later via SOS). @@ -2902,11 +2898,40 @@ [self.reachabilityTracker recheck]; [self.keychainView waitUntilAllOperationsAreFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self findGenericPassword:@"account-delete-me" expecting:errSecSuccess]; } +- (void)testWaitAfterCloudKitNetworkFailDuringOutgoingQueueOperation { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered ready"); + + // Network is now unavailable + self.reachabilityFlags = 0; + [self.reachabilityTracker recheck]; + + NSError* noNetwork = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorNetworkUnavailable userInfo:@{}]; + [self failNextCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID blockAfterReject:nil withError:noNetwork]; + [self addGenericPassword: @"data" account: @"account-delete-me"]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + sleep(2); + + // Once network is available again, the write should happen + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + + self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; + [self.reachabilityTracker recheck]; + + [self findGenericPassword:@"account-delete-me" expecting:errSecSuccess]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} - (void)testRecoverFromCloudKitFetchFailWithDelay { // Test starts with nothing in database, but one in our fake CloudKit. @@ -2934,7 +2959,7 @@ // We expect a single record to be uploaded [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromCloudKitOldChangeToken { @@ -2951,7 +2976,7 @@ // We expect a single record to be uploaded [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Delete all old database states, to destroy the change tag validity [self.keychainZone.pastDatabases removeAllObjects]; @@ -2964,7 +2989,7 @@ // Trigger a fake change notification [self.keychainView notifyZoneChange:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And check that a new upload happens just fine. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -2974,7 +2999,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromCloudKitUnknownDeviceStateRecord { @@ -3020,7 +3045,7 @@ checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromCloudKitUnknownItemRecord { @@ -3045,7 +3070,7 @@ // Expect a failed upload when we modify the item [self expectCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID]; [self updateGenericPassword:@"never seen again" account:@"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self.keychainView waitUntilAllOperationsAreFinished]; @@ -3067,7 +3092,7 @@ // We expect a single record to be uploaded [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // The first CKRecordZoneChanges should fail with a 'CKErrorUserDeletedZone' error. This will cause a local reset, ending up with zone re-creation. self.zones[self.keychainZoneID] = nil; // delete the zone @@ -3079,7 +3104,7 @@ [self.keychainView notifyZoneChange:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And check that a new upload occurs. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -3090,7 +3115,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromCloudKitZoneNotFoundWithoutZoneDeletion { @@ -3108,9 +3133,9 @@ // We expect a single record to be uploaded [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS should enter 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS should enter 'ready'"); [self waitForCKModifications]; [self.keychainView waitForOperationsOfClass:[CKKSScanLocalItemsOperation class]]; @@ -3123,7 +3148,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self.keychainView notifyZoneChange:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 80); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // And check that a new upload occurs. @@ -3135,7 +3160,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)testRecoverFromCloudKitZoneNotFoundFetchBeforeSigninOccurs { @@ -3152,13 +3177,13 @@ [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS should enter 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS should enter 'ready'"); // We expect a single record to be uploaded [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // The fetch should have come back by now [self waitForExpectations: @[fetchReturns] timeout:5]; @@ -3167,13 +3192,13 @@ - (void)testNoCloudKitAccount { // Test starts with nothing in database and the user logged out of CloudKit. We expect no CKKS operations. self.accountStatus = CKAccountStatusNoAccount; - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; self.silentFetchesAllowed = false; [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self addGenericPassword: @"data" account: @"account-delete-me"]; [self.keychainView waitUntilAllOperationsAreFinished]; @@ -3187,7 +3212,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me-3"]; [self.keychainView waitUntilAllOperationsAreFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Test that there are no items in the database (since we never logged in) [self checkNoCKKSData: self.keychainView]; @@ -3195,7 +3220,7 @@ - (void)testSACloudKitAccount { // Test starts with nothing in database and the user logged into CloudKit and in circle, but the account is not HSA2. - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; self.accountStatus = CKAccountStatusAvailable; @@ -3209,22 +3234,22 @@ XCTAssertEqualObjects(self.accountStateTracker.currentAccountError.domain, CKKSErrorDomain, "Account tracker error should be in CKKSErrorDomain"); XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSNotHSA2, "Account tracker error should be upset about HSA2"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // There should be no uploads, even when we save keychain items and enter/exit circle [self addGenericPassword: @"data" account: @"account-delete-me"]; [self.keychainView waitUntilAllOperationsAreFinished]; - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; [self addGenericPassword: @"data" account: @"account-delete-me-2"]; - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; [self addGenericPassword: @"data" account: @"account-delete-me-3"]; [self.keychainView waitUntilAllOperationsAreFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Test that there are no items in the database (since we never were in an HSA2 account) [self checkNoCKKSData: self.keychainView]; @@ -3232,7 +3257,7 @@ - (void)testNoCircle { // Test starts with nothing in database and the user logged into CloudKit, but out of Circle. - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; self.accountStatus = CKAccountStatusAvailable; @@ -3245,7 +3270,7 @@ XCTAssertEqualObjects(self.accountStateTracker.currentAccountError.domain, (__bridge NSString*)kSOSErrorDomain, "Account tracker error should be in SOSErrorDomain"); XCTAssertEqual(self.accountStateTracker.currentAccountError.code, kSOSErrorNotInCircle, "Account tracker error should be upset about out-of-circle"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self addGenericPassword: @"data" account: @"account-delete-me"]; [self.keychainView waitUntilAllOperationsAreFinished]; @@ -3259,7 +3284,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me-3"]; [self.keychainView waitUntilAllOperationsAreFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Test that there are no items in the database (since we never logged in) [self checkNoCKKSData: self.keychainView]; @@ -3268,20 +3293,20 @@ - (void)testCloudKitLogin { // Test starts with nothing in database and the user logged out of CloudKit. We expect no CKKS operations. self.accountStatus = CKAccountStatusNoAccount; - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; // Before we inform CKKS of its account state.... - XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK shouldn't know the account state"); + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK shouldn't know the account state"); [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.loggedOut wait:500*NSEC_PER_MSEC], "Should have been told of a 'logout' event on startup"); XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event shouldn't have happened"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); [self.keychainView waitUntilAllOperationsAreFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); XCTAssertEqualObjects(self.accountStateTracker.currentAccountError.domain, CKKSErrorDomain, "Account tracker error should be in CKKSErrorDomain"); @@ -3297,28 +3322,28 @@ // No writes yet, since we're not in circle [self.keychainView waitUntilAllOperationsAreFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // We expect some sort of TLK/key hierarchy upload once we are notified of entering the circle. [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // We expect a single class C record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; } @@ -3326,11 +3351,11 @@ // Test starts with nothing in database. We expect some sort of TLK/key hierarchy upload. [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK shouldn't know the account state"); + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK shouldn't know the account state"); [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -3345,7 +3370,7 @@ // simulate a cloudkit logout and NSNotification callback self.accountStatus = CKAccountStatusNoAccount; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); @@ -3355,7 +3380,7 @@ // Test that there are no items in the database after logout XCTAssertEqual(0, [self.keychainView.loggedOut wait:2000*NSEC_PER_MSEC], "Should have been told of a 'logout'"); XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); [self checkNoCKKSData: self.keychainView]; // There should be no further uploads, even when we save keychain items @@ -3364,7 +3389,7 @@ [self.keychainView waitUntilAllOperationsAreFinished]; OCMVerifyAllWithDelay(self.mockDatabase, 20); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered 'logged out'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'logged out'"); // simulate a cloudkit login // We should expect CKKS to re-find the key hierarchy it already uploaded, and then send up the two records we added during the pause @@ -3372,30 +3397,30 @@ self.accountStatus = CKAccountStatusAvailable; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); OCMVerifyAllWithDelay(self.mockDatabase, 20); // Let everything settle... - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); [self waitForCKModifications]; // Logout again self.accountStatus = CKAccountStatusNoAccount; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; // Test that there are no items in the database after logout XCTAssertEqual(0, [self.keychainView.loggedOut wait:2000*NSEC_PER_MSEC], "Should have been told of a 'logout'"); XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); [self checkNoCKKSData: self.keychainView]; // There should be no further uploads, even when we save keychain items @@ -3411,30 +3436,30 @@ self.accountStatus = CKAccountStatusAvailable; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); OCMVerifyAllWithDelay(self.mockDatabase, 20); // Let everything settle... [self.keychainView waitUntilAllOperationsAreFinished]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); // Logout again self.accountStatus = CKAccountStatusNoAccount; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = kSOSCCNotInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; // Test that there are no items in the database after logout XCTAssertEqual(0, [self.keychainView.loggedOut wait:2000*NSEC_PER_MSEC], "Should have been told of a 'logout'"); XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered 'logged out'"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'logged out'"); [self checkNoCKKSData: self.keychainView]; // Force zone into error state @@ -3442,7 +3467,7 @@ self.accountStatus = CKAccountStatusAvailable; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; XCTestExpectation *operationRun = [self expectationWithDescription:@"operation run"]; @@ -3455,24 +3480,24 @@ XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForExpectations: @[operationRun] timeout:5]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); } - (void)testCloudKitLogoutDueToGreyMode { // Test starts with nothing in database. We expect some sort of TLK/key hierarchy upload. [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; - XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK shouldn't know the account state"); + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK shouldn't know the account state"); [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.loggedIn wait:8*NSEC_PER_SEC], "Should have been told of a 'login'"); - XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:10*NSEC_PER_MSEC], "'logout' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.loggedIn wait:20*NSEC_PER_SEC], "Should have been told of a 'login'"); + XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:50*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -3486,11 +3511,11 @@ XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSiCloudGreyMode, "Account tracker error should be upset about grey mode"); // Test that there are no items in the database after logout - XCTAssertEqual(0, [self.keychainView.loggedOut wait:8*NSEC_PER_SEC], "Should have been told of a 'logout'"); - XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:10*NSEC_PER_MSEC], "'login' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.loggedOut wait:20*NSEC_PER_SEC], "Should have been told of a 'logout'"); + XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:50*NSEC_PER_MSEC], "'login' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); [self checkNoCKKSData: self.keychainView]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered 'logged out'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'logged out'"); // There should be no further uploads, even when we save keychain items [self addGenericPassword: @"data" account: @"account-delete-me-2"]; @@ -3516,9 +3541,9 @@ XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); - XCTAssertEqual(0, [self.keychainView.loggedIn wait:8*NSEC_PER_SEC], "Should have been told of a 'login'"); - XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:10*NSEC_PER_MSEC], "'logout' event should be reset"); - XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.loggedIn wait:20*NSEC_PER_SEC], "Should have been told of a 'login'"); + XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:50*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); OCMVerifyAllWithDelay(self.mockDatabase, 20); // And fetching still works! @@ -3526,7 +3551,7 @@ [self.keychainView notifyZoneChange:nil]; [self.keychainView waitForFetchAndIncomingQueueProcessing]; [self findGenericPassword: @"account0" expecting:errSecSuccess]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); } - (void)testCloudKitLoginRace { @@ -3537,14 +3562,14 @@ OCMReject([partialKVMock handleCKLogout]); // note: don't unblock the ck account state object yet... - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; // Add a keychain item, but make sure it doesn't upload yet. [self addGenericPassword: @"data" account: @"account-delete-me"]; [self.keychainView waitUntilAllOperationsAreFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Now that we're here (and handleCKLogout hasn't been called), bring the account up @@ -3560,13 +3585,13 @@ // simulate another NSNotification callback [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Make sure new items upload too [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me-2"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self.keychainView waitUntilAllOperationsAreFinished]; [self waitForCKModifications]; @@ -3575,6 +3600,48 @@ [partialKVMock stopMocking]; } +- (void)testDontLogOutIfBeforeFirstUnlock { + // test starts as if a previously logged-in device has just rebooted + self.aksLockState = true; + self.accountStatus = CKAccountStatusAvailable; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCError error:[NSError errorWithDomain:(__bridge id)kSOSErrorDomain code:kSOSErrorNotReady description:@"fake error: device is locked, so SOS doesn't know if it's in-circle"]]; + + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + + XCTAssertNil(self.accountStateTracker.currentAccountError, "Account tracker error should not yet exist"); + XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSAccountStatusUnknown, "Account tracker error should just be 'no account'"); + + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKKS shouldn't know the account state yet"); + + [self startCKKSSubsystem]; + + XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "Shouldn't have been told of a 'logout' event on startup"); + XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event shouldn't have happened"); + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKKS shouldn't know the account state yet"); + + [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; + + self.aksLockState = false; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + + XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); + + XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); + XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + // We expect a single class C record to be uploaded. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + [self addGenericPassword: @"data" account: @"account-delete-me"]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; +} + - (void)testSyncableItemsAddedWhileLoggedOut { // Test that once CKKS is up and 'logged out', nothing happens when syncable items are added self.accountStatus = CKAccountStatusNoAccount; @@ -3613,7 +3680,7 @@ [self startCKKSSubsystem]; - [self waitForExpectations: @[operationRun] timeout:80]; + [self waitForExpectations: @[operationRun] timeout:20]; } - (void)testCKKSControlBringup { diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m b/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m index 88ff5a8a..0f5ad14b 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m +++ b/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m @@ -56,7 +56,7 @@ [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [mockFixups verify]; [mockFixups stopMocking]; @@ -72,14 +72,14 @@ [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Tear down the CKKS object [self.keychainView halt]; self.keychainView = [[CKKSViewManager manager] restartZone:self.keychainZoneID.zoneName]; [self.keychainView waitForKeyHierarchyReadiness]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [mockFixups verify]; [mockFixups stopMocking]; @@ -95,7 +95,7 @@ [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Add some current item pointers. They don't necessarily need to point to anything... @@ -163,7 +163,7 @@ [self.keychainView waitForKeyHierarchyReadiness]; [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self.keychainView dispatchSync: ^bool { // The zone state entry should be up the most recent fixup level @@ -218,7 +218,7 @@ [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); // Tear down the CKKS object [self.keychainView halt]; @@ -254,11 +254,11 @@ self.keychainView = [[CKKSViewManager manager] restartZone:self.keychainZoneID.zoneName]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForFixupOperation] wait:8*NSEC_PER_SEC], "Key state should become waitforfixup"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForFixupOperation] wait:20*NSEC_PER_SEC], "Key state should become waitforfixup"); [self releaseCloudKitFetchHold]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self.keychainView.lastFixupOperation waitUntilFinished]; XCTAssertNil(self.keychainView.lastFixupOperation.error, "Shouldn't have been any error performing fixup"); @@ -280,13 +280,13 @@ [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; [self addGenericPassword: @"data" account: @"first"]; [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; // Add another record to mock up early CKKS record saving @@ -298,10 +298,10 @@ [secondRecordIDFilled fulfill]; return TRUE; }]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; XCTAssertNotNil(secondRecordID, "Should have filled in secondRecordID"); - XCTAssertEqual(0, [secondRecordIDFilled wait:8*NSEC_PER_SEC], "Should have filled in secondRecordID within enough time"); + XCTAssertEqual(0, [secondRecordIDFilled wait:20*NSEC_PER_SEC], "Should have filled in secondRecordID within enough time"); // Tear down the CKKS object [self.keychainView halt]; @@ -336,9 +336,9 @@ self.accountStatus = CKAccountStatusAvailable; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForFixupOperation] wait:8*NSEC_PER_SEC], "Key state should become waitforfixup"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForFixupOperation] wait:20*NSEC_PER_SEC], "Key state should become waitforfixup"); [self.operationQueue addOperation: self.keychainView.holdFixupOperation]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should become ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); [self.keychainView.lastFixupOperation waitUntilFinished]; XCTAssertNil(self.keychainView.lastFixupOperation.error, "Shouldn't have been any error performing fixup"); diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h index d1559cc8..a2a8c8d6 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h +++ b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h @@ -60,6 +60,7 @@ NS_ASSUME_NONNULL_BEGIN // A single trusted SOSPeer, but without any CKKS keys @property CKKSSOSPeer* remoteSOSOnlyPeer; +@property NSMutableSet* ckksViews; @property NSMutableSet* ckksZones; @property (nullable) NSMutableDictionary* keys; diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m index 1515a7fe..b82da1c0 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m +++ b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m @@ -98,6 +98,7 @@ [super setUp]; self.ckksZones = [NSMutableSet set]; + self.ckksViews = [NSMutableSet set]; self.keys = [[NSMutableDictionary alloc] init]; // Fake out whether class A keys can be loaded from the keychain. @@ -147,6 +148,11 @@ [self.mockCKKSKey stopMocking]; self.mockCKKSKey = nil; + // Make sure the key state machine won't be poked after teardown + for(CKKSKeychainView* view in self.ckksViews) { + [view.pokeKeyStateMachineScheduler cancel]; + } + [super tearDown]; self.keys = nil; @@ -192,7 +198,7 @@ zoneID:zoneID checkItem:[self checkClassCBlock:zoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: account]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)createClassAItemAndWaitForUpload:(CKRecordZoneID*)zoneID account:(NSString*)account { @@ -206,7 +212,7 @@ access:(id)kSecAttrAccessibleWhenUnlocked expecting:errSecSuccess message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 20); } // Helpers to handle 'locked' keychain loading and saving @@ -335,17 +341,21 @@ - (void)putFakeKeyHierarchyInCloudKit: (CKRecordZoneID*)zoneID { ZoneKeys* zonekeys = [self createFakeKeyHierarchy: zoneID oldTLK:nil]; - [self.zones[zoneID] addToZone: zonekeys.tlk zoneID: zoneID]; - [self.zones[zoneID] addToZone: zonekeys.classA zoneID: zoneID]; - [self.zones[zoneID] addToZone: zonekeys.classC zoneID: zoneID]; + FakeCKZone* zone = self.zones[zoneID]; - [self.zones[zoneID] addToZone: zonekeys.currentTLKPointer zoneID: zoneID]; - [self.zones[zoneID] addToZone: zonekeys.currentClassAPointer zoneID: zoneID]; - [self.zones[zoneID] addToZone: zonekeys.currentClassCPointer zoneID: zoneID]; + dispatch_sync(zone.queue, ^{ + [zone _onqueueAddToZone:zonekeys.tlk zoneID:zoneID]; + [zone _onqueueAddToZone:zonekeys.classA zoneID:zoneID]; + [zone _onqueueAddToZone:zonekeys.classC zoneID:zoneID]; - if(zonekeys.rolledTLK) { - [self.zones[zoneID] addToZone: zonekeys.rolledTLK zoneID: zoneID]; - } + [zone _onqueueAddToZone:zonekeys.currentTLKPointer zoneID:zoneID]; + [zone _onqueueAddToZone:zonekeys.currentClassAPointer zoneID:zoneID]; + [zone _onqueueAddToZone:zonekeys.currentClassCPointer zoneID:zoneID]; + + if(zonekeys.rolledTLK) { + [zone _onqueueAddToZone:zonekeys.rolledTLK zoneID:zoneID]; + } + }); } - (void)rollFakeKeyHierarchyInCloudKit: (CKRecordZoneID*)zoneID { @@ -572,10 +582,10 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) deletedRecordTypeCounts:(NSDictionary*)expectedDeletedRecordTypeCounts zoneID:(CKRecordZoneID*)zoneID checkModifiedRecord:(BOOL (^)(CKRecord*))checkRecord - runAfterModification:(void (^) ())afterModification + runAfterModification:(void (^) (void))afterModification { - void (^newAfterModification)() = afterModification; + void (^newAfterModification)(void) = afterModification; if([self.ckksZones containsObject:zoneID]) { __weak __typeof(self) weakSelf = self; newAfterModification = ^{ @@ -1044,7 +1054,7 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) XCTAssertEqual(errSecSuccess, SecItemCopyMatching((__bridge CFDictionaryRef) query, &result), "Should have found TLKs"); NSArray* items = (NSArray*) CFBridgingRelease(result); - XCTAssertEqual(items.count, n, "Should have received %lu items", n); + XCTAssertEqual(items.count, n, "Should have received %lu items", (unsigned long)n); } } diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m index 1c109e32..a50ce905 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m +++ b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m @@ -54,9 +54,10 @@ [self.ckksZones addObject:self.keychainZoneID]; // Wait for the ViewManager to be brought up - XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:4*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize"); + XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:20*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize"); self.keychainView = [[CKKSViewManager manager] findView:@"keychain"]; + [self.ckksViews addObject:self.keychainView]; XCTAssertNotNil(self.keychainView, "CKKSViewManager created the keychain view"); // Check that your environment is set up correctly diff --git a/keychain/ckks/tests/CloudKitMockXCTest.h b/keychain/ckks/tests/CloudKitMockXCTest.h index 8db293eb..3845ac96 100644 --- a/keychain/ckks/tests/CloudKitMockXCTest.h +++ b/keychain/ckks/tests/CloudKitMockXCTest.h @@ -50,6 +50,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable) id mockDatabase; @property (nullable) id mockDatabaseExceptionCatcher; @property (nullable) id mockContainer; +@property (nullable) id mockContainerExpectations; @property (nullable) id mockFakeCKModifyRecordZonesOperation; @property (nullable) id mockFakeCKModifySubscriptionsOperation; @property (nullable) id mockFakeCKFetchRecordZoneChangesOperation; @@ -61,10 +62,12 @@ NS_ASSUME_NONNULL_BEGIN @property CKAccountStatus accountStatus; @property BOOL supportsDeviceToDeviceEncryption; @property BOOL iCloudHasValidCredentials; -@property SOSCCStatus circleStatus; +@property SOSAccountStatus* circleStatus; @property (readonly) NSString* ckDeviceID; @property (readonly) CKKSCKAccountStateTracker* accountStateTracker; +@property NSString* apsEnvironment; + @property NSString* circlePeerID; @property bool aksLockState; // The current 'AKS lock state' @@ -121,13 +124,13 @@ NS_ASSUME_NONNULL_BEGIN deletedRecordTypeCounts:(NSDictionary* _Nullable)expectedDeletedRecordTypeCounts zoneID:(CKRecordZoneID*)zoneID checkModifiedRecord:(BOOL (^_Nullable)(CKRecord*))checkRecord - runAfterModification:(void (^_Nullable)())afterModification; + runAfterModification:(void (^_Nullable)(void))afterModification; - (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID; - (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID - blockAfterReject:(void (^_Nullable)())blockAfterReject; + blockAfterReject:(void (^_Nullable)(void))blockAfterReject; - (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID - blockAfterReject:(void (^_Nullable)())blockAfterReject + blockAfterReject:(void (^_Nullable)(void))blockAfterReject withError:(NSError* _Nullable)error; - (void)expectCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID; @@ -141,7 +144,7 @@ NS_ASSUME_NONNULL_BEGIN // Use this to 1) assert that a fetch occurs and 2) cause a block to run _after_ all changes have been delivered but _before_ the fetch 'completes'. // This way, you can modify the CK zone to cause later collisions. -- (void)expectCKFetchAndRunBeforeFinished:(void (^_Nullable)())blockAfterFetch; +- (void)expectCKFetchAndRunBeforeFinished:(void (^_Nullable)(void))blockAfterFetch; // Use this to assert that a FakeCKFetchRecordsOperation occurs. - (void)expectCKFetchByRecordID; diff --git a/keychain/ckks/tests/CloudKitMockXCTest.m b/keychain/ckks/tests/CloudKitMockXCTest.m index 82dea2e3..497a334b 100644 --- a/keychain/ckks/tests/CloudKitMockXCTest.m +++ b/keychain/ckks/tests/CloudKitMockXCTest.m @@ -102,8 +102,11 @@ self.zones = [[NSMutableDictionary alloc] init]; + self.apsEnvironment = @"fake APS push string"; + self.mockDatabaseExceptionCatcher = OCMStrictClassMock([CKDatabase class]); self.mockDatabase = OCMStrictClassMock([CKDatabase class]); + self.mockContainerExpectations = OCMStrictClassMock([CKContainer class]); self.mockContainer = OCMClassMock([CKContainer class]); OCMStub([self.mockContainer containerWithIdentifier:[OCMArg isKindOfClass:[NSString class]]]).andReturn(self.mockContainer); OCMStub([self.mockContainer defaultContainer]).andReturn(self.mockContainer); @@ -111,7 +114,8 @@ OCMStub([self.mockContainer containerIdentifier]).andReturn(SecCKKSContainerName); OCMStub([self.mockContainer initWithContainerID: [OCMArg any] options: [OCMArg any]]).andReturn(self.mockContainer); OCMStub([self.mockContainer privateCloudDatabase]).andReturn(self.mockDatabaseExceptionCatcher); - OCMStub([self.mockContainer serverPreferredPushEnvironmentWithCompletionHandler: ([OCMArg invokeBlockWithArgs:@"fake APS push string", [NSNull null], nil])]); + OCMStub([self.mockContainer serverPreferredPushEnvironmentWithCompletionHandler: ([OCMArg invokeBlockWithArgs:self.apsEnvironment, [NSNull null], nil])]); + OCMStub([self.mockContainer submitEventMetric:[OCMArg any]]).andCall(self, @selector(ckcontainerSubmitEventMetric:)); // Use two layers of mockDatabase here, so we can both add Expectations and catch the exception (instead of crash) when one fails. OCMStub([self.mockDatabaseExceptionCatcher addOperation:[OCMArg any]]).andCall(self, @selector(ckdatabaseAddOperation:)); @@ -169,7 +173,7 @@ return NO; }]]); - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; self.mockAccountStateTracker = OCMClassMock([CKKSCKAccountStateTracker class]); OCMStub([self.mockAccountStateTracker getCircleStatus]).andCall(self, @selector(circleStatus)); @@ -180,7 +184,7 @@ NSError * error)) { __strong __typeof(self) strongSelf = weakSelf; if(passedBlock && strongSelf) { - if(strongSelf.circleStatus == kSOSCCInCircle) { + if(strongSelf.circleStatus.status == kSOSCCInCircle) { passedBlock(strongSelf.circlePeerID, nil); } else { passedBlock(nil, [NSError errorWithDomain:@"securityd" code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey:@"no account, no circle id"}]); @@ -295,6 +299,14 @@ kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); } +- (void)ckcontainerSubmitEventMetric:(CKEventMetric*)metric { + @try { + [self.mockContainerExpectations submitEventMetric:metric]; + } @catch (NSException *exception) { + XCTFail("Received an container exception when trying to add a metric: %@", exception); + } +} + - (void)ckdatabaseAddOperation:(NSOperation*)op { @try { [self.mockDatabase addOperation:op]; @@ -328,7 +340,7 @@ [self expectCKFetchAndRunBeforeFinished: nil]; } --(void)expectCKFetchAndRunBeforeFinished: (void (^)())blockAfterFetch { +-(void)expectCKFetchAndRunBeforeFinished: (void (^)(void))blockAfterFetch { // Create an object for the block to retain and modify BoolHolder* runAlready = [[BoolHolder alloc] init]; @@ -338,11 +350,14 @@ if(runAlready.state) { return NO; } + + secnotice("fakecloudkit", "Received an operation (%@), checking if it's a fetch changes", obj); BOOL matches = NO; if ([obj isKindOfClass: [FakeCKFetchRecordZoneChangesOperation class]]) { matches = YES; runAlready.state = true; + secnotice("fakecloudkit", "Running fetch changes: %@", obj); FakeCKFetchRecordZoneChangesOperation *frzco = (FakeCKFetchRecordZoneChangesOperation *)obj; frzco.blockAfterFetch = blockAfterFetch; [frzco addNullableDependency: strongSelf.ckFetchHoldOperation]; @@ -523,7 +538,7 @@ deletedRecordTypeCounts:(NSDictionary*) expectedDeletedRecordTypeCounts zoneID:(CKRecordZoneID*) zoneID checkModifiedRecord:(BOOL (^)(CKRecord*)) checkModifiedRecord - runAfterModification:(void (^) ())afterModification + runAfterModification:(void (^) (void))afterModification { __weak __typeof(self) weakSelf = self; @@ -534,7 +549,7 @@ expectedRecordTypeCounts, expectedDeletedRecordTypeCounts); [[self.mockDatabase expect] addOperation:[OCMArg checkWithBlock:^BOOL(id obj) { - secnotice("fakecloudkit", "Received an operation, checking"); + secnotice("fakecloudkit", "Received an operation (%@), checking if it's a modification", obj); __block bool matches = false; if(runAlready.state) { secnotice("fakecloudkit", "Run already, skipping"); @@ -563,118 +578,132 @@ FakeCKZone* zone = strongSelf.zones[zoneID]; XCTAssertNotNil(zone, "Have a zone for these records"); - for(CKRecord* record in op.recordsToSave) { - if(![record.recordID.zoneID isEqual: zoneID]) { - secnotice("fakecloudkit", "Modified record zone ID mismatch: %@ %@", zoneID, record.recordID.zoneID); - return NO; - } - - NSError* recordError = [zone errorFromSavingRecord: record]; - if(recordError) { - secnotice("fakecloudkit", "Record zone rejected record write: %@ %@", recordError, record); - XCTFail(@"Record zone rejected record write: %@ %@", recordError, record); - return NO; - } + __block BOOL result = YES; + dispatch_sync(zone.queue, ^{ - NSNumber* currentCountNumber = modifiedRecordTypeCounts[record.recordType]; - NSUInteger currentCount = currentCountNumber ? [currentCountNumber unsignedIntegerValue] : 0; - modifiedRecordTypeCounts[record.recordType] = [NSNumber numberWithUnsignedInteger: currentCount + 1]; - } + for(CKRecord* record in op.recordsToSave) { + if(![record.recordID.zoneID isEqual: zoneID]) { + secnotice("fakecloudkit", "Modified record zone ID mismatch: %@ %@", zoneID, record.recordID.zoneID); + result = NO; + return; + } - for(CKRecordID* recordID in op.recordIDsToDelete) { - if(![recordID.zoneID isEqual: zoneID]) { - matches = false; - secnotice("fakecloudkit", "Deleted record zone ID mismatch: %@ %@", zoneID, recordID.zoneID); - } + NSError* recordError = [zone errorFromSavingRecord: record]; + if(recordError) { + secnotice("fakecloudkit", "Record zone rejected record write: %@ %@", recordError, record); + XCTFail(@"Record zone rejected record write: %@ %@", recordError, record); + result = NO; + return; + } - // Find the object in CloudKit, and record its type - CKRecord* record = strongSelf.zones[zoneID].currentDatabase[recordID]; - if(record) { - NSNumber* currentCountNumber = deletedRecordTypeCounts[record.recordType]; + NSNumber* currentCountNumber = modifiedRecordTypeCounts[record.recordType]; NSUInteger currentCount = currentCountNumber ? [currentCountNumber unsignedIntegerValue] : 0; - deletedRecordTypeCounts[record.recordType] = [NSNumber numberWithUnsignedInteger: currentCount + 1]; + modifiedRecordTypeCounts[record.recordType] = [NSNumber numberWithUnsignedInteger: currentCount + 1]; } - } - NSMutableDictionary* filteredExpectedRecordTypeCounts = [expectedRecordTypeCounts mutableCopy]; - for(NSString* key in filteredExpectedRecordTypeCounts.allKeys) { - if([filteredExpectedRecordTypeCounts[key] isEqual: [NSNumber numberWithInt:0]]) { - filteredExpectedRecordTypeCounts[key] = nil; - } - } - filteredExpectedRecordTypeCounts[SecCKRecordManifestType] = modifiedRecordTypeCounts[SecCKRecordManifestType]; - filteredExpectedRecordTypeCounts[SecCKRecordManifestLeafType] = modifiedRecordTypeCounts[SecCKRecordManifestLeafType]; - - // Inspect that we have exactly the same records as we expect - if(expectedRecordTypeCounts) { - matches &= !![modifiedRecordTypeCounts isEqual: filteredExpectedRecordTypeCounts]; - if(!matches) { - secnotice("fakecloudkit", "Record number mismatch: %@ %@", modifiedRecordTypeCounts, filteredExpectedRecordTypeCounts); - return NO; - } - } else { - matches &= op.recordsToSave.count == 0u; - if(!matches) { - secnotice("fakecloudkit", "Record number mismatch: %@ 0", modifiedRecordTypeCounts); - return NO; - } - } - if(expectedDeletedRecordTypeCounts) { - matches &= !![deletedRecordTypeCounts isEqual: expectedDeletedRecordTypeCounts]; - if(!matches) { - secnotice("fakecloudkit", "Deleted record number mismatch: %@ %@", deletedRecordTypeCounts, expectedDeletedRecordTypeCounts); - return NO; + for(CKRecordID* recordID in op.recordIDsToDelete) { + if(![recordID.zoneID isEqual: zoneID]) { + matches = false; + secnotice("fakecloudkit", "Deleted record zone ID mismatch: %@ %@", zoneID, recordID.zoneID); + } + + // Find the object in CloudKit, and record its type + CKRecord* record = strongSelf.zones[zoneID].currentDatabase[recordID]; + if(record) { + NSNumber* currentCountNumber = deletedRecordTypeCounts[record.recordType]; + NSUInteger currentCount = currentCountNumber ? [currentCountNumber unsignedIntegerValue] : 0; + deletedRecordTypeCounts[record.recordType] = [NSNumber numberWithUnsignedInteger: currentCount + 1]; + } } - } else { - matches &= op.recordIDsToDelete.count == 0u; - if(!matches) { - secnotice("fakecloudkit", "Deleted record number mismatch: %@ 0", deletedRecordTypeCounts); - return NO; + + NSMutableDictionary* filteredExpectedRecordTypeCounts = [expectedRecordTypeCounts mutableCopy]; + for(NSString* key in filteredExpectedRecordTypeCounts.allKeys) { + if([filteredExpectedRecordTypeCounts[key] isEqual: [NSNumber numberWithInt:0]]) { + filteredExpectedRecordTypeCounts[key] = nil; + } } - } + filteredExpectedRecordTypeCounts[SecCKRecordManifestType] = modifiedRecordTypeCounts[SecCKRecordManifestType]; + filteredExpectedRecordTypeCounts[SecCKRecordManifestLeafType] = modifiedRecordTypeCounts[SecCKRecordManifestLeafType]; - // We have the right number of things, and their etags match. Ensure that they have the right etags - if(matches && checkModifiedRecord) { - // Clearly we have the right number of things. Call checkRecord on them... - for(CKRecord* record in op.recordsToSave) { - matches &= !!(checkModifiedRecord(record)); + // Inspect that we have exactly the same records as we expect + if(expectedRecordTypeCounts) { + matches &= !![modifiedRecordTypeCounts isEqual: filteredExpectedRecordTypeCounts]; if(!matches) { - secnotice("fakecloudkit", "Check record reports NO: %@ 0", record); - return NO; + secnotice("fakecloudkit", "Record number mismatch: %@ %@", modifiedRecordTypeCounts, filteredExpectedRecordTypeCounts); + result = NO; + return; + } + } else { + matches &= op.recordsToSave.count == 0u; + if(!matches) { + secnotice("fakecloudkit", "Record number mismatch: %@ 0", modifiedRecordTypeCounts); + result = NO; + return; + } + } + if(expectedDeletedRecordTypeCounts) { + matches &= !![deletedRecordTypeCounts isEqual: expectedDeletedRecordTypeCounts]; + if(!matches) { + secnotice("fakecloudkit", "Deleted record number mismatch: %@ %@", deletedRecordTypeCounts, expectedDeletedRecordTypeCounts); + result = NO; + return; + } + } else { + matches &= op.recordIDsToDelete.count == 0u; + if(!matches) { + secnotice("fakecloudkit", "Deleted record number mismatch: %@ 0", deletedRecordTypeCounts); + result = NO; + return; } } - } - - if(matches) { - // Emulate cloudkit and schedule the operation for execution. Be sure to wait for this operation - // if you'd like to read the data from this write. - NSBlockOperation* ckop = [NSBlockOperation named:@"cloudkit-write" withBlock: ^{ - @synchronized(zone.currentDatabase) { - NSMutableArray* savedRecords = [[NSMutableArray alloc] init]; - for(CKRecord* record in op.recordsToSave) { - CKRecord* reflectedRecord = [record copy]; - reflectedRecord.modificationDate = [NSDate date]; - - [zone addToZone: reflectedRecord]; - [savedRecords addObject:reflectedRecord]; - op.perRecordCompletionBlock(reflectedRecord, nil); - } - for(CKRecordID* recordID in op.recordIDsToDelete) { - // I don't believe CloudKit fails an operation if you delete a record that's not there, so: - [zone deleteCKRecordIDFromZone: recordID]; + // We have the right number of things, and their etags match. Ensure that they have the right etags + if(matches && checkModifiedRecord) { + // Clearly we have the right number of things. Call checkRecord on them... + for(CKRecord* record in op.recordsToSave) { + matches &= !!(checkModifiedRecord(record)); + if(!matches) { + secnotice("fakecloudkit", "Check record reports NO: %@ 0", record); + result = NO; + return; } + } + } - if(afterModification) { - afterModification(); + if(matches) { + // Emulate cloudkit and schedule the operation for execution. Be sure to wait for this operation + // if you'd like to read the data from this write. + NSBlockOperation* ckop = [NSBlockOperation named:@"cloudkit-write" withBlock: ^{ + @synchronized(zone.currentDatabase) { + NSMutableArray* savedRecords = [[NSMutableArray alloc] init]; + for(CKRecord* record in op.recordsToSave) { + CKRecord* reflectedRecord = [record copy]; + reflectedRecord.modificationDate = [NSDate date]; + + [zone addToZone: reflectedRecord]; + + [savedRecords addObject:reflectedRecord]; + op.perRecordCompletionBlock(reflectedRecord, nil); + } + for(CKRecordID* recordID in op.recordIDsToDelete) { + // I don't believe CloudKit fails an operation if you delete a record that's not there, so: + [zone deleteCKRecordIDFromZone: recordID]; + } + + if(afterModification) { + afterModification(); + } + + op.modifyRecordsCompletionBlock(savedRecords, op.recordIDsToDelete, nil); + op.isFinished = YES; } - - op.modifyRecordsCompletionBlock(savedRecords, op.recordIDsToDelete, nil); - op.isFinished = YES; - } - }]; - [ckop addNullableDependency:strongSelf.ckModifyHoldOperation]; - [strongSelf.operationQueue addOperation: ckop]; + }]; + [ckop addNullableDependency:strongSelf.ckModifyHoldOperation]; + [strongSelf.operationQueue addOperation: ckop]; + } + }); + if(result != YES) { + return result; } } if(matches) { @@ -712,11 +741,11 @@ [self failNextCKAtomicModifyItemRecordsUpdateFailure:zoneID blockAfterReject:nil]; } -- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID blockAfterReject: (void (^)())blockAfterReject { +- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID blockAfterReject: (void (^)(void))blockAfterReject { [self failNextCKAtomicModifyItemRecordsUpdateFailure:zoneID blockAfterReject:blockAfterReject withError:nil]; } -- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID blockAfterReject: (void (^)())blockAfterReject withError:(NSError*)error { +- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID blockAfterReject: (void (^)(void))blockAfterReject withError:(NSError*)error { __weak __typeof(self) weakSelf = self; [[self.mockDatabase expect] addOperation:[OCMArg checkWithBlock:^BOOL(id obj) { @@ -888,7 +917,7 @@ [self.operationQueue cancelAllOperations]; [self waitForCKModifications]; - XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:2*NSEC_PER_SEC], + XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:20*NSEC_PER_SEC], "Timeout did not occur waiting for SecCKKSInitialize"); // Ensure that we can fetch zone status for all zones @@ -898,14 +927,14 @@ XCTAssertNil(error, "Should be no error fetching status"); [statusReturned fulfill]; }]; - [self waitForExpectations: @[statusReturned] timeout:5]; + [self waitForExpectations: @[statusReturned] timeout:20]; } // Make sure this happens before teardown. - XCTAssertEqual(0, [self.accountStateTracker.finishedInitialDispatches wait:1*NSEC_PER_SEC], "Account state tracker initialized itself"); + XCTAssertEqual(0, [self.accountStateTracker.finishedInitialDispatches wait:20*NSEC_PER_SEC], "Account state tracker initialized itself"); dispatch_group_t accountChangesDelivered = [self.accountStateTracker checkForAllDeliveries]; - XCTAssertEqual(0, dispatch_group_wait(accountChangesDelivered, dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC)), "Account state tracker finished delivering everything"); + XCTAssertEqual(0, dispatch_group_wait(accountChangesDelivered, dispatch_time(DISPATCH_TIME_NOW, 10*NSEC_PER_SEC)), "Account state tracker finished delivering everything"); } [super tearDown]; diff --git a/keychain/ckks/tests/MockCloudKit.h b/keychain/ckks/tests/MockCloudKit.h index 11ef4eb1..3aca53f6 100644 --- a/keychain/ckks/tests/MockCloudKit.h +++ b/keychain/ckks/tests/MockCloudKit.h @@ -37,24 +37,36 @@ NS_ASSUME_NONNULL_BEGIN typedef NSMutableDictionary FakeCKDatabase; -@interface FakeCKModifyRecordZonesOperation : NSBlockOperation +@interface FakeCKModifyRecordZonesOperation : NSBlockOperation { + CKOperationConfiguration* _configuration; +} @property (nullable) NSError* creationError; @property (nonatomic, nullable) NSMutableArray* recordZonesSaved; @property (nonatomic, nullable) NSMutableArray* recordZoneIDsDeleted; +@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration; + + (FakeCKDatabase*)ckdb; +(void)ensureZoneDeletionAllowed:(FakeCKZone*)zone; @end -@interface FakeCKModifySubscriptionsOperation : NSBlockOperation +@interface FakeCKModifySubscriptionsOperation : NSBlockOperation { + CKOperationConfiguration* _configuration; +} @property (nullable) NSError* subscriptionError; @property (nonatomic, nullable) NSMutableArray* subscriptionsSaved; @property (nonatomic, nullable) NSMutableArray* subscriptionIDsDeleted; +@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration; + (FakeCKDatabase*)ckdb; @end -@interface FakeCKFetchRecordZoneChangesOperation : NSOperation +@interface FakeCKFetchRecordZoneChangesOperation : NSOperation { + CKOperationConfiguration* _configuration; +} + + (FakeCKDatabase*)ckdb; -@property (nullable) void (^blockAfterFetch)(); +@property (nonatomic, copy) NSString *operationID; +@property (nonatomic, readonly, strong, nullable) CKOperationConfiguration *resolvedConfiguration; +@property (nullable) void (^blockAfterFetch)(void); @end @interface FakeCKFetchRecordsOperation : NSBlockOperation @@ -90,14 +102,19 @@ typedef NSMutableDictionary FakeCKDatabase; // Usually nil. If set, trying to subscribe to this zone should fail. @property (nullable) NSError* subscriptionError; -- (instancetype)initZone:(CKRecordZoneID*)zoneID; +// Serial queue. Use this for transactionality. +@property dispatch_queue_t queue; -- (void)rollChangeToken; +- (instancetype)initZone:(CKRecordZoneID*)zoneID; // Always Succeed - (void)addToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID; - (void)addToZone:(CKRecord*)record; +// If you want a transaction of adding, use these +- (void)_onqueueAddToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID; +- (void)_onqueueAddToZone:(CKRecord*)record; + // Removes this record from all versions of the CK database, without changing the change tag - (void)deleteFromHistory:(CKRecordID*)recordID; diff --git a/keychain/ckks/tests/MockCloudKit.m b/keychain/ckks/tests/MockCloudKit.m index 556ab2ab..f130b83f 100644 --- a/keychain/ckks/tests/MockCloudKit.m +++ b/keychain/ckks/tests/MockCloudKit.m @@ -41,6 +41,18 @@ @synthesize modifyRecordZonesCompletionBlock = _modifyRecordZonesCompletionBlock; @synthesize group = _group; +- (CKOperationConfiguration*)configuration { + return _configuration; +} + +- (void)setConfiguration:(CKOperationConfiguration*)configuration { + if(configuration) { + _configuration = configuration; + } else { + _configuration = [[CKOperationConfiguration alloc] init]; + } +} + - (instancetype)initWithRecordZonesToSave:(nullable NSArray *)recordZonesToSave recordZoneIDsToDelete:(nullable NSArray *)recordZoneIDsToDelete { if(self = [super init]) { _recordZonesToSave = recordZonesToSave; @@ -154,6 +166,18 @@ @synthesize subscriptionIDsToDelete = _subscriptionIDsToDelete; @synthesize modifySubscriptionsCompletionBlock = _modifySubscriptionsCompletionBlock; +- (CKOperationConfiguration*)configuration { + return _configuration; +} + +- (void)setConfiguration:(CKOperationConfiguration*)configuration { + if(configuration) { + _configuration = configuration; + } else { + _configuration = [[CKOperationConfiguration alloc] init]; + } +} + - (instancetype)initWithSubscriptionsToSave:(nullable NSArray *)subscriptionsToSave subscriptionIDsToDelete:(nullable NSArray *)subscriptionIDsToDelete { if(self = [super init]) { _subscriptionsToSave = subscriptionsToSave; @@ -224,8 +248,9 @@ @end @implementation FakeCKFetchRecordZoneChangesOperation +@synthesize database = _database; @synthesize recordZoneIDs = _recordZoneIDs; -@synthesize optionsByRecordZoneID = _optionsByRecordZoneID; +@synthesize configurationsByRecordZoneID = _configurationsByRecordZoneID; @synthesize fetchAllChanges = _fetchAllChanges; @synthesize recordChangedBlock = _recordChangedBlock; @@ -235,12 +260,28 @@ @synthesize recordZoneFetchCompletionBlock = _recordZoneFetchCompletionBlock; @synthesize fetchRecordZoneChangesCompletionBlock = _fetchRecordZoneChangesCompletionBlock; +@synthesize operationID = _operationID; +@synthesize resolvedConfiguration = _resolvedConfiguration; @synthesize group = _group; -- (instancetype)initWithRecordZoneIDs:(NSArray *)recordZoneIDs optionsByRecordZoneID:(nullable NSDictionary *)optionsByRecordZoneID { +- (CKOperationConfiguration*)configuration { + return _configuration; +} + +- (void)setConfiguration:(CKOperationConfiguration*)configuration { + if(configuration) { + _configuration = configuration; + } else { + _configuration = [[CKOperationConfiguration alloc] init]; + } +} + +- (instancetype)initWithRecordZoneIDs:(NSArray *)recordZoneIDs configurationsByRecordZoneID:(nullable NSDictionary *)configurationsByRecordZoneID { if(self = [super init]) { _recordZoneIDs = recordZoneIDs; - _optionsByRecordZoneID = optionsByRecordZoneID; + _configurationsByRecordZoneID = configurationsByRecordZoneID; + + _operationID = @"fake-operation-ID"; } return self; } @@ -248,6 +289,9 @@ - (void)main { // iterate through database, and return items that aren't in lastDatabase FakeCKDatabase* ckdb = [FakeCKFetchRecordZoneChangesOperation ckdb]; + if(self.recordZoneIDs.count == 0) { + secerror("fakeck: No zones to fetch. Likely a bug?"); + } for(CKRecordZoneID* zoneID in self.recordZoneIDs) { FakeCKZone* zone = ckdb[zoneID]; @@ -280,17 +324,26 @@ } // Extract the database at the last time they asked - CKServerChangeToken* token = self.optionsByRecordZoneID[zoneID].previousServerChangeToken; - NSMutableDictionary* lastDatabase = token ? zone.pastDatabases[token] : nil; + CKServerChangeToken* fetchToken = self.configurationsByRecordZoneID[zoneID].previousServerChangeToken; + __block NSMutableDictionary* lastDatabase = nil; + __block NSDictionary* currentDatabase = nil; + __block CKServerChangeToken* currentChangeToken = nil; - // You can fetch with the current change token; that's fine - if([token isEqual:zone.currentChangeToken]) { - lastDatabase = zone.currentDatabase; - } + dispatch_sync(zone.queue, ^{ + lastDatabase = fetchToken ? zone.pastDatabases[fetchToken] : nil; + + // You can fetch with the current change token; that's fine + if([fetchToken isEqual:zone.currentChangeToken]) { + lastDatabase = zone.currentDatabase; + } - ckksnotice("fakeck", zone.zoneID, "FakeCKFetchRecordZoneChangesOperation(%@): database is currently %@ change token %@ database then: %@", zone.zoneID, zone.currentDatabase, token, lastDatabase); + currentDatabase = zone.currentDatabase; + currentChangeToken = zone.currentChangeToken; + }); - if(!lastDatabase && token) { + ckksnotice("fakeck", zone.zoneID, "FakeCKFetchRecordZoneChangesOperation(%@): database is currently %@ change token %@ database then: %@", zone.zoneID, currentDatabase, fetchToken, lastDatabase); + + if(!lastDatabase && fetchToken) { ckksnotice("fakeck", zone.zoneID, "no database for this change token: failing fetch with 'CKErrorChangeTokenExpired'"); self.fetchRecordZoneChangesCompletionBlock([[CKPrettyError alloc] initWithDomain:CKErrorDomain @@ -300,8 +353,7 @@ return; } - [zone.currentDatabase enumerateKeysAndObjectsUsingBlock:^(CKRecordID * _Nonnull recordID, CKRecord * _Nonnull record, BOOL * _Nonnull stop) { - + [currentDatabase enumerateKeysAndObjectsUsingBlock:^(CKRecordID * _Nonnull recordID, CKRecord * _Nonnull record, BOOL * _Nonnull stop) { id last = [lastDatabase objectForKey: recordID]; if(!last || ![record isEqual:last]) { self.recordChangedBlock(record); @@ -311,21 +363,22 @@ // iterate through lastDatabase, and delete items that aren't in database [lastDatabase enumerateKeysAndObjectsUsingBlock:^(CKRecordID * _Nonnull recordID, CKRecord * _Nonnull record, BOOL * _Nonnull stop) { - id current = [zone.currentDatabase objectForKey: recordID]; + id current = [currentDatabase objectForKey: recordID]; if(current == nil) { self.recordWithIDWasDeletedBlock(recordID, [record recordType]); } }]; - self.recordZoneChangeTokensUpdatedBlock(zoneID, zone.currentChangeToken, nil); - self.recordZoneFetchCompletionBlock(zoneID, zone.currentChangeToken, nil, NO, nil); + self.recordZoneChangeTokensUpdatedBlock(zoneID, currentChangeToken, nil); + self.recordZoneFetchCompletionBlock(zoneID, currentChangeToken, nil, NO, nil); if(self.blockAfterFetch) { self.blockAfterFetch(); } - self.fetchRecordZoneChangesCompletionBlock(nil); } + + self.fetchRecordZoneChangesCompletionBlock(nil); } +(FakeCKDatabase*) ckdb { @@ -337,6 +390,7 @@ @end @implementation FakeCKFetchRecordsOperation +@synthesize database = _database; @synthesize recordIDs = _recordIDs; @synthesize desiredKeys = _desiredKeys; @synthesize configuration = _configuration; @@ -527,29 +581,51 @@ _fetchErrors = [[NSMutableArray alloc] init]; - [self rollChangeToken]; + _queue = dispatch_queue_create("fake-ckzone", DISPATCH_QUEUE_SERIAL); + + dispatch_sync(_queue, ^{ + [self _onqueueRollChangeToken]; + }); } return self; } -- (void)rollChangeToken { +- (void)_onqueueRollChangeToken { + dispatch_assert_queue(self.queue); + NSData* changeToken = [[[NSUUID UUID] UUIDString] dataUsingEncoding:NSUTF8StringEncoding]; self.currentChangeToken = [[CKServerChangeToken alloc] initWithData: changeToken]; } - (void)addToZone: (CKKSCKRecordHolder*) item zoneID: (CKRecordZoneID*) zoneID { + dispatch_sync(self.queue, ^{ + [self _onqueueAddToZone:item zoneID:zoneID]; + }); +} + +- (void)_onqueueAddToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID { + dispatch_assert_queue(self.queue); + CKRecord* record = [item CKRecordWithZoneID: zoneID]; - [self addToZone: record]; + [self _onqueueAddToZone: record]; // Save off the etag item.storedCKRecord = record; } - (void)addToZone: (CKRecord*) record { + dispatch_sync(self.queue, ^{ + [self _onqueueAddToZone:record]; + }); +} + +- (void)_onqueueAddToZone:(CKRecord*)record { + dispatch_assert_queue(self.queue); + // Save off this current databse self.pastDatabases[self.currentChangeToken] = [self.currentDatabase mutableCopy]; - [self rollChangeToken]; + [self _onqueueRollChangeToken]; record.etag = [self.currentChangeToken description]; ckksnotice("fakeck", self.zoneID, "change tag: %@ %@", record.recordChangeTag, record.recordID); @@ -594,11 +670,12 @@ - (NSError*)deleteCKRecordIDFromZone:(CKRecordID*) recordID { // todo: fail somehow + dispatch_sync(self.queue, ^{ + self.pastDatabases[self.currentChangeToken] = [self.currentDatabase mutableCopy]; + [self _onqueueRollChangeToken]; - self.pastDatabases[self.currentChangeToken] = [self.currentDatabase mutableCopy]; - [self rollChangeToken]; - - [self.currentDatabase removeObjectForKey: recordID]; + [self.currentDatabase removeObjectForKey: recordID]; + }); return nil; } diff --git a/keychain/ckksctl/ckksctl.m b/keychain/ckksctl/ckksctl.m index cc9e4ac6..19d91bab 100644 --- a/keychain/ckksctl/ckksctl.m +++ b/keychain/ckksctl/ckksctl.m @@ -191,7 +191,7 @@ static void print_entry(id k, id v, int ind) printf("Beginning CloudKit reset for %s...\n", view ? [[view description] UTF8String] : "all zones"); dispatch_semaphore_t sema = dispatch_semaphore_create(0); - [self.control rpcResetCloudKit:view reply:^(NSError* error){ + [self.control rpcResetCloudKit:view reason:@"ckksctl" reply:^(NSError* error){ if(error == NULL) { printf("CloudKit Reset complete.\n"); ret = 0; @@ -347,7 +347,6 @@ static void print_entry(id k, id v, int ind) NSString* lastIncomingQueueOperation = pop(status,@"lastIncomingQueueOperation"); NSString* lastNewTLKOperation = pop(status,@"lastNewTLKOperation"); NSString* lastOutgoingQueueOperation = pop(status,@"lastOutgoingQueueOperation"); - NSString* lastRecordZoneChangesOperation = pop(status,@"lastRecordZoneChangesOperation"); NSString* lastProcessReceivedKeysOperation = pop(status,@"lastProcessReceivedKeysOperation"); NSString* lastReencryptOutgoingItemsOperation = pop(status,@"lastReencryptOutgoingItemsOperation"); NSString* lastScanLocalItemsOperation = pop(status,@"lastScanLocalItemsOperation"); @@ -405,7 +404,6 @@ static void print_entry(id k, id v, int ind) printf("lastIncomingQueueOperation: %s\n", [lastIncomingQueueOperation isEqual: [NSNull null]] ? "never" : [lastIncomingQueueOperation UTF8String]); printf("lastNewTLKOperation: %s\n", [lastNewTLKOperation isEqual: [NSNull null]] ? "never" : [lastNewTLKOperation UTF8String]); printf("lastOutgoingQueueOperation: %s\n", [lastOutgoingQueueOperation isEqual: [NSNull null]] ? "never" : [lastOutgoingQueueOperation UTF8String]); - printf("lastRecordZoneChangesOperation: %s\n", [lastRecordZoneChangesOperation isEqual: [NSNull null]] ? "never" : [lastRecordZoneChangesOperation UTF8String]); printf("lastProcessReceivedKeysOperation: %s\n", [lastProcessReceivedKeysOperation isEqual: [NSNull null]] ? "never" : [lastProcessReceivedKeysOperation UTF8String]); printf("lastReencryptOutgoingItemsOperation: %s\n", [lastReencryptOutgoingItemsOperation isEqual: [NSNull null]] ? "never" : [lastReencryptOutgoingItemsOperation UTF8String]); printf("lastScanLocalItemsOperation: %s\n", [lastScanLocalItemsOperation isEqual: [NSNull null]] ? "never" : [lastScanLocalItemsOperation UTF8String]); diff --git a/keychain/ot/OTCloudStore.m b/keychain/ot/OTCloudStore.m index ccecbaca..3abbdfcd 100644 --- a/keychain/ot/OTCloudStore.m +++ b/keychain/ot/OTCloudStore.m @@ -24,6 +24,8 @@ #import #import +#import +#import #import "keychain/ot/OTCloudStore.h" #import "keychain/ot/OTCloudStoreState.h" @@ -160,10 +162,10 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass OTCloudStoreState* state = [OTCloudStoreState state: self.zoneName]; - CKFetchRecordZoneChangesOptions* options = [[CKFetchRecordZoneChangesOptions alloc] init]; + CKFetchRecordZoneChangesConfiguration* options = [[CKFetchRecordZoneChangesConfiguration alloc] init]; options.previousServerChangeToken = state.changeToken; - self.fetchRecordZoneChangesOperation = [[[self.fetchRecordZoneChangesOperationClass class] alloc] initWithRecordZoneIDs:@[self.zoneID] optionsByRecordZoneID:@{self.zoneID : options}]; + self.fetchRecordZoneChangesOperation = [[[self.fetchRecordZoneChangesOperationClass class] alloc] initWithRecordZoneIDs:@[self.zoneID] configurationsByRecordZoneID:@{self.zoneID : options}]; self.fetchRecordZoneChangesOperation.recordChangedBlock = ^(CKRecord *record) { secinfo("octagon", "CloudKit notification: record changed(%@): %@", [record recordType], record); @@ -331,12 +333,12 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass [op waitUntilFinished]; if(op.error != nil) { - secerror("octagon: failed to fetch changes error:%@", op.error); - if(error){ - *error = op.error; - } - return nil; + secnotice("octagon", "failed to fetch changes error:%@", op.error); } + + secnotice("octagon", "checking local store for bottles"); + + //check localstore for bottles NSArray* localStoreBottledPeerRecords = [self.localStore readAllLocalBottledPeerRecords:&localError]; if(!localStoreBottledPeerRecords) { @@ -414,7 +416,11 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass self.modifyRecordsOperation.atomic = YES; self.modifyRecordsOperation.longLived = NO; // The keys are only in memory; mark this explicitly not long-lived - self.modifyRecordsOperation.qualityOfService = NSQualityOfServiceUserInitiated; // Currently done during buddy. User is waiting. + + // Currently done during buddy. User is waiting. + self.modifyRecordsOperation.configuration.automaticallyRetryNetworkFailures = NO; + self.modifyRecordsOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged; self.modifyRecordsOperation.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) { diff --git a/keychain/ot/OTCloudStoreState.m b/keychain/ot/OTCloudStoreState.m index 3c119dc7..ac61ea81 100644 --- a/keychain/ot/OTCloudStoreState.m +++ b/keychain/ot/OTCloudStoreState.m @@ -125,7 +125,7 @@ return @{@"ckzone": self.ckzone}; } -- (NSDictionary*) sqlValues { +- (NSDictionary*) sqlValues { NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; return @{@"ckzone": self.ckzone, diff --git a/keychain/ot/OTContext.h b/keychain/ot/OTContext.h index 52b33e7b..e8ee0b75 100644 --- a/keychain/ot/OTContext.h +++ b/keychain/ot/OTContext.h @@ -71,7 +71,6 @@ NS_ASSUME_NONNULL_BEGIN error:(NSError**)error; -(OctagonBottleCheckState)doesThisDeviceHaveABottle:(NSError**)error; --(void) postFollowUp; @end NS_ASSUME_NONNULL_END diff --git a/keychain/ot/OTContext.m b/keychain/ot/OTContext.m index 479d8878..e16b3ea9 100644 --- a/keychain/ot/OTContext.m +++ b/keychain/ot/OTContext.m @@ -32,8 +32,6 @@ #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CKKSAnalytics.h" -#import "CoreCDP/CDPFollowUpController.h" -#import "CoreCDP/CDPFollowUpContext.h" #import NSString* OTCKContainerName = @"com.apple.security.keychain"; @@ -528,30 +526,5 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; return bottleStatus; } --(void) postFollowUp -{ - NSError* error = nil; - - CKKSAnalytics* logger = [CKKSAnalytics logger]; - SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityBottleCheck withAction:nil]; - - [tracker start]; - CDPFollowUpController *cdpd = [[CDPFollowUpController alloc] init]; - CDPFollowUpContext *context = [CDPFollowUpContext contextForOfflinePasscodeChange]; - - [cdpd postFollowUpWithContext:context error:&error]; - if(error){ - [logger logUnrecoverableError:error forEvent:OctagonEventCoreFollowUp withAttributes:@{ - OctagonEventAttributeFailureReason : @"core follow up failed"}]; - - secerror("request to CoreCDP to follow up failed: %@", error); - } - else{ - [logger logSuccessForEventNamed:OctagonEventCoreFollowUp]; - } - [tracker stop]; -} - - @end #endif diff --git a/keychain/ot/OTControl.m b/keychain/ot/OTControl.m index 41cc74af..b8921485 100644 --- a/keychain/ot/OTControl.m +++ b/keychain/ot/OTControl.m @@ -34,6 +34,10 @@ #include +#if OCTAGON +#import +#endif + @interface OTControl () @property NSXPCConnection *connection; @end diff --git a/keychain/ot/OTControlProtocol.h b/keychain/ot/OTControlProtocol.h index 6caa8dc9..2cc27dda 100644 --- a/keychain/ot/OTControlProtocol.h +++ b/keychain/ot/OTControlProtocol.h @@ -22,8 +22,11 @@ */ #import + NS_ASSUME_NONNULL_BEGIN +@class SFECKeyPair; + @protocol OTControlProtocol - (void)restore:(NSString *)contextID dsid:(NSString *)dsid secret:(NSData*)secret escrowRecordID:(NSString*)escrowRecordID reply:(void (^)(NSData* _Nullable signingKeyData, NSData* _Nullable encryptionKeyData, NSError * _Nullable error))reply; - (void)octagonEncryptionPublicKey:(void (^)(NSData* _Nullable encryptionKey, NSError * _Nullable))reply;; diff --git a/keychain/ot/OTControlProtocol.m b/keychain/ot/OTControlProtocol.m index fde2ded8..1868ea72 100644 --- a/keychain/ot/OTControlProtocol.m +++ b/keychain/ot/OTControlProtocol.m @@ -30,6 +30,7 @@ #import #import #include +#import #endif // OCTAGON NSXPCInterface* OTSetupControlProtocol(NSXPCInterface* interface) { diff --git a/keychain/ot/OTManager.m b/keychain/ot/OTManager.m index cef912b2..4cbc9246 100644 --- a/keychain/ot/OTManager.m +++ b/keychain/ot/OTManager.m @@ -38,7 +38,7 @@ #import "keychain/ot/OT.h" #import "keychain/ot/OTConstants.h" -#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #import "keychain/ckks/CKKSAnalytics.h" #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CKKS.h" @@ -358,7 +358,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; } NSInteger retryDelayInSeconds = 0; - BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error]; + BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; //got an error from ramp check, we should log it if(error){ @@ -428,7 +428,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; } NSInteger retryDelayInSeconds = 0; - BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error]; + BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; //got an error from ramp check, we should log it if(error){ @@ -497,7 +497,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; } NSInteger retryDelayInSeconds = 0; - BOOL isFeatureOn = [self.restoreRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error]; + BOOL isFeatureOn = [self.restoreRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; //got an error from ramp check, we should log it if(error){ @@ -621,7 +621,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; [tracker start]; NSInteger retryDelayInSeconds = 0; - BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error]; + BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; //got an error from ramp check, we should log it if(error){ @@ -668,6 +668,14 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; { NSError* error = nil; + if(!self.context || !self.localStore){ + if(![self initializeManagerPropertiesForContext:nil error:&error]){ + secerror("octagon: could not init manager obejcts: %@", error); + reply(NO,error); + return; + } + } + if(self.context.lockStateTracker.isLocked){ secnotice("octagon","device is locked! can't check ramp state"); error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain @@ -715,6 +723,13 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; - (void)listOfEligibleBottledPeerRecords:(void (^)(NSArray* listOfRecords, NSError *))reply { NSError* error = nil; + if(!self.context || !self.localStore){ + if(![self initializeManagerPropertiesForContext:nil error:&error]){ + secerror("octagon: could not init manager obejcts: %@", error); + reply(nil,error); + return; + } + } if(self.context.lockStateTracker.isLocked){ secnotice("octagon","device is locked! can't check ramp state"); @@ -807,7 +822,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; CKKSAnalytics* logger = [CKKSAnalytics logger]; if(self.cfuRamp){ - BOOL canCFU = [self.cfuRamp checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError]; + BOOL canCFU = [self.cfuRamp checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError]; if(localError){ secerror("octagon: checking ramp state for CFU error'd: %@", localError); @@ -824,7 +839,9 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; //time to post a follow up! secnotice("octagon", "device does not have a bottle, posting a follow up"); if(!SecCKKSTestsEnabled()){ - [self.context postFollowUp]; + //40347954 removing cfu invocations until we can add CDP without creating a cycle. + //[self.context postFollowUp]; + secnotice("octagon", "would have posted a follow up"); } NSInteger timeDiff = -1; diff --git a/keychain/ot/OTRamping.h b/keychain/ot/OTRamping.h index 184ee8ac..8dacb9d4 100644 --- a/keychain/ot/OTRamping.h +++ b/keychain/ot/OTRamping.h @@ -25,6 +25,8 @@ #define OTRamping_h #if OCTAGON +#import +#import #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CloudKitDependencies.h" #import "keychain/ckks/CKKSLockStateTracker.h" @@ -50,9 +52,9 @@ NS_ASSUME_NONNULL_BEGIN reachabilityTracker:(CKKSReachabilityTracker*) reachabilityTracker fetchRecordRecordsOperationClass:(Class) fetchRecordRecordsOperationClass; --(void) fetchRampRecord:(NSQualityOfService)qos +-(void) fetchRampRecord:(CKOperationDiscretionaryNetworkBehavior)networkBehavior reply:(void (^)(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError))recordRampStateFetchCompletionBlock; --(BOOL) checkRampState:(NSInteger*)retryAfter qos:(NSQualityOfService)qos error:(NSError**)error; +-(BOOL) checkRampState:(NSInteger*)retryAfter networkBehavior:(CKOperationDiscretionaryNetworkBehavior)networkBehavior error:(NSError**)error; @end NS_ASSUME_NONNULL_END #endif /* OCTAGON */ diff --git a/keychain/ot/OTRamping.m b/keychain/ot/OTRamping.m index 73991155..29b2bb0c 100644 --- a/keychain/ot/OTRamping.m +++ b/keychain/ot/OTRamping.m @@ -96,13 +96,13 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR return self; } --(void) fetchRampRecord:(NSQualityOfService)qos reply:(void (^)(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError))recordRampStateFetchCompletionBlock +-(void) fetchRampRecord:(CKOperationDiscretionaryNetworkBehavior)networkBehavior reply:(void (^)(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError))recordRampStateFetchCompletionBlock { __weak __typeof(self) weakSelf = self; CKOperationConfiguration *opConfig = [[CKOperationConfiguration alloc] init]; opConfig.allowsCellularAccess = YES; - opConfig.qualityOfService = qos; + opConfig.discretionaryNetworkBehavior = networkBehavior; _recordID = [[CKRecordID alloc] initWithRecordName:_recordName zoneID:_zoneID]; CKFetchRecordsOperation *operation = [[[self.fetchRecordRecordsOperationClass class] alloc] initWithRecordIDs:@[ _recordID]]; @@ -146,7 +146,7 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR secnotice("octagon", "Attempting to fetch ramp state from CloudKit"); } --(BOOL) checkRampState:(NSInteger*)retryAfter qos:(NSQualityOfService)qos error:(NSError**)error +-(BOOL) checkRampState:(NSInteger*)retryAfter networkBehavior:(CKOperationDiscretionaryNetworkBehavior)networkBehavior error:(NSError**)error { __block BOOL isFeatureEnabled = NO; __block NSError* localError = nil; @@ -202,7 +202,7 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR [tracker start]; - [self fetchRampRecord:qos reply:^(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError) { + [self fetchRampRecord:networkBehavior reply:^(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError) { secnotice("octagon", "fetch ramp records returned with featureAllowed: %d,\n featurePromoted: %d,\n featureVisible: %d,\n", featureAllowed, featurePromoted, featureVisible); isFeatureEnabled = featureAllowed; @@ -226,7 +226,7 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR [tracker stop]; if(localRetryAfter > 0){ - secnotice("octagon", "cloud kit asked security to retry: %ld", localRetryAfter); + secnotice("octagon", "cloud kit asked security to retry: %lu", (unsigned long)localRetryAfter); *retryAfter = localRetryAfter; } diff --git a/keychain/ot/tests/OTLockStateNetworkingTests.m b/keychain/ot/tests/OTLockStateNetworkingTests.m index b1fd55f1..b5baca36 100644 --- a/keychain/ot/tests/OTLockStateNetworkingTests.m +++ b/keychain/ot/tests/OTLockStateNetworkingTests.m @@ -590,7 +590,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - [self.enroll checkRampState:&retryAfter qos:NSQualityOfServiceUserInitiated error:&error]; + [self.enroll checkRampState:&retryAfter networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); @@ -611,7 +611,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.reachabilityFlags = 0; [self.reachabilityTracker recheck]; - [self.enroll checkRampState:&retryAfter qos:NSQualityOfServiceUserInitiated error:&error]; + [self.enroll checkRampState:&retryAfter networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); } @@ -626,7 +626,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.aksLockState = true; [self.lockStateTracker recheck]; - [self.enroll checkRampState:&retryAfter qos:NSQualityOfServiceUserInitiated error:&error]; + [self.enroll checkRampState:&retryAfter networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); } diff --git a/keychain/ot/tests/OTRampingTests.m b/keychain/ot/tests/OTRampingTests.m index 1bbb1dcd..fc205e49 100644 --- a/keychain/ot/tests/OTRampingTests.m +++ b/keychain/ot/tests/OTRampingTests.m @@ -350,7 +350,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; [self setUpRampRecordsInCloudKitWithFeatureOn]; - XCTAssertTrue([self.cfu checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError], @"should be true"); + XCTAssertTrue([self.cfu checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError], @"should be true"); } -(void)testCFUWithRampOff @@ -359,7 +359,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; NSInteger retryAfterInSeconds = 0; [self setUpRampRecordsInCloudKitWithFeatureOff]; - XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError], @"should be false"); + XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError], @"should be false"); XCTAssertTrue(retryAfterInSeconds != 0, @"should be asked to retry later"); } @@ -368,7 +368,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; { NSError* localError = nil; NSInteger retryAfterInSeconds = 0; - XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError], @"should be false"); + XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError], @"should be false"); } @end diff --git a/keychain/ot/tests/OTTestsBase.m b/keychain/ot/tests/OTTestsBase.m index 81738098..63345a33 100644 --- a/keychain/ot/tests/OTTestsBase.m +++ b/keychain/ot/tests/OTTestsBase.m @@ -140,7 +140,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; [self startCKKSSubsystem]; self.accountStatus = CKAccountStatusAvailable; - self.circleStatus = kSOSCCInCircle; + self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; [self.cfu.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; [self.context.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; diff --git a/keychain/otctl/otctl.m b/keychain/otctl/otctl.m index 416d4d56..52653cc4 100644 --- a/keychain/otctl/otctl.m +++ b/keychain/otctl/otctl.m @@ -8,6 +8,7 @@ #import #import #import +#import "OT.h" #import #import "keychain/ot/OTControl.h" #import "keychain/ot/OTConstants.h" @@ -341,27 +342,6 @@ @end -static bool SecOTIsEnabled(void) { - - bool userDefaultsShouldBottledPeer = true; - CFBooleanRef enabled = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("EnableOTRestore"), - CFSTR("com.apple.security"), - kCFPreferencesAnyUser, kCFPreferencesAnyHost); - if(enabled && CFGetTypeID(enabled) == CFBooleanGetTypeID()){ - if(enabled == kCFBooleanFalse){ - secnotice("octagon", "Octagon Restore Disabled"); - userDefaultsShouldBottledPeer = false; - } - if(enabled == kCFBooleanTrue){ - secnotice("octagon", "Octagon Restore Enabled"); - userDefaultsShouldBottledPeer = true; - } - } - - CFReleaseNull(enabled); - return userDefaultsShouldBottledPeer; -} - static int enroll = false; static int restore = false; static int octagonkeys = false; diff --git a/libsecurity_smime/lib/CMSDecoder.c b/libsecurity_smime/lib/CMSDecoder.c index 48cb56e2..d6a1037d 100644 --- a/libsecurity_smime/lib/CMSDecoder.c +++ b/libsecurity_smime/lib/CMSDecoder.c @@ -1041,3 +1041,42 @@ exit: } return status; } + +/* + * Obtain the expiration time of signer 'signerIndex' of a CMS message, if + * present. This is part of the signed attributes of the message. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerAppleExpirationTime( + CMSDecoderRef cmsDecoder, + size_t signerIndex, + CFAbsoluteTime *expirationTime) /* RETURNED */ +{ + OSStatus status = errSecParam; + SecCmsMessageRef cmsg = NULL; + int numContentInfos = 0; + SecCmsSignedDataRef signedData = NULL; + + require(cmsDecoder && expirationTime, xit); + require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit); + numContentInfos = SecCmsMessageContentLevelCount(cmsg); + for (int dex = 0; !signedData && dex < numContentInfos; dex++) { + SecCmsContentInfoRef ci = SecCmsMessageContentLevel(cmsg, dex); + SECOidTag tag = SecCmsContentInfoGetContentTypeTag(ci); + if (tag == SEC_OID_PKCS7_SIGNED_DATA) { + if ((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci))) { + SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(signedData, (int)signerIndex); + if (signerInfo) { + status = SecCmsSignerInfoGetAppleExpirationTime(signerInfo, expirationTime); + break; + } + } + } + } +xit: + return status; +} diff --git a/libsecurity_smime/lib/CMSDecoder.h b/libsecurity_smime/lib/CMSDecoder.h index 7b754404..bc6d689f 100644 --- a/libsecurity_smime/lib/CMSDecoder.h +++ b/libsecurity_smime/lib/CMSDecoder.h @@ -407,8 +407,8 @@ OSStatus CMSDecoderGetDecoder( OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( CMSDecoderRef cmsDecoder, size_t signerIndex, /* usually 0 */ - CFDataRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValue); /* RETURNED */ - + CFDataRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValue) /* RETURNED */ +API_AVAILABLE(macos(10.12.4), ios(11.0)); /* * Obtain the Hash Agility v2 attribute value of signer 'signerIndex' @@ -422,7 +422,23 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( OSStatus CMSDecoderCopySignerAppleCodesigningHashAgilityV2( CMSDecoderRef cmsDecoder, size_t signerIndex, /* usually 0 */ - CFDictionaryRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValues); /* RETURNED */ + CFDictionaryRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValues) /* RETURNED */ +API_AVAILABLE(macos(10.13.4), ios(11.3)); + +/* + * Obtain the expiration time of signer 'signerIndex' of a CMS message, if + * present. This is part of the signed attributes of the message. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerAppleExpirationTime( + CMSDecoderRef cmsDecoder, + size_t signerIndex, + CFAbsoluteTime *expirationTime) /* RETURNED */ +API_AVAILABLE(macos(10.14), ios(12.0)); CF_ASSUME_NONNULL_END diff --git a/libsecurity_smime/lib/CMSEncoder.c b/libsecurity_smime/lib/CMSEncoder.c index 44d1dd0c..171527e8 100644 --- a/libsecurity_smime/lib/CMSEncoder.c +++ b/libsecurity_smime/lib/CMSEncoder.c @@ -98,6 +98,7 @@ struct _CMSEncoder { CMSCertificateChainMode chainMode; CFDataRef hashAgilityAttrValue; CFDictionaryRef hashAgilityV2AttrValues; + CFAbsoluteTime expirationTime; }; static void cmsEncoderInit(CFTypeRef enc); @@ -280,12 +281,20 @@ static int convertOid( // CFStringRef: OID representation is a dotted-decimal string CFStringRef inStr = (CFStringRef)inRef; CFIndex max = CFStringGetLength(inStr) * 3; - char buf[max]; - if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII)) + char *buf = (char *)malloc(max); + if (!buf) { + return errSecMemoryError; + } + if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII)) { + free(buf); return errSecParam; + } - if(encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0) + if (encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0) { + free(buf); return errSecParam; + } + free(buf); } else if (CFGetTypeID(inRef) == CFDataGetTypeID()) { // CFDataRef: OID representation is in binary DER format @@ -537,6 +546,14 @@ static OSStatus cmsSetupForSignedData( break; } } + if (cmsEncoder->signedAttributes & kCMSAttrAppleExpirationTime) { + ortn = SecCmsSignerInfoAddAppleExpirationTime(signerInfo, cmsEncoder->expirationTime); + if(ortn) { + ortn = cmsRtnToOSStatus(ortn); + CSSM_PERROR("SecCmsSignerInfoAddAppleExpirationTime", ortn); + break; + } + } CFRELEASE(ourCert); ourCert = NULL; @@ -1035,6 +1052,24 @@ OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2( return errSecSuccess; } +/* + * Set the expiration time for a CMSEncoder. + * This is only used if the kCMSAttrAppleExpirationTime attribute is included. + */ +OSStatus CMSEncoderSetAppleExpirationTime( + CMSEncoderRef cmsEncoder, + CFAbsoluteTime time) +{ + if(cmsEncoder == NULL) { + return errSecParam; + } + if(cmsEncoder->encState != ES_Init) { + return errSecParam; + } + cmsEncoder->expirationTime = time; + return errSecSuccess; +} + OSStatus CMSEncoderSetCertificateChainMode( CMSEncoderRef cmsEncoder, CMSCertificateChainMode chainMode) diff --git a/libsecurity_smime/lib/CMSEncoder.h b/libsecurity_smime/lib/CMSEncoder.h index e548c56d..d91fa1da 100644 --- a/libsecurity_smime/lib/CMSEncoder.h +++ b/libsecurity_smime/lib/CMSEncoder.h @@ -250,6 +250,10 @@ typedef CF_OPTIONS(uint32_t, CMSSignedAttributes) { */ kCMSAttrAppleCodesigningHashAgility = 0x0010, kCMSAttrAppleCodesigningHashAgilityV2 = 0x0020, + /* + * Include the expiration time. + */ + kCMSAttrAppleExpirationTime = 0x0040, }; /* @@ -348,7 +352,7 @@ OSStatus CMSEncodeContent( CFDataRef * __nullable CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_11_0); -#if TIMESTAMPING_SUPOORTED +#if TIMESTAMPING_SUPPORTED OSStatus CMSEncoderCopySignerTimestamp( CMSEncoderRef cmsEncoder, size_t signerIndex, /* usually 0 */ @@ -364,7 +368,7 @@ OSStatus CMSEncoderCopySignerTimestampWithPolicy( void CmsMessageSetTSAContext(CMSEncoderRef cmsEncoder, CFTypeRef tsaContext); -#endif +#endif // TIMESTAMPING_SUPPORTED /* * Obtain the SecCmsMessageRef associated with a CMSEncoderRef. Intended @@ -428,6 +432,14 @@ OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2( CMSEncoderRef cmsEncoder, CFDictionaryRef hashAgilityV2AttrValues); +/* + * Set the expiration time for a CMSEncoder. + * This is only used if the kCMSAttrAppleExpirationTime attribute is included. + */ +OSStatus CMSEncoderSetAppleExpirationTime( + CMSEncoderRef cmsEncoder, + CFAbsoluteTime time); + CF_ASSUME_NONNULL_END diff --git a/libsecurity_smime/lib/SecCmsBase.h b/libsecurity_smime/lib/SecCmsBase.h index c9e6e1ad..c39fb5b9 100644 --- a/libsecurity_smime/lib/SecCmsBase.h +++ b/libsecurity_smime/lib/SecCmsBase.h @@ -39,12 +39,6 @@ #include #include -#if !SEC_OS_OSX_INCLUDES -#if !USE_CDSA_CRYPTO -typedef CFTypeRef SecKeychainRef; -#endif -#endif // ! SEC_OS_OSX_INCLUDES - #if defined(__cplusplus) extern "C" { #endif @@ -59,7 +53,10 @@ typedef struct SECOidDataStr SECOidData; @typedef @discussion XXX We might want to get rid of this alltogether. */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" typedef SecAsn1AlgId SECAlgorithmID; +#pragma clang diagnostic pop /*! @typedef @@ -156,7 +153,10 @@ typedef void (*SecCmsContentCallback)(void *arg, const char *buf, size_t len); @typedef @discussion Type of function passed to SecCmsDecode or SecCmsDecoderStart to retrieve the decryption key. This function is intended to be used for EncryptedData content info's which do not have a key available in a certificate, etc. */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" typedef SecSymmetricKeyRef(*SecCmsGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid); +#pragma clang diagnostic pop /*! @enum SecCmsVerificationStatus @@ -486,6 +486,9 @@ typedef enum { SEC_OID_APPLE_HASH_AGILITY = 214, SEC_OID_APPLE_HASH_AGILITY_V2 = 215, + /* Apple Expiration Time Attribute */ + SEC_OID_APPLE_EXPIRATION_TIME = 216, + SEC_OID_TOTAL } SECOidTag; diff --git a/libsecurity_smime/lib/SecCmsSignerInfo.h b/libsecurity_smime/lib/SecCmsSignerInfo.h index ab132f23..01d5757c 100644 --- a/libsecurity_smime/lib/SecCmsSignerInfo.h +++ b/libsecurity_smime/lib/SecCmsSignerInfo.h @@ -111,6 +111,16 @@ SecCmsSignerInfoGetAppleCodesigningHashAgility(SecCmsSignerInfoRef sinfo, CFData extern OSStatus SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDictionaryRef *sdict); +/*! + @function SecCmsSignerInfoGetAppleExpirationTime + @abstract Return the expriation time, in CFAbsoluteTime, of a CMS signerInfo. + @param sinfo SignerInfo data for this signer. + @discussion Returns a CFAbsoluteTime + @result A return value of SECFailure is an error. + */ +extern OSStatus +SecCmsSignerInfoGetAppleExpirationTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *etime); + /*! @function @abstract Return the signing cert of a CMS signerInfo. @@ -204,6 +214,16 @@ SecCmsSignerInfoAddAppleCodesigningHashAgility(SecCmsSignerInfoRef signerinfo, C OSStatus SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef signerinfo, CFDictionaryRef attrValues); +/*! + @function SecCmsSignerInfoAddAppleExpirationTime + @abstract Add the expiration time to the authenticated (i.e. signed) attributes of "signerinfo". + @discussion This is expected to be included in outgoing signed messages for Asset Receipts but is likely + useful in other situations. This should only be added once; a second call will do nothing. + @result A result of SECFailure indicates an error adding the attribute. + */ +extern OSStatus +SecCmsSignerInfoAddAppleExpirationTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t); + /*! @function @abstract The following needs to be done in the S/MIME layer code after signature of a signerinfo has been verified. diff --git a/libsecurity_smime/lib/cert.c b/libsecurity_smime/lib/cert.c index fb9d902b..34628872 100644 --- a/libsecurity_smime/lib/cert.c +++ b/libsecurity_smime/lib/cert.c @@ -225,6 +225,7 @@ CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Bo CFArrayRef certChain = NULL; CSSM_TP_APPLE_EVIDENCE_INFO *statusChain; OSStatus status = 0; + SecTrustResultType trustResult = kSecTrustResultInvalid; if (!cert) goto loser; @@ -241,7 +242,7 @@ CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Bo if (status) goto loser; - status = SecTrustEvaluate(trust, NULL); + status = SecTrustEvaluate(trust, &trustResult); if (status) goto loser; diff --git a/libsecurity_smime/lib/cmsattr.c b/libsecurity_smime/lib/cmsattr.c index 8bab00d0..c5eb1142 100644 --- a/libsecurity_smime/lib/cmsattr.c +++ b/libsecurity_smime/lib/cmsattr.c @@ -265,6 +265,7 @@ cms_attr_choose_attr_value_template(void *src_or_dest, Boolean encoding, const c theTemplate = SEC_ASN1_GET(kSecAsn1OctetStringTemplate); break; case SEC_OID_PKCS9_SIGNING_TIME: + case SEC_OID_APPLE_EXPIRATION_TIME: encoded = PR_FALSE; theTemplate = SEC_ASN1_GET(kSecAsn1UTCTimeTemplate); // @@@ This should be a choice between UTCTime and GeneralizedTime -- mb break; diff --git a/libsecurity_smime/lib/cmsenvdata.c b/libsecurity_smime/lib/cmsenvdata.c index b7ccbdd6..07b6b6b9 100644 --- a/libsecurity_smime/lib/cmsenvdata.c +++ b/libsecurity_smime/lib/cmsenvdata.c @@ -238,9 +238,12 @@ SecCmsEnvelopedDataEncodeBeforeStart(SecCmsEnvelopedDataRef envd) #else { size_t keysize = (cinfo->keysize + 7)/8; - uint8_t key_material[keysize]; + uint8_t *key_material = (uint8_t *)malloc(keysize); + if (!key_material) { + goto loser; + } require_noerr(SecRandomCopyBytes(kSecRandomDefault, keysize, key_material), loser); - bulkkey = (SecSymmetricKeyRef)CFDataCreate(kCFAllocatorDefault, key_material, keysize); + bulkkey = (SecSymmetricKeyRef)CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, key_material, keysize, kCFAllocatorMalloc); } #endif diff --git a/libsecurity_smime/lib/cmspubkey.c b/libsecurity_smime/lib/cmspubkey.c index eb7944e2..4e15bfc3 100644 --- a/libsecurity_smime/lib/cmspubkey.c +++ b/libsecurity_smime/lib/cmspubkey.c @@ -67,12 +67,7 @@ SecCmsUtilEncryptSymKeyRSA(PLArenaPool *poolp, SecCertificateRef cert, SecAsn1Item * encKey) { OSStatus rv; - SecPublicKeyRef publickey; -#if TARGET_OS_MAC && !TARGET_OS_IPHONE - rv = SecCertificateCopyPublicKey(cert,&publickey); -#else - publickey = SecCertificateCopyPublicKey(cert); -#endif + SecPublicKeyRef publickey = SecCertificateCopyKey(cert); if (publickey == NULL) return SECFailure; @@ -776,11 +771,7 @@ SecCmsUtilEncryptSymKeyECDH( encKey->Length = 0; /* Copy the recipient's static public ECDH key */ -#if TARGET_OS_IPHONE - theirPubKey = SecCertificateCopyPublicKey(cert); -#else - rv = SecCertificateCopyPublicKey(cert, &theirPubKey); -#endif + theirPubKey = SecCertificateCopyKey(cert); if (rv || !theirPubKey) { dprintf("SecCmsUtilEncryptSymKeyECDH: failed to get public key from cert, %d\n", (int)rv); goto out; diff --git a/libsecurity_smime/lib/cmssiginfo.c b/libsecurity_smime/lib/cmssiginfo.c index e2e06912..a3144dfa 100644 --- a/libsecurity_smime/lib/cmssiginfo.c +++ b/libsecurity_smime/lib/cmssiginfo.c @@ -609,6 +609,7 @@ SecCmsSignerInfoVerifyCertificate(SecCmsSignerInfoRef signerinfo, SecKeychainRef if (SecCmsSignerInfoGetSigningTime(signerinfo, &stime) != SECSuccess) stime = CFAbsoluteTimeGetCurrent(); + #if USE_CDSA_CRYPTO rv = CERT_VerifyCert(keychainOrArray, cert, policies, stime, trustRef); #else @@ -662,16 +663,9 @@ SecCmsSignerInfoVerify(SecCmsSignerInfoRef signerinfo, SecAsn1Item * digest, Sec goto loser; } -#if USE_CDSA_CRYPTO - if (SecCertificateCopyPublicKey(cert, &publickey)) { - vs = SecCmsVSProcessingError; - goto loser; - } -#else - publickey = SecCertificateCopyPublicKey(cert); + publickey = SecCertificateCopyKey(cert); if (publickey == NULL) goto loser; -#endif if (!SecCmsArrayIsEmpty((void **)signerinfo->authAttr)) { if (contentType) { @@ -1010,6 +1004,41 @@ SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDi return errSecAllocate; } +/* + * SecCmsSignerInfoGetAppleExpirationTime - return the expiration time, + * in UTCTime format, of a CMS signerInfo. + * + * sinfo - signerInfo data for this signer + * + * Returns a pointer to XXXX (what?) + * A return value of NULL is an error. + */ +OSStatus +SecCmsSignerInfoGetAppleExpirationTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *etime) +{ + SecCmsAttribute *attr = NULL; + SecAsn1Item * value = NULL; + + if (sinfo == NULL || etime == NULL) { + return SECFailure; + } + + if (sinfo->expirationTime != 0) { + *etime = sinfo->expirationTime; /* cached copy */ + return SECSuccess; + } + + attr = SecCmsAttributeArrayFindAttrByOidTag(sinfo->authAttr, SEC_OID_APPLE_EXPIRATION_TIME, PR_TRUE); + if (attr == NULL || (value = SecCmsAttributeGetValue(attr)) == NULL) { + return SECFailure; + } + if (DER_UTCTimeToCFDate(value, etime) != SECSuccess) { + return SECFailure; + } + sinfo->expirationTime = *etime; /* make cached copy */ + return SECSuccess; +} + /* * Return the signing cert of a CMS signerInfo. * @@ -1529,6 +1558,47 @@ loser: return status; } +/* + * SecCmsSignerInfoAddAppleExpirationTime - add the expiration time to the + * authenticated (i.e. signed) attributes of "signerinfo". + * + * This is expected to be included in outgoing signed + * messages for Asset Receipts but is likely useful in other situations. + * + * This should only be added once; a second call will do nothing. + */ +OSStatus +SecCmsSignerInfoAddAppleExpirationTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t) +{ + SecCmsAttribute *attr = NULL; + PLArenaPool *poolp = signerinfo->signedData->contentInfo.cmsg->poolp; + void *mark = PORT_ArenaMark(poolp); + + /* create new expiration time attribute */ + SecAsn1Item etime; + if (DER_CFDateToUTCTime(t, &etime) != SECSuccess) { + goto loser; + } + + if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_APPLE_EXPIRATION_TIME, &etime, PR_FALSE)) == NULL) { + SECITEM_FreeItem (&etime, PR_FALSE); + goto loser; + } + + SECITEM_FreeItem(&etime, PR_FALSE); + + if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) { + goto loser; + } + + PORT_ArenaUnmark(poolp, mark); + return SECSuccess; + +loser: + PORT_ArenaRelease(poolp, mark); + return SECFailure; +} + SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSignerInfoRef signerinfo) { SecCertificateRef cert = NULL; SecCmsAttribute *attr; diff --git a/libsecurity_smime/lib/cmstpriv.h b/libsecurity_smime/lib/cmstpriv.h index 324e2ce1..fede4e52 100644 --- a/libsecurity_smime/lib/cmstpriv.h +++ b/libsecurity_smime/lib/cmstpriv.h @@ -208,6 +208,7 @@ struct SecCmsSignerInfoStr { SecPublicKeyRef pubKey; CFDataRef hashAgilityAttrValue; CFDictionaryRef hashAgilityV2AttrValues; + CFAbsoluteTime expirationTime; }; #define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */ #define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */ diff --git a/libsecurity_smime/lib/crypto-embedded.c b/libsecurity_smime/lib/crypto-embedded.c index d7e4504c..6cf8af24 100644 --- a/libsecurity_smime/lib/crypto-embedded.c +++ b/libsecurity_smime/lib/crypto-embedded.c @@ -211,7 +211,7 @@ CFArrayRef CERT_DupCertList(CFArrayRef oldList) // Extract a public key object from a SubjectPublicKeyInfo SecPublicKeyRef CERT_ExtractPublicKey(SecCertificateRef cert) { - return SecCertificateCopyPublicKey(cert); + return SecCertificateCopyKey(cert); } // Extract the issuer and serial number from a certificate @@ -225,7 +225,7 @@ SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef ce CFDataRef issuer_data = SecCertificateCopyIssuerSequence(cert); if (!issuer_data) goto loser; - serial_data = SecCertificateCopySerialNumber(cert); + serial_data = SecCertificateCopySerialNumberData(cert, NULL); if (!serial_data) goto loser; @@ -433,20 +433,24 @@ WRAP_PubWrapSymKey(SecPublicKeyRef publickey, encKey->Data, &encKey->Length); } +#define MAX_KEY_SIZE 8192/8 SecSymmetricKeyRef WRAP_PubUnwrapSymKey(SecPrivateKeyRef privkey, const SecAsn1Item *encKey, SECOidTag bulkalgtag) { size_t bulkkey_size = encKey->Length; - if (bulkkey_size > 16384) { + if (bulkkey_size > MAX_KEY_SIZE) { return NULL; } - uint8_t bulkkey_buffer[bulkkey_size]; - if (SecKeyDecrypt(privkey, kSecPaddingPKCS1, - encKey->Data, encKey->Length, bulkkey_buffer, &bulkkey_size)) - return NULL; + uint8_t *bulkkey_buffer = (uint8_t *)malloc(bulkkey_size); + if (!bulkkey_buffer) { + return NULL; + } + if (SecKeyDecrypt(privkey, kSecPaddingPKCS1, encKey->Data, encKey->Length, bulkkey_buffer, &bulkkey_size)) { + return NULL; + } - CFDataRef bulkkey = CFDataCreate(kCFAllocatorDefault, bulkkey_buffer, bulkkey_size); + CFDataRef bulkkey = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, bulkkey_buffer, bulkkey_size, kCFAllocatorMalloc); return (SecSymmetricKeyRef)bulkkey; } @@ -464,7 +468,7 @@ CERT_CheckIssuerAndSerial(SecCertificateRef cert, SecAsn1Item *issuer, SecAsn1It break; } CFRelease(cert_issuer); - CFDataRef cert_serial = SecCertificateCopySerialNumber(cert); + CFDataRef cert_serial = SecCertificateCopySerialNumberData(cert, NULL); if (!cert_serial) break; if ((serial->Length != (size_t)CFDataGetLength(cert_serial)) || diff --git a/libsecurity_smime/lib/secoid.c b/libsecurity_smime/lib/secoid.c index 491d64d4..825d988d 100644 --- a/libsecurity_smime/lib/secoid.c +++ b/libsecurity_smime/lib/secoid.c @@ -483,6 +483,9 @@ __unused CONST_OID mqvSinglePassSha1kdf[] = {ANSI_X9_63_SCHEME, 4 }; CONST_OID appleHashAgility[] = {APPLE_CMS_ATTRIBUTES, 1}; CONST_OID appleHashAgilityV2[] = {APPLE_CMS_ATTRIBUTES, 2}; +/* Apple Expiration Time */ +CONST_OID appleExpirationTime[] = {APPLE_CMS_ATTRIBUTES, 3}; + /* a special case: always associated with a caller-specified OID */ CONST_OID noOid[] = { 0 }; @@ -1166,6 +1169,11 @@ static const SECOidData oids[] = { "appleCodesigningHashAgilityAttributeV2", CSSM_ALGID_NONE, INVALID_CERT_EXTENSION), + /* Apple Expiration Time */ + OD( appleExpirationTime, SEC_OID_APPLE_EXPIRATION_TIME, + "appleExpirationTimeAttribute", CSSM_ALGID_NONE, + INVALID_CERT_EXTENSION), + }; /* diff --git a/libsecurity_smime/libCMS.xcodeproj/project.pbxproj b/libsecurity_smime/libCMS.xcodeproj/project.pbxproj index a11713cc..27fe46a6 100644 --- a/libsecurity_smime/libCMS.xcodeproj/project.pbxproj +++ b/libsecurity_smime/libCMS.xcodeproj/project.pbxproj @@ -487,7 +487,7 @@ 4C2741E803E9FBAF00A80181 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1000; TargetAttributes = { D447C4DB1D31C9DD0082FC1D = { CreatedOnToolsVersion = 8.0; @@ -633,11 +633,13 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -692,11 +694,8 @@ debug, profile, ); + CLANG_ENABLE_OBJC_WEAK = YES; CURRENT_PROJECT_VERSION = 8; - FRAMEWORK_SEARCH_PATHS = ( - /usr/local/SecurityPieces/Frameworks, - /usr/local/SecurityPieces/Components/Security, - ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; HEADER_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)/SecurityPieces/Headers", @@ -730,6 +729,7 @@ 79BDD2B00D60CA06000D84D3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; FRAMEWORK_VERSION = A; INSTALL_PATH = /usr/local/SecurityPieces/Components/Security; PRODUCT_NAME = security_smime; @@ -740,6 +740,7 @@ 79BDD2B10D60CA06000D84D3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = NO; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; HEADER_SEARCH_PATHS = ( @@ -770,11 +771,13 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -824,11 +827,8 @@ debug, profile, ); + CLANG_ENABLE_OBJC_WEAK = YES; CURRENT_PROJECT_VERSION = 8; - FRAMEWORK_SEARCH_PATHS = ( - /usr/local/SecurityPieces/Frameworks, - /usr/local/SecurityPieces/Components/Security, - ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; HEADER_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)/SecurityPieces/Headers", @@ -862,6 +862,7 @@ 79BDD2BC0D60CA0A000D84D3 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; FRAMEWORK_VERSION = A; INSTALL_PATH = /usr/local/SecurityPieces/Components/Security; PRODUCT_NAME = security_smime; @@ -872,6 +873,7 @@ 79BDD2BD0D60CA0A000D84D3 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; HEADER_SEARCH_PATHS = ( @@ -897,6 +899,7 @@ D447C4DC1D31C9DD0082FC1D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -904,6 +907,7 @@ D447C4DD1D31C9DD0082FC1D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/ntlm/ntlmBlobPriv.c b/ntlm/ntlmBlobPriv.c index d71073ab..3044310f 100644 --- a/ntlm/ntlmBlobPriv.c +++ b/ntlm/ntlmBlobPriv.c @@ -295,7 +295,7 @@ OSStatus ntlmHostName( *flat = (unsigned char *)malloc(len+1); *flatLen = (unsigned)len; memmove(*flat, hostname, len); - flat[len] = '\0'; // ensure null terminator + flat[len] = NULL; // ensure null terminator return errSecSuccess; } } diff --git a/protocol/SecProtocol.c b/protocol/SecProtocol.c new file mode 100644 index 00000000..c3443da0 --- /dev/null +++ b/protocol/SecProtocol.c @@ -0,0 +1,981 @@ +// +// SecProtocol.c +// Security +// + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#define CFReleaseSafe(value) \ + if (value != NULL) { \ + CFRelease(value); \ + } + +typedef bool (^sec_access_block_t)(void *handle); + +static bool +sec_protocol_options_access_handle(sec_protocol_options_t options, + sec_access_block_t access_block) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static bool (*_nw_protocol_options_access_handle)(void *, sec_access_block_t) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_options_access_handle = (__typeof(_nw_protocol_options_access_handle))dlsym(libnetworkImage, + "nw_protocol_options_access_handle"); + if (NULL == _nw_protocol_options_access_handle) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_options_access_handle"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_options_access_handle == NULL) { + return false; + } + + return _nw_protocol_options_access_handle(options, access_block); +} + +static bool +sec_protocol_metadata_access_handle(sec_protocol_metadata_t options, + sec_access_block_t access_block) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static bool (*_nw_protocol_metadata_access_handle)(void *, sec_access_block_t) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_metadata_access_handle = (__typeof(_nw_protocol_metadata_access_handle))dlsym(libnetworkImage, + "nw_protocol_metadata_access_handle"); + if (NULL == _nw_protocol_metadata_access_handle) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork _nw_protocol_metadata_access_handle"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_metadata_access_handle == NULL) { + return false; + } + + return _nw_protocol_metadata_access_handle(options, access_block); +} + +#define SEC_PROTOCOL_OPTIONS_VALIDATE(o,r) \ +if (o == NULL) { \ +return r; \ +} + +#define SEC_PROTOCOL_METADATA_VALIDATE(m,r) \ +if (((void *)m == NULL) || ((size_t)m == 0)) { \ +return r; \ +} + +void +sec_protocol_options_set_local_identity(sec_protocol_options_t options, sec_identity_t identity) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->identity != NULL) { + sec_release(content->identity); + } + content->identity = sec_retain(identity); + return true; + }); +} + +void +sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options, SSLCipherSuite ciphersuite) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->ciphersuites == NULL) { + content->ciphersuites = xpc_array_create(NULL, 0); + } + xpc_array_set_uint64(content->ciphersuites, XPC_ARRAY_APPEND, (uint64_t)ciphersuite); + return true; + }); +} + +void +sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, SSLCiphersuiteGroup group) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->ciphersuites == NULL) { + content->ciphersuites = xpc_array_create(NULL, 0); + } + + // Fetch the list of ciphersuites associated with the ciphersuite group + size_t ciphersuite_count = 0; + const SSLCipherSuite *list = SSLCiphersuiteGroupToCiphersuiteList(group, &ciphersuite_count); + if (list != NULL) { + for (size_t i = 0; i < ciphersuite_count; i++) { + SSLCipherSuite ciphersuite = list[i]; + xpc_array_set_uint64(content->ciphersuites, XPC_ARRAY_APPEND, (uint64_t)ciphersuite); + } + } + + return true; + }); +} + +void +sec_protocol_options_set_tls_min_version(sec_protocol_options_t options, SSLProtocol version) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->min_version = version; + return true; + }); +} + +void +sec_protocol_options_set_tls_max_version(sec_protocol_options_t options, SSLProtocol version) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->max_version = version; + return true; + }); +} + +void +sec_protocol_options_add_tls_application_protocol(sec_protocol_options_t options, const char *application_protocol) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(application_protocol,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->application_protocols == NULL) { + content->application_protocols = xpc_array_create(NULL, 0); + } + xpc_array_set_string(content->application_protocols, XPC_ARRAY_APPEND, application_protocol); + return true; + }); +} + +void +sec_protocol_options_set_tls_server_name(sec_protocol_options_t options, const char *server_name) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(server_name,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->server_name != NULL) { + free(content->server_name); + } + content->server_name = strdup(server_name); + return true; + }); +} + +void +sec_protocol_options_set_tls_diffie_hellman_parameters(sec_protocol_options_t options, dispatch_data_t params) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(params,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->dh_params) { + dispatch_release(content->dh_params); + } + content->dh_params = params; + dispatch_retain(params); + return true; + }); +} + +void +sec_protocol_options_add_pre_shared_key(sec_protocol_options_t options, dispatch_data_t psk, dispatch_data_t psk_identity) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(psk,); + SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->pre_shared_keys == NULL) { + content->pre_shared_keys = xpc_array_create(NULL, 0); + } + + xpc_object_t psk_data = xpc_data_create_with_dispatch_data(psk); + xpc_object_t psk_identity_data = xpc_data_create_with_dispatch_data(psk_identity); + + xpc_object_t tuple = xpc_array_create(NULL, 0); + xpc_array_set_value(tuple, XPC_ARRAY_APPEND, psk_data); + xpc_array_set_value(tuple, XPC_ARRAY_APPEND, psk_identity_data); + xpc_release(psk_data); + xpc_release(psk_identity_data); + + xpc_array_set_value(content->pre_shared_keys, XPC_ARRAY_APPEND, tuple); + xpc_release(tuple); + return true; + }); +} + +void +sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options, bool fallback_attempt) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->enable_fallback_attempt = fallback_attempt; + return true; + }); +} + +void +sec_protocol_options_set_tls_tickets_enabled(sec_protocol_options_t options, bool tickets_enabled) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->enable_tickets = tickets_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_resumption_enabled(sec_protocol_options_t options, bool resumption_enabled) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->enable_resumption = resumption_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_false_start_enabled(sec_protocol_options_t options, bool false_start_enabled) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->enable_false_start = false_start_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options, bool early_data_enabled) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->enable_early_data = early_data_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options, bool sni_disabled) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->disable_sni = sni_disabled; + return true; + }); +} + +void +sec_protocol_options_set_enforce_ev(sec_protocol_options_t options, bool enforce_ev) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->enforce_ev = enforce_ev; + return true; + }); +} + +void +sec_protocol_options_set_tls_ocsp_enabled(sec_protocol_options_t options, bool ocsp_enabled) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->enable_ocsp = ocsp_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_sct_enabled(sec_protocol_options_t options, bool sct_enabled) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->enable_sct = sct_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_renegotiation_enabled(sec_protocol_options_t options, bool renegotiation_enabled) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->enable_renegotiation = renegotiation_enabled; + return true; + }); +} + +void +sec_protocol_options_set_peer_authentication_required(sec_protocol_options_t options, bool peer_authentication_required) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + content->peer_authentication_required = peer_authentication_required; + content->peer_authentication_override = true; + return true; + }); +} + +void +sec_protocol_options_set_key_update_block(sec_protocol_options_t options, sec_protocol_key_update_t update_block, dispatch_queue_t update_queue) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->key_update_block != NULL) { + Block_release(content->key_update_block); + } + if (content->key_update_queue != NULL) { + dispatch_release(content->key_update_queue); + } + + content->key_update_block = Block_copy(update_block); + content->key_update_queue = Block_copy(update_queue); + dispatch_retain(content->key_update_queue); + return true; + }); +} + +void +sec_protocol_options_set_challenge_block(sec_protocol_options_t options, sec_protocol_challenge_t challenge_block, dispatch_queue_t challenge_queue) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(challenge_queue,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->challenge_block != NULL) { + Block_release(content->challenge_block); + } + if (content->challenge_queue != NULL) { + dispatch_release(content->challenge_queue); + } + + content->challenge_block = Block_copy(challenge_block); + content->challenge_queue = challenge_queue; + dispatch_retain(content->challenge_queue); + return true; + }); +} + +void +sec_protocol_options_set_verify_block(sec_protocol_options_t options, sec_protocol_verify_t verify_block, dispatch_queue_t verify_queue) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(verify_queue,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->verify_block != NULL) { + Block_release(content->verify_block); + } + if (content->verify_queue != NULL) { + dispatch_release(content->verify_queue); + } + + content->verify_block = Block_copy(verify_block); + content->verify_queue = verify_queue; + dispatch_retain(content->verify_queue); + return true; + }); +} + +void +sec_protocol_options_add_tls_extension(sec_protocol_options_t options, sec_tls_extension_t extension) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(extension,); + + (void)sec_protocol_options_access_handle(options, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); + + if (content->custom_extensions == NULL) { + content->custom_extensions = sec_array_create(); + } + + sec_array_append(content->custom_extensions, (sec_object_t)extension); + return true; + }); +} + +const char * +sec_protocol_metadata_get_negotiated_protocol(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + + __block const char *negotiated_protocol = NULL; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + negotiated_protocol = content->negotiated_protocol; + return true; + }); + + return negotiated_protocol; +} + +bool +sec_protocol_metadata_access_peer_certificate_chain(sec_protocol_metadata_t metadata, + void (^handler)(sec_certificate_t certficate)) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + SEC_PROTOCOL_METADATA_VALIDATE(handler, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + if (content->peer_certificate_chain == NULL) { + return false; + } + sec_array_t array = content->peer_certificate_chain; + sec_array_apply(array, ^bool(__unused size_t index, sec_object_t object) { + handler((sec_certificate_t)object); + return true; + }); + return true; + }); +} + +dispatch_data_t +sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + + __block dispatch_data_t peer_public_key = NULL; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + peer_public_key = ((dispatch_data_t)content->peer_public_key); + if (peer_public_key) { + dispatch_retain(peer_public_key); + } + return true; + }); + + return peer_public_key; +} + +SSLProtocol +sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, kSSLProtocolUnknown); + + __block SSLProtocol protocol_version = kSSLProtocolUnknown; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + protocol_version = content->negotiated_protocol_version; + return true; + }); + + return protocol_version; +} + +SSLCipherSuite +sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, SSL_NO_SUCH_CIPHERSUITE); + + __block SSLCipherSuite negotiated_ciphersuite = SSL_NO_SUCH_CIPHERSUITE; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + negotiated_ciphersuite = content->negotiated_ciphersuite; + return true; + }); + + return negotiated_ciphersuite; +} + +bool +sec_protocol_metadata_get_early_data_accepted(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + return content->early_data_accepted; + }); +} + +bool +sec_protocol_metadata_access_supported_signature_algorithms(sec_protocol_metadata_t metadata, + void (^handler)(uint16_t signature_algorithm)) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + SEC_PROTOCOL_METADATA_VALIDATE(handler, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + if (content->supported_signature_algorithms == NULL) { + return false; + } + xpc_object_t array = content->supported_signature_algorithms; + xpc_array_apply(array, ^bool(__unused size_t index, xpc_object_t _Nonnull value) { + handler((uint16_t)xpc_uint64_get_value(value)); + return true; + }); + return true; + }); +} + +bool +sec_protocol_metadata_access_ocsp_response(sec_protocol_metadata_t metadata, + void (^handler)(dispatch_data_t ocsp_data)) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + SEC_PROTOCOL_METADATA_VALIDATE(handler, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + if (content->ocsp_response == NULL) { + return false; + } + sec_array_t array = content->ocsp_response; + sec_array_apply(array, ^bool(__unused size_t index, sec_object_t object) { + handler((dispatch_data_t)object); + return true; + }); + return true; + }); +} + +bool +sec_protocol_metadata_access_distinguished_names(sec_protocol_metadata_t metadata, + void (^handler)(dispatch_data_t distinguished_name)) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + SEC_PROTOCOL_METADATA_VALIDATE(handler, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + if (content->distinguished_names == NULL) { + return false; + } + sec_array_t array = content->distinguished_names; + sec_array_apply(array, ^bool(__unused size_t index, sec_object_t object) { + handler((dispatch_data_t)object); + return true; + }); + return true; + }); +} + +static bool +sec_protocol_dispatch_data_are_equal(dispatch_data_t left, dispatch_data_t right) +{ + if (!left || !right || left == right) { + return left == right; + } + if (dispatch_data_get_size(left) != dispatch_data_get_size(right)) { + return false; + } + + __block bool equal = true; + dispatch_data_apply(left, ^bool(__unused dispatch_data_t _Nonnull lregion, size_t loffset, const void * _Nonnull lbuffer, size_t lsize) { + dispatch_data_apply(right, ^bool(__unused dispatch_data_t _Nonnull rregion, size_t roffset, const void * _Nonnull rbuffer, size_t rsize) { + // There is some overlap + const size_t start = MAX(loffset, roffset); + const size_t end = MIN(loffset + lsize, roffset + rsize); + if (start < end) { + equal = memcmp(&((const uint8_t*)rbuffer)[start - roffset], &((const uint8_t*)lbuffer)[start - loffset], end - start) == 0; + } else { + if (roffset > loffset + lsize) { + // Iteration of right has gone past where we're at on left, bail out of inner apply + // left |---| + // right |---| + return false; + } else if (roffset + rsize < loffset) { + // Iteration of right has not yet reached where we're at on left, keep going + // left |---| + // right |--| + return true; + } + } + return equal; + }); + return equal; + }); + return equal; +} + +static bool +sec_protocol_sec_array_of_dispatch_data_are_equal(sec_array_t arrayA, sec_array_t arrayB) +{ + if (sec_array_get_count(arrayA) != sec_array_get_count(arrayB)) { + return false; + } + + __block bool equal = true; + (void)sec_array_apply(arrayA, ^bool(size_t indexA, sec_object_t objectA) { + return sec_array_apply(arrayB, ^bool(size_t indexB, sec_object_t objectB) { + if (indexA == indexB) { + dispatch_data_t dataA = (dispatch_data_t)objectA; + dispatch_data_t dataB = (dispatch_data_t)objectB; + equal &= sec_protocol_dispatch_data_are_equal(dataA, dataB); + return equal; + } + return true; + }); + }); + + return equal; +} + +static bool +sec_protocol_sec_array_of_sec_certificate_are_equal(sec_array_t arrayA, sec_array_t arrayB) +{ + if (sec_array_get_count(arrayA) != sec_array_get_count(arrayB)) { + return false; + } + + __block bool equal = true; + (void)sec_array_apply(arrayA, ^bool(size_t indexA, sec_object_t objectA) { + return sec_array_apply(arrayB, ^bool(size_t indexB, sec_object_t objectB) { + if (indexA == indexB) { + sec_certificate_t certA = (sec_certificate_t)objectA; + sec_certificate_t certB = (sec_certificate_t)objectB; + + SecCertificateRef certRefA = sec_certificate_copy_ref(certA); + SecCertificateRef certRefB = sec_certificate_copy_ref(certB); + + if (certRefA == NULL && certRefB != NULL) { + equal = false; + } else if (certRefA != NULL && certRefB == NULL) { + equal = false; + } else if (certRefA == NULL && certRefB == NULL) { + // pass + } else { + equal &= CFEqual(certRefA, certRefB); + } + + CFReleaseSafe(certRefA); + CFReleaseSafe(certRefB); + + return equal; + } + return true; + }); + }); + + return equal; +} + +static bool +sec_protocol_xpc_object_are_equal(xpc_object_t objectA, xpc_object_t objectB) +{ + if (objectA == NULL && objectB != NULL) { + return false; + } else if (objectA != NULL && objectB == NULL) { + return false; + } else if (objectA == NULL && objectB == NULL) { + return true; + } else { + return xpc_equal(objectA, objectB); + } +} + +bool +sec_protocol_metadata_peers_are_equal(sec_protocol_metadata_t metadataA, sec_protocol_metadata_t metadataB) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadataA, false); + SEC_PROTOCOL_METADATA_VALIDATE(metadataB, false); + + return sec_protocol_metadata_access_handle(metadataA, ^bool(void *handleA) { + sec_protocol_metadata_content_t contentA = (sec_protocol_metadata_content_t)handleA; + SEC_PROTOCOL_METADATA_VALIDATE(contentA, false); + + return sec_protocol_metadata_access_handle(metadataB, ^bool(void *handleB) { + sec_protocol_metadata_content_t contentB = (sec_protocol_metadata_content_t)handleB; + SEC_PROTOCOL_METADATA_VALIDATE(contentB, false); + + // Relevant peer information includes: Certificate chain, public key, support signature algorithms, OCSP response, and distinguished names + if (!sec_protocol_sec_array_of_sec_certificate_are_equal(contentA->peer_certificate_chain, contentB->peer_certificate_chain)) { + return false; + } + if (!sec_protocol_dispatch_data_are_equal((dispatch_data_t)contentA->peer_public_key, (dispatch_data_t)contentB->peer_public_key)) { + return false; + } + if (!sec_protocol_xpc_object_are_equal((xpc_object_t)contentA->supported_signature_algorithms, (xpc_object_t)contentB->supported_signature_algorithms)) { + return false; + } + if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA->ocsp_response, contentB->ocsp_response)) { + return false; + } + if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA->distinguished_names, contentB->distinguished_names)) { + return false; + } + + return true; + }); + }); +} + +bool +sec_protocol_metadata_challenge_parameters_are_equal(sec_protocol_metadata_t metadataA, sec_protocol_metadata_t metadataB) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadataA, false); + SEC_PROTOCOL_METADATA_VALIDATE(metadataB, false); + + return sec_protocol_metadata_access_handle(metadataA, ^bool(void *handleA) { + sec_protocol_metadata_content_t contentA = (sec_protocol_metadata_content_t)handleA; + SEC_PROTOCOL_METADATA_VALIDATE(contentA, false); + + return sec_protocol_metadata_access_handle(metadataB, ^bool(void *handleB) { + sec_protocol_metadata_content_t contentB = (sec_protocol_metadata_content_t)handleB; + SEC_PROTOCOL_METADATA_VALIDATE(contentB, false); + + if (!sec_protocol_xpc_object_are_equal((xpc_object_t)contentA->supported_signature_algorithms, (xpc_object_t)contentB->supported_signature_algorithms)) { + return false; + } + if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA->distinguished_names, contentB->distinguished_names)) { + return false; + } + if (!sec_protocol_dispatch_data_are_equal(contentA->request_certificate_types, contentB->request_certificate_types)) { + return false; + } + + return true; + }); + }); +} + +dispatch_data_t +sec_protocol_metadata_create_secret(sec_protocol_metadata_t metadata, size_t label_len, + const char *label, size_t exporter_length) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + SEC_PROTOCOL_METADATA_VALIDATE(label_len, NULL); + SEC_PROTOCOL_METADATA_VALIDATE(label, NULL); + SEC_PROTOCOL_METADATA_VALIDATE(exporter_length, NULL); + + __block dispatch_data_t secret = NULL; + sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + + if (content->exporter_function && content->exporter_context) { + sec_protocol_metadata_exporter exporter = (sec_protocol_metadata_exporter)content->exporter_function; + secret = exporter(content->exporter_context, label_len, label, 0, NULL, exporter_length); + } + return true; + }); + return secret; +} + +dispatch_data_t +sec_protocol_metadata_create_secret_with_context(sec_protocol_metadata_t metadata, size_t label_len, + const char *label, size_t context_len, + const uint8_t *context, size_t exporter_length) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + SEC_PROTOCOL_METADATA_VALIDATE(label_len, NULL); + SEC_PROTOCOL_METADATA_VALIDATE(label, NULL); + SEC_PROTOCOL_METADATA_VALIDATE(context_len, NULL); + SEC_PROTOCOL_METADATA_VALIDATE(context, NULL); + SEC_PROTOCOL_METADATA_VALIDATE(exporter_length, NULL); + + __block dispatch_data_t secret = NULL; + sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + + if (content->exporter_function && content->exporter_context) { + sec_protocol_metadata_exporter exporter = (sec_protocol_metadata_exporter)content->exporter_function; + secret = exporter(content->exporter_context, label_len, label, context_len, context, exporter_length); + } + return true; + }); + return secret; +} + +bool +sec_protocol_metadata_get_tls_false_start_used(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + return content->false_start_used; + }); +} + +bool +sec_protocol_metadata_get_ticket_offered(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + return content->ticket_offered; + }); +} + +bool +sec_protocol_metadata_get_ticket_received(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + return content->ticket_received; + }); +} + +bool +sec_protocol_metadata_get_session_resumed(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + return content->session_resumed; + }); +} + +bool +sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + + return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) { + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + return content->session_renewed; + }); +} + +void * +sec_retain(void *obj) +{ + if (obj != NULL) { + return os_retain(obj); + } else { + return NULL; + } +} + +void +sec_release(void *obj) +{ + if (obj != NULL) { + os_release(obj); + } +} diff --git a/protocol/SecProtocol.h b/protocol/SecProtocol.h new file mode 100644 index 00000000..6f333f55 --- /dev/null +++ b/protocol/SecProtocol.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018 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@ + */ + +#ifndef SecProtocol_h +#define SecProtocol_h + +#include +#include +#include +#include + +#endif // SecProtocol_h diff --git a/protocol/SecProtocolMetadata.h b/protocol/SecProtocolMetadata.h new file mode 100644 index 00000000..11d69193 --- /dev/null +++ b/protocol/SecProtocolMetadata.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2018 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@ + */ + +#ifndef SecProtocolMetadata_h +#define SecProtocolMetadata_h + +#include +#include +#include +#include + +#include +#include + +/*! + * The following diagram shows how clients interact with sec_protocol_options + * and sec_protocol_metadata when configuring and using network security protocols. + * + * +--------+ + * | Client | + * +-+---/ \+ + * | | + * +-------------+ +-------------+ + * | (1) set (2) get | + * | options metadata | + * +-----\ /---------------+ +------------+----------+ + * | sec_protocol_options | | sec_protocol_metadata | + * +-----------------------+ +-----------------------+ + * + * Clients configure security protocols with `sec_protocol_options` instances. + * And they inspect protocol instances using `sec_protocol_metadata` instances. + */ + +#ifndef SEC_OBJECT_IMPL +/*! + * A `sec_protocol_metadata` instance conatins read-only properties of a connected and configured + * security protocol. Clients use this object to read information about a protocol instance. Properties + * include, for example, the negotiated TLS version, ciphersuite, and peer certificates. + */ +SEC_OBJECT_DECL(sec_protocol_metadata); +#endif // !SEC_OBJECT_IMPL + +__BEGIN_DECLS + +SEC_ASSUME_NONNULL_BEGIN + +/*! + * @function sec_protocol_metadata_get_negotiated_protocol + * + * @abstract + * Get the application protocol negotiated, e.g., via the TLS ALPN extension. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A NULL-terminated string carrying the negotiated protocol. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +const char * _Nullable +sec_protocol_metadata_get_negotiated_protocol(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_copy_peer_public_key + * + * @abstract + * Get the protocol instance peer's public key. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A `dispatch_data_t` containing the peer's raw public key. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED _Nullable dispatch_data_t +sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_negotiated_protocol_version + * + * @abstract + * Get the negotiated TLS version. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A SSLProtocol enum of the TLS version. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SSLProtocol +sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_negotiated_ciphersuite + * + * @abstract + * Get the negotiated TLS ciphersuite. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A SSLCipherSuite. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SSLCipherSuite +sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_early_data_accepted + * + * @abstract + * Determine if early data was accepted by the peer. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A bool indicating if early data was accepted. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_get_early_data_accepted(sec_protocol_metadata_t metadata); + +#ifdef __BLOCKS__ +/*! + * @function sec_protocol_metadata_access_peer_certificate_chain + * + * @abstract + * Get the certificate chain of the protocol instance peer. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param handler + * A block to invoke one or more times with sec_certificate_t objects + * + * @return Returns true if the peer certificates were accessible, false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_access_peer_certificate_chain(sec_protocol_metadata_t metadata, + void (^handler)(sec_certificate_t certificate)); + +/*! + * @function sec_protocol_metadata_copy_ocsp_response + * + * @abstract + * Get the OCSP response from the protocol instance peer. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param handler + * A block to invoke one or more times with OCSP data + * + * @return Returns true if the OSCP response was accessible, false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_access_ocsp_response(sec_protocol_metadata_t metadata, + void (^handler)(dispatch_data_t ocsp_data)); + +/*! + * @function sec_protocol_metadata_access_supported_signature_algorithms + * + * @abstract + * Get the signature algorithms supported by the peer. Clients may call this + * in response to a challenge block. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param handler + * A block to invoke one or more times with OCSP data + * + * @return Returns true if the supported signature list was accessible, false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_access_supported_signature_algorithms(sec_protocol_metadata_t metadata, + void (^handler)(uint16_t signature_algorithm)); + +/*! + * @function sec_protocol_metadata_access_distinguished_names + * + * @abstract + * Get the X.509 Distinguished Names from the protocol instance peer. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param handler + * A block to invoke one or more times with distinguished_name data + * + * @return Returns true if the distinguished names were accessible, false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_access_distinguished_names(sec_protocol_metadata_t metadata, + void (^handler)(dispatch_data_t distinguished_name)); +#endif // __BLOCKS__ + +/*! + * @function sec_protocol_metadata_peers_are_equal + * + * @abstract + * Compare peer information for two `sec_protocol_metadata` instances. + * This comparison does not include protocol configuration options, e.g., ciphersuites. + * + * @param metadataA + * A `sec_protocol_metadata_t` instance. + * + * @param metadataB + * A `sec_protocol_metadata_t` instance. + * + * @return Returns true if both metadata values refer to the same peer, and false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_peers_are_equal(sec_protocol_metadata_t metadataA, sec_protocol_metadata_t metadataB); + +/*! + * @function sec_protocol_metadata_challenge_parameters_are_equal + * + * @abstract + * Compare challenge-relevant information for two `sec_protocol_metadata` instances. + * + * This comparison includes all information relevant to a challenge request, including: + * distinguished names, signature algorithms, and supported certificate types. + * See Section 7.4.4 of RFC5246 for more details. + * + * @param metadataA + * A `sec_protocol_metadata_t` instance. + * + * @param metadataB + * A `sec_protocol_metadata_t` instance. + * + * @return Returns true if both metadata values have the same challenge parameters. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_challenge_parameters_are_equal(sec_protocol_metadata_t metadataA, sec_protocol_metadata_t metadataB); + +/*! + * @function sec_protocol_metadata_create_secret + * + * @abstract + * Export a secret, e.g., a cryptographic key, derived from the protocol metadata using a label string. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param label_len + * Length of the KDF label string. + * + * @param label + * KDF label string. + * + * @param exporter_length + * Length of the secret to be exported. + * + * @return Returns a dispatch_data_t object carrying the exported secret. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED _Nullable dispatch_data_t +sec_protocol_metadata_create_secret(sec_protocol_metadata_t metadata, size_t label_len, + const char *label, size_t exporter_length); + +/*! + * @function sec_protocol_metadata_create_secret_with_context + * + * @abstract + * Export a secret, e.g., a cryptographic key, derived from the protocol metadata using a label and context string. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param label_len + * Length of the KDF label string. + * + * @param label + * KDF label string. + * + * @param context_len + * Length of the KDF context string. + * + * @param context + * Constant opaque context value + * + * @param exporter_length + * Length of the secret to be exported. + * + * @return Returns a dispatch_data_t object carrying the exported secret. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED _Nullable dispatch_data_t +sec_protocol_metadata_create_secret_with_context(sec_protocol_metadata_t metadata, size_t label_len, + const char *label, size_t context_len, + const uint8_t *context, size_t exporter_length); + +SEC_ASSUME_NONNULL_END + +__END_DECLS + +#endif // SecProtocolMetadata_h diff --git a/protocol/SecProtocolObject.h b/protocol/SecProtocolObject.h new file mode 100644 index 00000000..96c2445f --- /dev/null +++ b/protocol/SecProtocolObject.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018 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@ + */ + +#ifndef SecProtocolObject_h +#define SecProtocolObject_h + +#include +#include + +#if OS_OBJECT_USE_OBJC +# define SEC_OBJECT_DECL(type) OS_OBJECT_DECL(type) +#else // OS_OBJECT_USE_OBJC +# define SEC_OBJECT_DECL(type) \ +struct type; \ +typedef struct type *type##_t +#endif // OS_OBJECT_USE_OBJC + +#if __has_feature(assume_nonnull) +# define SEC_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define SEC_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +#else // !__has_feature(assume_nonnull) +# define SEC_ASSUME_NONNULL_BEGIN +# define SEC_ASSUME_NONNULL_END +#endif // !__has_feature(assume_nonnull) + +#if defined(__OBJC__) && __has_attribute(ns_returns_retained) +# define SEC_RETURNS_RETAINED __attribute__((__ns_returns_retained__)) +#else // __OBJC__ && ns_returns_retained +# define SEC_RETURNS_RETAINED +#endif // __OBJC__ && ns_returns_retained + +#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE +__BEGIN_DECLS +__attribute__((visibility("default"))) void *sec_retain(void *obj); +__attribute__((visibility("default"))) void sec_release(void *obj); +__END_DECLS +#else // !OS_OBJECT_USE_OBJC_RETAIN_RELEASE +#undef sec_retain +#undef sec_release +#define sec_retain(object) [(object) retain] +#define sec_release(object) [(object) release] +#endif // !OS_OBJECT_USE_OBJC_RETAIN_RELEASE + +#ifndef SEC_OBJECT_IMPL +/*! + * A `sec_object` is a generic, ARC-able type wrapper for common CoreFoundation Security types. + */ +SEC_OBJECT_DECL(sec_object); +#endif // !SEC_OBJECT_IMPL + +#endif // SecProtocolObject_h diff --git a/protocol/SecProtocolOptions.h b/protocol/SecProtocolOptions.h new file mode 100644 index 00000000..7770ba87 --- /dev/null +++ b/protocol/SecProtocolOptions.h @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2018 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@ + */ + +#ifndef SecProtocolOptions_h +#define SecProtocolOptions_h + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/*! + * The following diagram shows how clients interact with sec_protocol_options + * and sec_protocol_metadata when configuring and using network security protocols. + * + * +--------+ + * | Client | + * +-+---/ \+ + * | | + * +-------------+ +-------------+ + * | (1) set (2) get | + * | options metadata | + * +-----\ /---------------+ +------------+----------+ + * | sec_protocol_options | | sec_protocol_metadata | + * +-----------------------+ +-----------------------+ + * + * Clients configure security protocols with `sec_protocol_options` instances. + * And they inspect protocol instances using `sec_protocol_metadata` instances. + */ + +#ifndef SEC_OBJECT_IMPL +/*! + * A `sec_protocol_options` instance is a container of options for security protocol instances, + * such as TLS. Protocol options are used to configure security protocols in the network stack. + * For example, clients may set the maximum and minimum allowed TLS versions through protocol + * options. + */ +SEC_OBJECT_DECL(sec_protocol_options); +#endif // !SEC_OBJECT_IMPL + +__BEGIN_DECLS + +SEC_ASSUME_NONNULL_BEGIN + +/*! + * @function sec_protocol_options_set_local_identity + * + * @abstract + * Set the local identity to be used for this protocol instance. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param identity + * A `sec_identity_t` instance carrying the private key and certificate. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_local_identity(sec_protocol_options_t options, sec_identity_t identity); + +/*! + * @function sec_protocol_options_add_tls_ciphersuite + * + * @abstract + * Add a TLS ciphersuite to the set of enabled ciphersuites. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param ciphersuite + * A SSLCipherSuite value. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options, SSLCipherSuite ciphersuite); + +/*! + * @function sec_protocol_options_add_tls_ciphersuite_group + * + * @abstract + * Add a TLS ciphersuite group to the set of enabled ciphersuites. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param group + * A SSLCipherSuiteGroup value. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, SSLCiphersuiteGroup group); + +/*! + * @function sec_protocol_options_set_tls_min_version + * + * @abstract + * Set the minimum support TLS version. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param version + * A SSLProtocol enum value. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_min_version(sec_protocol_options_t options, SSLProtocol version); + +/*! + * @function sec_protocol_options_set_tls_max_version + * + * @abstract + * Set the maximum support TLS version. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param version + * A SSLProtocol enum value. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_max_version(sec_protocol_options_t options, SSLProtocol version); + +/*! + * @function sec_protocol_options_add_tls_application_protocol + * + * @abstract + * Add an application protocol supported by clients of this protocol instance. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param application_protocol + * A NULL-terminated string defining the application protocol. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_add_tls_application_protocol(sec_protocol_options_t options, const char *application_protocol); + +/*! + * @function sec_protocol_options_set_tls_server_name + * + * @abstract + * Set the server (domain) name to be used in the TLS SNI. This will override + * the server name obtained from the endpoint. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param server_name + * A NULL-terminated string carrying the server (domain) name. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_server_name(sec_protocol_options_t options, const char *server_name); + +/*! + * @function sec_protocol_options_set_tls_diffie_hellman_parameters + * + * @abstract + * Set the supported Diffie-Hellman parameters. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param params + * A dispatch_data_t containing legacy Diffie-Hellman parameters. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_diffie_hellman_parameters(sec_protocol_options_t options, dispatch_data_t params); + +/*! + * @function sec_protocol_options_add_pre_shared_key + * + * @abstract + * Add a pre-shared key (PSK) and its identity to the options. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param psk + * A dispatch_data_t containing a PSK blob. + * + * @param psk_identity + * A dispatch_data_t containing a PSK identity blob. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_add_pre_shared_key(sec_protocol_options_t options, dispatch_data_t psk, dispatch_data_t psk_identity); + +/*! + * @function sec_protocol_options_set_tls_tickets_enabled + * + * @abstract + * Enable or disable TLS session ticket support. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param tickets_enabled + * Flag to enable or disable TLS session ticket support. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_tickets_enabled(sec_protocol_options_t options, bool tickets_enabled); + +/*! + * @function sec_protocol_options_set_tls_is_fallback_attempt + * + * @abstract + * Signal if this is a TLS fallback attempt. + * + * A fallback attempt is one following a previously failed TLS connection + * due to version or parameter incompatibility, e.g., when speaking to a server + * that does not support a client-offered ciphersuite. + * + * Clients MUST NOT enable fallback for fresh connections. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param is_fallback_attempt + * Set a flag indicating that this is a TLS fallback attempt. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options, bool is_fallback_attempt); + +/*! + * @function sec_protocol_options_set_tls_resumption_enabled + * + * @abstract + * Enable or disable TLS session resumption. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param resumption_enabled + * Flag to enable or disable TLS session resumption. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_resumption_enabled(sec_protocol_options_t options, bool resumption_enabled); + +/*! + * @function sec_protocol_options_set_tls_false_start_enabled + * + * @abstract + * Enable or disable TLS False Start. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param false_start_enabled + * Flag to enable or disable TLS False Start. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_false_start_enabled(sec_protocol_options_t options, bool false_start_enabled); + +/*! + * @function nw_protocol_options_set_tls_ocsp_enabled + * + * @abstract + * Enable or disable OCSP support. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param ocsp_enabled + * Flag to enable or disable OCSP support. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_ocsp_enabled(sec_protocol_options_t options, bool ocsp_enabled); + +/*! + * @function sec_protocol_options_set_tls_sct_enabled + * + * @abstract + * Enable or disable SCT (signed certificate timestamp) support. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param sct_enabled + * Flag to enable or disable SCT support. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_sct_enabled(sec_protocol_options_t options, bool sct_enabled); + +/*! + * @function sec_protocol_options_set_tls_renegotiation_enabled + * + * @abstract + * Enable or disable TLS (1.2 and prior) session renegotiation. This defaults to `true`. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param renegotiation_enabled + * Flag to enable or disable TLS (1.2 and prior) session renegotiation. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_renegotiation_enabled(sec_protocol_options_t options, bool renegotiation_enabled); + +/*! + * @function sec_protocol_options_set_peer_authentication_required + * + * @abstract + * Enable or disable peer authentication. Clients default to true, whereas servers default to false. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param peer_authentication_required + * Flag to enable or disable mandatory peer authentication. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_peer_authentication_required(sec_protocol_options_t options, bool peer_authentication_required); + +#ifdef __BLOCKS__ + +/*! + * @block sec_protocol_key_update_complete_t + * + * @abstract + * Block to be invoked when a key update event is handled. + */ +typedef void (^sec_protocol_key_update_complete_t)(void); + +/*! + * @block sec_protocol_key_update_t + * + * @abstract + * Block to be invoked when the protocol key MUST be updated. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param complete + * A `sec_protocol_key_update_complete_t` to be invoked when the key update is complete. + */ +typedef void (^sec_protocol_key_update_t)(sec_protocol_metadata_t metadata, sec_protocol_key_update_complete_t complete); + +/*! + * @block sec_protocol_challenge_complete_t + * + * @abstract + * Block to be invoked when an identity (authentication) challenge is complete. + * + * @param identity + * A `sec_identity_t` containing the identity to use for this challenge. + */ +typedef void (^sec_protocol_challenge_complete_t)(sec_identity_t identity); + +/*! + * @block sec_protocol_challenge_t + * + * @abstract + * Block to be invoked when the protocol instance is issued a challenge (e.g., a TLS certificate request). + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param complete + * A `sec_protocol_challenge_complete_t` to be invoked when the challenge is complete. + */ +typedef void (^sec_protocol_challenge_t)(sec_protocol_metadata_t metadata, sec_protocol_challenge_complete_t complete); + +/*! + * @block sec_protocol_verify_complete_t + * + * @abstract + * Block to be invoked when verification is complete. + * + * @param result + * A `bool` indicating if verification succeeded or failed. + */ +typedef void (^sec_protocol_verify_complete_t)(bool result); + +/*! + * @block sec_protocol_verify_t + * + * @abstract + * Block to be invoked when the protocol instance must verify the peer. + * + * NOTE: this may be called one or more times for a given connection. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param trust_ref + * A `sec_trust_t` instance. + * + * @param complete + * A `sec_protocol_verify_finish_t` to be invoked when verification is complete. + */ +typedef void (^sec_protocol_verify_t)(sec_protocol_metadata_t metadata, sec_trust_t trust_ref, sec_protocol_verify_complete_t complete); + +/*! + * @function sec_protocol_options_set_key_update_block + * + * @abstract + * Set the key update block. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param key_update_block + * A `sec_protocol_key_update_t` block. + * + * @params key_update_queue + * A `dispatch_queue_t` on which the key update block should be called. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_key_update_block(sec_protocol_options_t options, sec_protocol_key_update_t key_update_block, dispatch_queue_t key_update_queue); + +/*! + * @function sec_protocol_options_set_challenge_block + * + * @abstract + * Set the challenge block. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @params challenge_block + * A `sec_protocol_challenge_t` block. + * + * @params challenge_queue + * A `dispatch_queue_t` on which the challenge block should be called. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_challenge_block(sec_protocol_options_t options, sec_protocol_challenge_t challenge_block, dispatch_queue_t challenge_queue); + +/*! + * @function sec_protocol_options_set_verify_block + * + * @abstract + * Set the verify block. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @params verify_block + * A `sec_protocol_verify_t` block. + * + * @params verify_block_queue + * A `dispatch_queue_t` on which the verify block should be called. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_verify_block(sec_protocol_options_t options, sec_protocol_verify_t verify_block, dispatch_queue_t verify_block_queue); + +#endif // __BLOCKS__ + +SEC_ASSUME_NONNULL_END + +__END_DECLS + +#endif // SecProtocolOptions_h diff --git a/protocol/SecProtocolPriv.h b/protocol/SecProtocolPriv.h new file mode 100644 index 00000000..77aff1a3 --- /dev/null +++ b/protocol/SecProtocolPriv.h @@ -0,0 +1,342 @@ +// +// SecProtocolPriv.h +// Security +// + +#ifndef SecProtocolPriv_h +#define SecProtocolPriv_h + +#include +#include + +__BEGIN_DECLS + +typedef struct sec_protocol_options_content { + SSLProtocol min_version; + SSLProtocol max_version; + + void *ciphersuites; // xpc_object_t (array of uint64) + + void *application_protocols; // xpc_object_t (array of strings) + + void *identity; // sec_identity_t + char *server_name; + + void *pre_shared_keys; // xpc_object_t (array of (data, identity)) + + void *key_update_block; // sec_protocol_key_update_t + void *key_update_queue; // dispatch_queue_t + void *challenge_block; // sec_protocol_challenge_t + void *challenge_queue; // dispatch_queue_t + void *verify_block; // sec_protocol_verify_t + void *verify_queue; // dispatch_queue_t + + void *dh_params; // dispatch_data_t + + void *custom_extensions; // sec_array_t of sec_tls_extension_t + + unsigned disable_sni : 1; + unsigned enable_fallback_attempt : 1; + unsigned enable_false_start : 1; + unsigned enable_tickets : 1; + unsigned enable_sct : 1; + unsigned enable_ocsp : 1; + unsigned enforce_ev : 1; + unsigned enable_resumption : 1; + unsigned enable_renegotiation : 1; + unsigned enable_early_data : 1; + unsigned peer_authentication_required : 1; + unsigned peer_authentication_override : 1; +} *sec_protocol_options_content_t; + +typedef dispatch_data_t (*sec_protocol_metadata_exporter)(void * handle, size_t label_len, const char *label, + size_t context_len, const uint8_t *context, size_t exporter_len); + +typedef struct sec_protocol_metadata_content { + void *peer_certificate_chain; // sec_array_t of sec_certificate_t + void *peer_public_key; // dispatch_data_t + + const char *negotiated_protocol; + + SSLProtocol negotiated_protocol_version; + SSLCipherSuite negotiated_ciphersuite; + + void *supported_signature_algorithms; // xpc_object_t (array of uint64) + void *request_certificate_types; // dispatch_data + void *ocsp_response; // sec_array_t of dispatch_data + void *distinguished_names; // sec_array_t of dispatch_data + + void *exporter_context; // Opaque context for the exporter function + sec_protocol_metadata_exporter exporter_function; // Exporter function pointer. This MUST be set by the metadata allocator. + + unsigned early_data_accepted : 1; + unsigned false_start_used : 1; + unsigned ticket_offered : 1; + unsigned ticket_received : 1; + unsigned session_resumed : 1; + unsigned session_renewed : 1; + + // Struct padding + unsigned __pad_bits : 2; +} *sec_protocol_metadata_content_t; + +#ifndef SEC_OBJECT_IMPL +SEC_OBJECT_DECL(sec_array); +#endif // !SEC_OBJECT_IMPL + +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED sec_array_t +sec_array_create(void); + +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_array_append(sec_array_t array, sec_object_t object); + +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +size_t +sec_array_get_count(sec_array_t array); + +#ifdef __BLOCKS__ +typedef bool (^sec_array_applier_t) (size_t index, sec_object_t object); + +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_array_apply(sec_array_t array, sec_array_applier_t applier); + +#ifdef __BLOCKS__ +/*! + * @block sec_protocol_tls_ext_add_callback + * + * @param metadata + * A valid `sec_protocol_metadata_t` instance. + * + * @param extension_type + * The 2-byte identifier for the extension. + * + * @param data + * Pointer to a uint8_t buffer where the encoded extension data is located. + * + * @param data_length + * Pointer to a variable containing the data length. This should be set to the size of the `data` buffer. + * + * @param error + * Pointer to a return error code that's populated in the event of an error. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +typedef int (^sec_protocol_tls_ext_add_callback)(sec_protocol_metadata_t metadata, uint16_t extension_type, + const uint8_t **data, size_t *data_length, int *error); + +/*! + * @block sec_protocol_tls_ext_free_callback + * + * @param metadata + * A valid `sec_protocol_metadata_t` instance. + * + * @param extension_type + * The 2-byte identifier for the extension. + * + * @param data + * Pointer to a uint8_t buffer where the encoded extension data is located. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +typedef void (^sec_protocol_tls_ext_free_callback)(sec_protocol_metadata_t metadata, uint16_t extension_type, + const uint8_t *data); + +/*! + * @block sec_protocol_tls_ext_parse_callback + * + * @param metadata + * A valid `sec_protocol_metadata_t` handle. + * + * @param extension_type + * The 2-byte identifier for the extension. + * + * @param data + * A buffer where the encoded extension data is stored. + * + * @param data_length + * Length of the encoded extension data. + * + * @param error + * Pointer to a return error code that's populated in the event of an error. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +typedef int (^sec_protocol_tls_ext_parse_callback)(sec_protocol_metadata_t metadata, uint16_t extension_type, + const uint8_t *data, size_t data_length, + int *error); +#endif // __BLOCKS__ + +#ifndef SEC_OBJECT_IMPL +SEC_OBJECT_DECL(sec_tls_extension); +#endif // !SEC_OBJECT_IMPL + +#ifdef __BLOCKS__ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +uint16_t +sec_tls_extension_get_type(sec_tls_extension_t extension); + +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED sec_protocol_tls_ext_add_callback +sec_tls_extension_copy_add_block(sec_tls_extension_t extension); + +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED sec_protocol_tls_ext_parse_callback +sec_tls_extension_copy_parse_block(sec_tls_extension_t extension); + +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED sec_protocol_tls_ext_free_callback +sec_tls_extension_copy_free_block(sec_tls_extension_t extension); + +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +sec_tls_extension_t +sec_tls_extension_create(uint16_t type, sec_protocol_tls_ext_add_callback add_block, + sec_protocol_tls_ext_parse_callback parse_block, + sec_protocol_tls_ext_free_callback free_block); +#endif // __BLOCKS__ + +/*! + * @function sec_protocol_options_add_tls_extension + * + * @abstract + * Add support for a custom TLS extension. + * + * Clients such as QUIC use this when custom TLS extensions are needed. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param extension + * A `sec_tls_extension_t` instance. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_add_tls_extension(sec_protocol_options_t options, sec_tls_extension_t extension); + +#endif // __BLOCKS__ + +/*! + * @function sec_protocol_options_set_tls_early_data_enabled + * + * @abstract + * Enable or disable early (0-RTT) data for TLS. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param early_data_enabled + * Flag to enable or disable early (0-RTT) data. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options, bool early_data_enabled); + +/*! + * @function sec_protocol_options_set_tls_sni_disabled + * + * @abstract + * Enable or disable the TLS SNI extension. This defaults to `false`. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param sni_disabled + * Flag to enable or disable use of the TLS SNI extension. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options, bool sni_disabled); + +/*! + * @function sec_protocol_options_set_enforce_ev + * + * @abstract + * Enable or disable EV enforcement. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param enforce_ev + * Flag to determine if EV is enforced. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +void +sec_protocol_options_set_enforce_ev(sec_protocol_options_t options, bool enforce_ev); + +/*! + * @function sec_protocol_metadata_get_tls_false_start_used + * + * @abstract + * Determine if False Start was used. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return True if False Start was used, and false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_get_tls_false_start_used(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_ticket_offered + * + * @abstract + * Determine if a ticket was offered for session resumption. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return True if a ticket was offered for resumption, and false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_get_ticket_offered(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_ticket_received + * + * @abstract + * Determine if a ticket was received upon completing the new connection. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return True if a ticket was received from the peer (server), and false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_get_ticket_received(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_session_resumed + * + * @abstract + * Determine if this new connection was a session resumption. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return True if this new connection was resumed, and false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_get_session_resumed(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_session_renewed + * + * @abstract + * Determine if this resumed connection was renewed with a new ticket. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return True if this resumed connection was renewed with a new ticket, and false otherwise. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata); + +__END_DECLS + +#endif /* SecProtocolPriv_h */ diff --git a/protocol/SecProtocolTypes.h b/protocol/SecProtocolTypes.h new file mode 100644 index 00000000..98104cd9 --- /dev/null +++ b/protocol/SecProtocolTypes.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2018 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@ + */ + +#ifndef SecProtocolTypes_h +#define SecProtocolTypes_h + +#include +#include +#include +#include + +#ifndef SEC_OBJECT_IMPL +/*! + * These are os_object compatible and ARC-able wrappers around existing CoreFoundation + * Security types, including: SecTrustRef, SecIdentityRef, and SecCertificateRef. They allow + * clients to use these types in os_object-type APIs and data structures. The underlying + * CoreFoundation types may be extracted and used by clients as needed. + */ +SEC_OBJECT_DECL(sec_trust); +SEC_OBJECT_DECL(sec_identity); +SEC_OBJECT_DECL(sec_certificate); +#endif // !SEC_OBJECT_IMPL + +SEC_ASSUME_NONNULL_BEGIN + +/*! + * @function sec_trust_create + * + * @abstract + * Create an ARC-able `sec_trust_t` instance from a `SecTrustRef`. + * + * @param trust + * A `SecTrustRef` instance. + * + * @return a `sec_trust_t` instance. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED _Nullable sec_trust_t +sec_trust_create(SecTrustRef __nonnull trust); + +/*! + * @function sec_trust_copy_ref + * + * @abstract + * Copy a retained reference to the underlying `SecTrustRef` instance. + * + * @param trust + * A `sec_trust_t` instance. + * + * @return The underlying `SecTrustRef` instance. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SecTrustRef +sec_trust_copy_ref(sec_trust_t __nonnull trust); + +/*! + * @function sec_identity_create + * + * @abstract + * Create an ARC-able `sec_identity_t` instance from a `SecIdentityRef`. + * + * @param identity + * A `SecIdentityRef` instance. + * + * @return a `sec_identity_t` instance. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED _Nullable sec_identity_t +sec_identity_create(SecIdentityRef __nonnull identity); + +/*! + * @function sec_identity_create_with_certificates + * + * @abstract + * Create an ARC-able `sec_identity_t` instance from a `SecIdentityRef` and + * array of SecCertificateRef instances. + * + * @param identity + * A `SecIdentityRef` instance. + * + * @param certificates + * An array of `SecCertificateRef` instances. + * + * @return a `sec_identity_t` instance. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED _Nullable sec_identity_t +sec_identity_create_with_certificates(SecIdentityRef __nonnull identity, CFArrayRef __nonnull certificates); + +/*! + * @function sec_identity_copy_ref + * + * @abstract + * Copy a retained reference to the underlying `SecIdentityRef` instance. + * + * @param identity + * A `sec_identity_t` instance. + * + * @return The underlying `SecIdentityRef` instance. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SecIdentityRef +sec_identity_copy_ref(sec_identity_t __nonnull identity); + +/*! + * @function sec_identity_copy_certificates_ref + * + * @abstract + * Copy a retained reference to the underlying `CFArrayRef` container of `SecCertificateRef` types. + * + * @param identity + * A `sec_identity_t` instance. + * + * @return The underlying `CFArrayRef` container with `SecCertificateRef` instances. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +CFArrayRef +sec_identity_copy_certificates_ref(sec_identity_t __nonnull identity); + +/*! + * @function sec_certificate_create + * + * @abstract + * Create an ARC-able `sec_certificate_t` instance from a `SecCertificateRef`. + * + * @param certificate + * A `SecCertificateRef` instance. + * + * @return a `sec_certificate_t` instance. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED _Nullable sec_certificate_t +sec_certificate_create(SecCertificateRef __nonnull certificate); + +/*! + * @function sec_certificate_copy_ref + * + * @abstract + * Copy a retained reference to the underlying `SecCertificateRef` instance. + * + * @param certificate + * A `sec_certificate_t` instance. + * + * @return The underlying `SecCertificateRef` instance. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SecCertificateRef +sec_certificate_copy_ref(sec_certificate_t __nonnull certificate); + +SEC_ASSUME_NONNULL_END + +#endif // SecProtocolTypes_h diff --git a/protocol/SecProtocolTypes.m b/protocol/SecProtocolTypes.m new file mode 100644 index 00000000..04666e39 --- /dev/null +++ b/protocol/SecProtocolTypes.m @@ -0,0 +1,417 @@ +// +// SecProtocolTypes.m +// Security +// + +#include "utilities/SecCFRelease.h" + +#define OS_OBJECT_HAVE_OBJC_SUPPORT 1 + +#define SEC_NULL_BAD_INPUT ((void *_Nonnull)NULL) +#define SEC_NULL_OUT_OF_MEMORY SEC_NULL_BAD_INPUT + +#define SEC_NIL_BAD_INPUT ((void *_Nonnull)nil) +#define SEC_NIL_OUT_OF_MEMORY SEC_NIL_BAD_INPUT + +#define SEC_CONCRETE_CLASS_NAME(external_type) SecConcrete_##external_type +#define SEC_CONCRETE_PREFIX_STR "SecConcrete_" + +#define SEC_OBJECT_DECL_INTERNAL_OBJC(external_type) \ + @class SEC_CONCRETE_CLASS_NAME(external_type); \ + typedef SEC_CONCRETE_CLASS_NAME(external_type) *external_type##_t + +#define SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL_AND_VISBILITY(external_type, _protocol, visibility, ...) \ + @protocol OS_OBJECT_CLASS(external_type) <_protocol> \ + @end \ + visibility \ + @interface SEC_CONCRETE_CLASS_NAME(external_type) : NSObject \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wobjc-interface-ivars\"") \ + __VA_ARGS__ \ + _Pragma("clang diagnostic pop") \ + @end \ + typedef int _useless_typedef_oio_##external_type + +#define SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL(external_type, _protocol, ...) \ + SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL_AND_VISBILITY(external_type, _protocol, ,__VA_ARGS__) + +#define SEC_OBJECT_IMPL_INTERNAL_OBJC(external_type, ...) \ + SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL(external_type, NSObject, ##__VA_ARGS__) + +#define SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_VISIBILITY(external_type, visibility, ...) \ + SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL_AND_VISBILITY(external_type, NSObject, visibility, ##__VA_ARGS__) + +#define SEC_OBJECT_IMPL 1 + +SEC_OBJECT_DECL_INTERNAL_OBJC(sec_array); +SEC_OBJECT_DECL_INTERNAL_OBJC(sec_identity); +SEC_OBJECT_DECL_INTERNAL_OBJC(sec_trust); +SEC_OBJECT_DECL_INTERNAL_OBJC(sec_certificate); +SEC_OBJECT_DECL_INTERNAL_OBJC(sec_tls_extension); +SEC_OBJECT_DECL_INTERNAL_OBJC(sec_object); +SEC_OBJECT_DECL_INTERNAL_OBJC(sec_protocol_options); +SEC_OBJECT_DECL_INTERNAL_OBJC(sec_protocol_metadata); + +#import + +#import +#import +#import +#import + +#import + +#ifndef SEC_ANALYZER_HIDE_DEADSTORE +# ifdef __clang_analyzer__ +# define SEC_ANALYZER_HIDE_DEADSTORE(var) do { if (var) {} } while (0) +# else // __clang_analyzer__ +# define SEC_ANALYZER_HIDE_DEADSTORE(var) do {} while (0) +# endif // __clang_analyzer__ +#endif // SEC_ANALYZER_HIDE_DEADSTORE + +SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_array, +{ + xpc_object_t xpc_array; +}); + +@implementation SEC_CONCRETE_CLASS_NAME(sec_array) + +- (instancetype)init +{ + self = [super init]; + if (self == nil) { + return SEC_NIL_OUT_OF_MEMORY; + } + self->xpc_array = xpc_array_create(NULL, 0); + return self; +} + +- (void)dealloc +{ + if (self->xpc_array != nil) { + xpc_array_apply(self->xpc_array, ^bool(size_t index, __unused xpc_object_t value) { + void *pointer = xpc_array_get_pointer(self->xpc_array, index); + sec_object_t object = (sec_object_t)CFBridgingRelease(pointer); + SEC_ANALYZER_HIDE_DEADSTORE(object); + object = nil; + return true; + }); + self->xpc_array = nil; + } +} + +sec_array_t +sec_array_create(void) +{ + return [[SEC_CONCRETE_CLASS_NAME(sec_array) alloc] init]; +} + +void +sec_array_append(sec_array_t array, sec_object_t object) +{ + if (array != NULL && + array->xpc_array != NULL && xpc_get_type(array->xpc_array) == XPC_TYPE_ARRAY && + object != NULL) { + void *retained_pointer = __DECONST(void *, CFBridgingRetain(object)); + xpc_array_set_pointer(array->xpc_array, XPC_ARRAY_APPEND, retained_pointer); + // 'Leak' the retain, and save the pointer into the array + } +} + +size_t +sec_array_get_count(sec_array_t array) +{ + if (array != NULL && + array->xpc_array != NULL && xpc_get_type(array->xpc_array) == XPC_TYPE_ARRAY) { + return xpc_array_get_count(array->xpc_array); + } + return 0; +} + +bool +sec_array_apply(sec_array_t array, sec_array_applier_t applier) +{ + if (array != NULL && + array->xpc_array != NULL && xpc_get_type(array->xpc_array) == XPC_TYPE_ARRAY) { + return xpc_array_apply(array->xpc_array, ^bool(size_t index, __unused xpc_object_t value) { + void *pointer = xpc_array_get_pointer(array->xpc_array, index); + return applier(index, (__bridge sec_object_t)(pointer)); + }); + } + return false; +} + +@end + +SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_identity, +{ + SecIdentityRef identity; + CFArrayRef certs; +}); + +@implementation SEC_CONCRETE_CLASS_NAME(sec_identity) + +- (instancetype)initWithIdentity:(SecIdentityRef)_identity +{ + if (_identity == NULL) { + return SEC_NIL_BAD_INPUT; + } + + self = [super init]; + if (self == nil) { + return SEC_NIL_OUT_OF_MEMORY; + } + self->identity = __DECONST(SecIdentityRef, CFRetainSafe(_identity)); + return self; +} + +- (instancetype)initWithIdentityAndCertificates:(SecIdentityRef)_identity certificates:(CFArrayRef)certificates +{ + if (_identity == NULL) { + return SEC_NIL_BAD_INPUT; + } + + self = [super init]; + if (self == nil) { + return SEC_NIL_OUT_OF_MEMORY; + } + self->identity = __DECONST(SecIdentityRef, CFRetainSafe(_identity)); + self->certs = __DECONST(CFArrayRef, CFRetainSafe(certificates)); + + return self; +} + +- (void)dealloc +{ + if (self->identity != NULL) { + CFRelease(self->identity); + self->identity = NULL; + + if (self->certs) { + CFRelease(self->certs); + } + self->certs = NULL; + } +} + +sec_identity_t +sec_identity_create(SecIdentityRef identity) +{ + return [[SEC_CONCRETE_CLASS_NAME(sec_identity) alloc] initWithIdentity:identity]; +} + +sec_identity_t +sec_identity_create_with_certificates(SecIdentityRef identity, CFArrayRef certificates) +{ + return [[SEC_CONCRETE_CLASS_NAME(sec_identity) alloc] initWithIdentityAndCertificates:identity certificates:certificates]; +} + +SecIdentityRef +sec_identity_copy_ref(sec_identity_t object) +{ + if (object == NULL) { + return SEC_NULL_BAD_INPUT; + } + if (object->identity != NULL) { + return __DECONST(SecIdentityRef, CFRetain(object->identity)); + } + return SEC_NULL_BAD_INPUT; +} + +CFArrayRef +sec_identity_copy_certificates_ref(sec_identity_t object) +{ + if (object == NULL) { + return SEC_NULL_BAD_INPUT; + } + if (object->certs != NULL) { + return __DECONST(CFArrayRef, CFRetain(object->certs)); + } + return SEC_NULL_BAD_INPUT; +} + +@end + +SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_certificate, +{ + SecCertificateRef certificate; +}); + +@implementation SEC_CONCRETE_CLASS_NAME(sec_certificate) + +- (instancetype)initWithCertificate:(SecCertificateRef)_certificate +{ + if (_certificate == NULL) { + return SEC_NIL_BAD_INPUT; + } + + self = [super init]; + if (self == nil) { + return SEC_NIL_OUT_OF_MEMORY; + } + self->certificate = __DECONST(SecCertificateRef, CFRetainSafe(_certificate)); + return self; +} + +- (void)dealloc +{ + if (self->certificate != NULL) { + CFRelease(self->certificate); + self->certificate = NULL; + } +} + +sec_certificate_t +sec_certificate_create(SecCertificateRef certificate) +{ + return [[SEC_CONCRETE_CLASS_NAME(sec_certificate) alloc] initWithCertificate:certificate]; +} + +SecCertificateRef +sec_certificate_copy_ref(sec_certificate_t object) +{ + if (object == NULL) { + return SEC_NULL_BAD_INPUT; + } + if (object->certificate != NULL) { + return __DECONST(SecCertificateRef, CFRetain(object->certificate)); + } + return SEC_NULL_BAD_INPUT; +} + +@end + +SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_trust, +{ + SecTrustRef trust; +}); + +@implementation SEC_CONCRETE_CLASS_NAME(sec_trust) + +- (instancetype)initWithTrust:(SecTrustRef)_trust +{ + if (_trust == NULL) { + return SEC_NIL_BAD_INPUT; + } + + self = [super init]; + if (self == nil) { + return SEC_NIL_OUT_OF_MEMORY; + } + self->trust = __DECONST(SecTrustRef, CFRetainSafe(_trust)); + return self; +} + +- (void)dealloc +{ + if (self->trust != NULL) { + CFRelease(self->trust); + self->trust = NULL; + } +} + +sec_trust_t +sec_trust_create(SecTrustRef trust) +{ + return [[SEC_CONCRETE_CLASS_NAME(sec_trust) alloc] initWithTrust:trust]; +} + +SecTrustRef +sec_trust_copy_ref(sec_trust_t object) +{ + if (object == NULL) { + return SEC_NULL_BAD_INPUT; + } + if (object->trust != NULL) { + return __DECONST(SecTrustRef, CFRetain(object->trust)); + } + return SEC_NULL_BAD_INPUT; +} + +@end + +SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_tls_extension, +{ + uint16_t type; + sec_protocol_tls_ext_add_callback adder; + sec_protocol_tls_ext_parse_callback parser; + sec_protocol_tls_ext_free_callback freer; +}); + +@implementation SEC_CONCRETE_CLASS_NAME(sec_tls_extension) + +- (instancetype)initWithCallbacks:(uint16_t)ext_type + adder:(sec_protocol_tls_ext_add_callback)add_block + parser:(sec_protocol_tls_ext_parse_callback)parse_block + freer:(sec_protocol_tls_ext_free_callback)free_block +{ + if (add_block == nil) { + return SEC_NIL_BAD_INPUT; + } + if (parse_block == nil) { + return SEC_NIL_BAD_INPUT; + } + if (free_block == nil) { + return SEC_NIL_BAD_INPUT; + } + + self = [super init]; + if (self == nil) { + return SEC_NIL_OUT_OF_MEMORY; + } + + self->type = ext_type; + self->adder = add_block; + self->parser = parse_block; + self->freer = free_block; + return self; +} + +uint16_t +sec_tls_extension_get_type(sec_tls_extension_t extension) +{ + if (extension == NULL) { + return 0; + } + + return extension->type; +} + +sec_protocol_tls_ext_add_callback +sec_tls_extension_copy_add_block(sec_tls_extension_t extension) +{ + if (extension == NULL) { + return SEC_NULL_BAD_INPUT; + } + + return extension->adder; +} + +sec_protocol_tls_ext_parse_callback +sec_tls_extension_copy_parse_block(sec_tls_extension_t extension) +{ + if (extension == NULL) { + return SEC_NULL_BAD_INPUT; + } + + return extension->parser; +} + +sec_protocol_tls_ext_free_callback +sec_tls_extension_copy_free_block(sec_tls_extension_t extension) +{ + if (extension == NULL) { + return SEC_NULL_BAD_INPUT; + } + + return extension->freer; +} + +sec_tls_extension_t +sec_tls_extension_create(uint16_t type, sec_protocol_tls_ext_add_callback adder, sec_protocol_tls_ext_parse_callback parser, sec_protocol_tls_ext_free_callback freer) +{ + return [[SEC_CONCRETE_CLASS_NAME(sec_tls_extension) alloc] initWithCallbacks:type adder:adder parser:parser freer:freer]; +} + +@end + diff --git a/resources/English.lproj/Certificate.strings b/resources/English.lproj/Certificate.strings index 04daf46f712b2b7122307580778de9c8cb278638..f37a57812e64b184b9e4c5eadf1b3a77a82cd7c5 100644 GIT binary patch delta 152 zcmZ2;l5yK<#tnUOlRs#98HY0DF(fi1G2}3$GAJ;VFysTtB!*IkOrS^#ke$qs0hG@K ps)ETDP4@Mdx7TA(0*crIu@VEBW-#haPL!3N9Kg!9c|jZx8vvToAr}Au delta 26 icmdmXnsLoZ#tnUOlM7^dCI_&xO*T+V*vyr%h7|yn7YW7y diff --git a/resources/English.lproj/SharedWebCredentials.strings b/resources/English.lproj/SharedWebCredentials.strings index 2b6f90d368337a0c0a37a748c871dd8336c9fd4f..2e0c69b47dccbad7ae83df3bd40da7685915ad18 100644 GIT binary patch delta 280 zcmbQEzE5MrCl=FihJ1!nh8%_z1_g#nFk1o0%VfxANCk?N07VoSiWw3a%AouVpj`3f zi7cY^nGAVwJw-rPCWA9jC&)CAS>8bPl?=%Y89==dl@PN^fu?~>E(eO10A&?`@&!Ox z3})ql^_BxwBmqT0DpJ8R`Cz*ef#&A`)q&k9$^f!71*o75s4y9<(4JxP0k*u&7g+V! zCaVa@Oy=X^n%pEPB&ool22|?^RFw>NU>?w5kcGvYC3$8tG6Q`#c_ClxW*fc)Rsi1^ BI(q;B delta 64 zcmdm|F-LvFCzi=a*wiLVaPu%GPFCa=p8SA$#%4P859^Y8S;Q+@aDZd UGZ`mK2}w;h5G>eyk1v500GRX>TmS$7 diff --git a/resources/English.lproj/Trust.strings b/resources/English.lproj/Trust.strings index 7eac8dea065081c6ecefebe087a98d3dd624d042..b56f74c86d1d5544478c0f53f85e253d73e818f7 100644 GIT binary patch delta 40 vcmcan-B7n-6XWCn1+K|S3UZTgF;19#PeEXEj0MMJJuVF(+hFr1Ml~A%QrZtc delta 16 YcmZpuyHUMi6XWCu)*PE3G0E8g07mWyTmS$7 diff --git a/secdxctests/CDKeychainTests.m b/secdxctests/CDKeychainTests.m new file mode 100644 index 00000000..1a736d23 --- /dev/null +++ b/secdxctests/CDKeychainTests.m @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "SecCDKeychain.h" +#import "CKKS.h" +#import "spi.h" +#import "SecItemServer.h" +#import "SecdTestKeychainUtilities.h" +#import "server_security_helpers.h" +#import "SecDbKeychainItemV7.h" +#import "KeychainXCTest.h" +#import "SecCDKeychainManagedItem+CoreDataClass.h" +#import "SecFileLocations.h" +#import +#import +#import +#import + +#if USE_KEYSTORE + +@interface SecCDKeychain (UnitTestingRedeclarations) + +@property (readonly, getter=_queue) dispatch_queue_t queue; + +- (void)_registerItemTypeForTesting:(SecCDKeychainItemType*)itemType; + +- (void)performOnManagedObjectQueue:(void (^)(NSManagedObjectContext* context, NSError* error))block; +- (void)performOnManagedObjectQueueAndWait:(void (^)(NSManagedObjectContext* context, NSError* error))block; +- (SecCDKeychainManagedItem*)fetchManagedItemForPersistentID:(NSUUID*)persistentID withManagedObjectContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error; + +- (NSData*)_onQueueGetDatabaseKeyDataWithError:(NSError**)error; +- (void)_onQueueDropClassAPersistentStore; + +@end + +@interface SecCDKeychainItem (UnitTestingRedeclarations) + +- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error; + +@end + +@interface TestItemType : SecCDKeychainItemType +@end + +@implementation TestItemType + ++ (instancetype)itemType +{ + return [[self alloc] _initWithName:@"TestItem" version:1 primaryKeys:nil syncableKeys:nil]; +} + +@end + +@interface CDKeychainTests : KeychainXCTest +@end + +@implementation CDKeychainTests { + SecCDKeychain* _keychain; + SFKeychainServerFakeConnection* _connection; +} + +- (void)setUp +{ + [super setUp]; + + NSURL* persistentStoreURL = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"CDKeychain"); + NSBundle* resourcesBundle = [NSBundle bundleWithPath:@"/System/Library/Keychain/KeychainResources.bundle"]; + NSURL* managedObjectModelURL = [resourcesBundle URLForResource:@"KeychainModel" withExtension:@"momd"]; + _keychain = [[SecCDKeychain alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectModelURL encryptDatabase:false]; + _connection = [[SFKeychainServerFakeConnection alloc] init]; + + self.keychainPartialMock = OCMPartialMock(_keychain); + [[[[self.keychainPartialMock stub] andCall:@selector(getDatabaseKeyDataithError:) onObject:self] ignoringNonObjectArgs] _onQueueGetDatabaseKeyDataWithError:NULL]; + + [_keychain _registerItemTypeForTesting:[TestItemType itemType]]; +} + +- (void)tearDown +{ + [self.keychainPartialMock stopMocking]; + self.keychainPartialMock = nil; + + [super tearDown]; +} + +- (NSArray*)lookupTuplesForAttributes:(NSDictionary*)attributes +{ + NSMutableArray* lookupTuples = [[NSMutableArray alloc] initWithCapacity:attributes.count]; + [attributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id value, BOOL* stop) { + [lookupTuples addObject:[SecCDKeychainLookupTuple lookupTupleWithKey:key value:value]]; + }]; + return lookupTuples; +} + +- (void)testInsertAndRetrieveItemWithPersistentID +{ + SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"]; + + NSUUID* persistentID = [NSUUID UUID]; + SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecret"} owner:owner keyclass:key_class_ak]; + + XCTestExpectation* insertExpectation = [self expectationWithDescription:@"insert item"]; + [_keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertTrue(success, @"should have been able to insert item"); + XCTAssertNil(error, @"should not have gotten an error inserting item"); + [insertExpectation fulfill]; + }]; + [self waitForExpectations:@[insertExpectation] timeout:5.0]; + + XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch item"]; + [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) { + XCTAssertNotNil(fetchedItem, @"should have been able to fetch item"); + XCTAssertNil(error, @"should not have gotten an error fetching item"); + XCTAssertEqualObjects(fetchedItem, item, @"fetched item should match inserted item"); + [fetchExpectation fulfill]; + }]; + [self waitForExpectations:@[fetchExpectation] timeout:5.0]; +} + +- (SecCDKeychainItem*)fullItemForItemMetadata:(SecCDKeychainItemMetadata*)metadata +{ + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block SecCDKeychainItem* result = nil; + [metadata fetchFullItemWithKeychain:_keychain withConnection:_connection completionHandler:^(SecCDKeychainItem* item, NSError* error) { + result = item; + dispatch_semaphore_signal(semaphore); + }]; + dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)); + return result; +} + +- (void)testLookupItemByAttribute +{ + NSUUID* firstItemID = [NSUUID UUID]; + NSUUID* secondItemID = [NSUUID UUID]; + NSDictionary* firstItemAttributes = @{@"attribute1" : @"gotIt", @"sharedAttribute" : @"first"}; + NSDictionary* secondItemAttributes = @{@"attribute2" : @"gotIt", @"sharedAttribute" : @"second"}; + NSArray* firstItemLookupAttributes = [self lookupTuplesForAttributes:firstItemAttributes]; + NSArray* secondItemLookupAttributes = [self lookupTuplesForAttributes:secondItemAttributes]; + + SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"]; + SecCDKeychainItem* firstItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:firstItemID attributes:firstItemAttributes lookupAttributes:firstItemLookupAttributes secrets:@{@"data" : @"I'm the first"} owner:owner keyclass:key_class_ak]; + SecCDKeychainItem* secondItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:secondItemID attributes:secondItemAttributes lookupAttributes:secondItemLookupAttributes secrets:@{@"data" : @"I'm the second"} owner:owner keyclass:key_class_ak]; + + XCTestExpectation* insertExpection = [self expectationWithDescription:@"insert items"]; + [_keychain insertItems:@[firstItem, secondItem] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertTrue(success, @"failed to successfully insert items with error: %@", error); + XCTAssertNil(error, @"encountered error inserting items: %@", error); + [insertExpection fulfill]; + }]; + [self waitForExpectations:@[insertExpection] timeout:5.0]; + + XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch items"]; + [_keychain fetchItemsWithValue:@"gotIt" forLookupKey:@"attribute1" ofType:SecCDKeychainLookupValueTypeString withConnection:_connection completionHandler:^(NSArray* items, NSError* error) { + XCTAssertEqual(items.count, (unsigned long)1, @"did not get the expected number of fetched items; expected 1, but got %d", (int)items.count); + SecCDKeychainItem* fetchedItem = [self fullItemForItemMetadata:items.firstObject]; + XCTAssertNotNil(fetchedItem, @"failed to fetch item we just inserted with error: %@", error); + XCTAssertNil(error, @"encountered error fetching item: %@", error); + XCTAssertEqualObjects(fetchedItem, firstItem, @"fetched item does not match the item we expected to fetch"); + [fetchExpectation fulfill]; + }]; + + XCTestExpectation* secondFetchExpectation = [self expectationWithDescription:@"second fetch"]; + [_keychain fetchItemsWithValue:@"first" forLookupKey:@"sharedAttribute" ofType:SecCDKeychainLookupValueTypeString withConnection:_connection completionHandler:^(NSArray* items, NSError* error) { + XCTAssertEqual(items.count, (unsigned long)1, @"did not get the expected number of fetched items; expected 1, but got %d", (int)items.count); + SecCDKeychainItem* fetchedItem = [self fullItemForItemMetadata:items.firstObject]; + XCTAssertNotNil(fetchedItem, @"failed to fetch item we just inserted with error: %@", error); + XCTAssertNil(error, @"encountered error fetching item: %@", error); + XCTAssertEqualObjects(fetchedItem, firstItem, @"fetched item does not match the item we expected to fetch"); + [secondFetchExpectation fulfill]; + }]; + [self waitForExpectations:@[fetchExpectation, secondFetchExpectation] timeout:5.0]; +} + +- (void)testLookupMultipleItems +{ + NSUUID* firstItemID = [NSUUID UUID]; + NSUUID* secondItemID = [NSUUID UUID]; + NSUUID* thirdUUID = [NSUUID UUID]; + NSDictionary* firstItemAttributes = @{@"attribute1" : @"gotIt", @"sharedAttribute" : @"bothHaveThis"}; + NSDictionary* secondItemAttributes = @{@"attribute2" : @"gotIt", @"sharedAttribute" : @"bothHaveThis"}; + NSDictionary* thirdItemAttributes = @{@"attribute3" : @"gotIt", @"sharedAttribute" : @"somethingDifferent"}; + NSArray* firstItemLookupAttributes = [self lookupTuplesForAttributes:firstItemAttributes]; + NSArray* secondItemLookupAttributes = [self lookupTuplesForAttributes:secondItemAttributes]; + NSArray* thirdItemLookupAttributes = [self lookupTuplesForAttributes:thirdItemAttributes]; + + SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"]; + SecCDKeychainItem* firstItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:firstItemID attributes:firstItemAttributes lookupAttributes:firstItemLookupAttributes secrets:@{@"data" : @"I'm the first"} owner:owner keyclass:key_class_ak]; + SecCDKeychainItem* secondItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:secondItemID attributes:secondItemAttributes lookupAttributes:secondItemLookupAttributes secrets:@{@"data" : @"I'm the second"} owner:owner keyclass:key_class_ak]; + SecCDKeychainItem* thirdItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:thirdUUID attributes:thirdItemAttributes lookupAttributes:thirdItemLookupAttributes secrets:@{@"data" : @"I'm the third"} owner:owner keyclass:key_class_ak]; + + XCTestExpectation* insertExpectation = [self expectationWithDescription:@"insert items"]; + [_keychain insertItems:@[firstItem, secondItem] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertTrue(success, @"failed to successfully insert items with error: %@", error); + XCTAssertNil(error, @"encountered error inserting items: %@", error); + [insertExpectation fulfill]; + }]; + [self waitForExpectations:@[insertExpectation] timeout:5.0]; + + XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch items"]; + [_keychain fetchItemsWithValue:@"bothHaveThis" forLookupKey:@"sharedAttribute" ofType:SecCDKeychainLookupValueTypeString withConnection:_connection completionHandler:^(NSArray* items, NSError* error) { + XCTAssertEqual(items.count, (unsigned long)2, @"did not get the expected number of fetched items; expected 2, but got %d", (int)items.count); + XCTAssertNil(error, @"encountered error fetching item: %@", error); + if (items.count >= 2) { + SecCDKeychainItem* firstFetchedObject = [self fullItemForItemMetadata:items[0]]; + SecCDKeychainItem* secondFetchedObject = [self fullItemForItemMetadata:items[1]]; + XCTAssertTrue([firstFetchedObject isEqual:firstItem] || [firstFetchedObject isEqual:secondItem], @"first fetched object does not match either of the items we expected to fetch"); + XCTAssertTrue([secondFetchedObject isEqual:firstItem] || [secondFetchedObject isEqual:secondItem], @"second fetched object does not match either of the items we expected to fetch"); + XCTAssertFalse([firstFetchedObject isEqual:secondFetchedObject], @"the objects we got back from our query are unexpectedly equal to each other"); + XCTAssertFalse([items containsObject:thirdItem.metadata], @"found an unexpected item in our fetch results"); + } + [fetchExpectation fulfill]; + }]; + [self waitForExpectations:@[fetchExpectation] timeout:5.0]; +} + +- (void)testDuplicates +{ + // TODO: test some duplicate-rejection scenarios, including the case where no primary keys are explicitly defined +} + +- (void)testAccessGroups +{ + [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"TestAccessGroup"]]; + + // first we'll try inserting in an access group that should be rejected + SecCDKeychainAccessControlEntity* badOwner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"BadAccessGroup"]; + NSUUID* persistentID = [NSUUID UUID]; + SecCDKeychainItem* badItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecret"} owner:badOwner keyclass:key_class_ak]; + + XCTestExpectation* badAccessGroupInsertExpectation = [self expectationWithDescription:@"items insert with bad access group"]; + [_keychain insertItems:@[badItem] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertFalse(success, @"should have rejected insert of item for a bad access group"); + XCTAssertNotNil(error, @"should have encountered an error for inserting with bad access group"); + XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain"); + XCTAssertEqual(error.code, SFKeychainErrorInvalidAccessGroup, @"should have gotten the SFKeychainErrorInvalidAccessGroup error code"); + [badAccessGroupInsertExpectation fulfill]; + }]; + [self waitForExpectations:@[badAccessGroupInsertExpectation] timeout:5.0]; + + // ok, now try an insertion that should succeed + SecCDKeychainAccessControlEntity* goodOwner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"TestAccessGroup"]; + SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecret"} owner:goodOwner keyclass:key_class_ak]; + + XCTestExpectation* insertExpectation = [self expectationWithDescription:@"items inserted"]; + [_keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertTrue(success, @"should have been able to insert item"); + XCTAssertNil(error, @"should not have gotten an error inserting item"); + [insertExpectation fulfill]; + }]; + [self waitForExpectations:@[insertExpectation] timeout:5.0]; + + XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch item"]; + [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) { + XCTAssertNotNil(fetchedItem, @"should have been able to fetch item"); + XCTAssertNil(error, @"should not have gotten error fetching item"); + XCTAssertEqualObjects(fetchedItem, item, @"fetched item should match the inserted item"); + [fetchExpectation fulfill]; + }]; + [self waitForExpectations:@[fetchExpectation] timeout:5.0]; + + // now change my access group and see if I get the expected error trying to fetch the item + [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"NotYourAccessGroup"]]; + + XCTestExpectation* badFetchExpectation = [self expectationWithDescription:@"fetch item with bad access group"]; + [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) { + XCTAssertNil(fetchedItem, @"should not have gotten item when fetching with a bad access group"); + XCTAssertNotNil(error, @"should have gotten an error fetching item"); + XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain"); + XCTAssertEqual(error.code, SFKeychainErrorItemNotFound, @"should have gotten the SFKeychainErrorItemNotFound error code"); + [badFetchExpectation fulfill]; + }]; + [self waitForExpectations:@[badFetchExpectation] timeout:5.0]; + + // now try to delete the thing to confirm we cannot + + XCTestExpectation* badDeleteExpectation = [self expectationWithDescription:@"delete item with bad access group"]; + [_keychain deleteItemWithPersistentID:persistentID withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertFalse(success, @"should not have succeeded at deleting item we don't have access to"); + XCTAssertNotNil(error, @"should have gotten an error deleting item we don't have access to"); + XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain"); + XCTAssertEqual(error.code, SFKeychainErrorItemNotFound, @"should have gotten the SFKeychainErrorItemNotFound error code"); + [badDeleteExpectation fulfill]; + }]; + [self waitForExpectations:@[badDeleteExpectation] timeout:5.0]; + + // switch to the good access group to make sure it's still there + [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"TestAccessGroup"]]; + + XCTestExpectation* fetchAgainExpecation = [self expectationWithDescription:@"fetch item again"]; + [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) { + XCTAssertNotNil(fetchedItem, @"should have been able to fetch item"); + XCTAssertNil(error, @"should not have gotten error fetching item"); + XCTAssertEqualObjects(fetchedItem, item, @"fetched item should match the inserted item"); + [fetchAgainExpecation fulfill]; + }]; + [self waitForExpectations:@[fetchAgainExpecation] timeout:5.0]; + + // and finally delete with proper permissions + + XCTestExpectation* deleteExpectation = [self expectationWithDescription:@"delete item"]; + [_keychain deleteItemWithPersistentID:persistentID withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertTrue(success, @"should have succeeded deleting item"); + XCTAssertNil(error, @"should not have gotten error deleting item: %@", error); + [deleteExpectation fulfill]; + }]; + [self waitForExpectations:@[deleteExpectation] timeout:5.0]; + + XCTestExpectation* postDeleteFetchExpectation = [self expectationWithDescription:@"fetch item after delete"]; + [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) { + XCTAssertNil(fetchedItem, @"should not have gotten item when fetching with a bad access group"); + XCTAssertNotNil(error, @"should have gotten error for fetch of deleted item"); + XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain"); + XCTAssertEqual(error.code, SFKeychainErrorItemNotFound, @"should have gotten the SFKeychainErrorItemNotFound error code"); + [postDeleteFetchExpectation fulfill]; + }]; + [self waitForExpectations:@[postDeleteFetchExpectation] timeout:5.0]; +} + +- (void)testDifferentOwnersWithSimilarItems +{ + [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"FirstAccessGroup"]]; + SecCDKeychainAccessControlEntity* firstOwner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"FirstAccessGroup"]; + + NSUUID* firstPersistentID = [NSUUID UUID]; + SecCDKeychainItem* firstItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:firstPersistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MyFirstSecret"} owner:firstOwner keyclass:key_class_ak]; + + XCTestExpectation* firstInsertExpectation = [self expectationWithDescription:@"insert first item"]; + [_keychain insertItems:@[firstItem] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertTrue(success, @"should have been able to insert item"); + XCTAssertNil(error, @"should not have gotten an error inserting item"); + [firstInsertExpectation fulfill]; + }]; + [self waitForExpectations:@[firstInsertExpectation] timeout:5.0]; + + [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"SecondAccessGroup"]]; + SecCDKeychainAccessControlEntity* secondOwner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"SecondAccessGroup"]; + + NSUUID* secondPersistentID = [NSUUID UUID]; + SecCDKeychainItem* secondItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:secondPersistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecondSecret"} owner:secondOwner keyclass:key_class_ak]; + + XCTestExpectation* secondInsertExpectation = [self expectationWithDescription:@"insert item"]; + [_keychain insertItems:@[secondItem] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertTrue(success, @"should have been able to insert item"); + XCTAssertNil(error, @"should not have gotten an error inserting item"); + [secondInsertExpectation fulfill]; + }]; + [self waitForExpectations:@[secondInsertExpectation] timeout:5.0]; + + // now try fetching the first and second items + // we should have access to the second but not the first + + XCTestExpectation* firstFetchExpectation = [self expectationWithDescription:@"fetch first item"]; + [_keychain fetchItemForPersistentID:firstPersistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) { + XCTAssertNil(fetchedItem, @"should not have been able to fetch item from first access group"); + XCTAssertNotNil(error, @"should have gotten an error fetching item"); + XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain"); + XCTAssertEqual(error.code, SFKeychainErrorItemNotFound, @"should have gotten the SFKeychainErrorItemNotFound error code"); + [firstFetchExpectation fulfill]; + }]; + [self waitForExpectations:@[firstFetchExpectation] timeout:5.0]; + + XCTestExpectation* secondFetchExpectation = [self expectationWithDescription:@"fetch second item"]; + [_keychain fetchItemForPersistentID:secondPersistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) { + XCTAssertNotNil(fetchedItem, @"should have been able to fetch item"); + XCTAssertNil(error, @"should not have gotten an error fetching item"); + XCTAssertEqualObjects(fetchedItem, secondItem, @"fetched item should match inserted item"); + [secondFetchExpectation fulfill]; + }]; + [self waitForExpectations:@[secondFetchExpectation] timeout:5.0]; + + // finally, do a search; make sure it returns exactly one result + XCTestExpectation* searchExpectation = [self expectationWithDescription:@"search items"]; + [_keychain fetchItemsWithValue:@"value" forLookupKey:@"key" ofType:SecCDKeychainLookupValueTypeString withConnection:_connection completionHandler:^(NSArray* items, NSError* error) { + XCTAssertEqual(items.count, (unsigned long)1, @"should have gotten 1 search result, but got %d", (int)items.count); + SecCDKeychainItem* fetchedItem = [self fullItemForItemMetadata:items.firstObject]; + XCTAssertNotNil(fetchedItem, @"should have been able to fetch full item"); + XCTAssertNil(error, @"should not have gotten error looking up item"); + XCTAssertEqualObjects(fetchedItem, secondItem, @"item we looked up should match the one we inserted"); + [searchExpectation fulfill]; + }]; + [self waitForExpectations:@[searchExpectation] timeout:5.0]; +} + +- (void)testTamperedMetadata +{ + SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"]; + + NSUUID* persistentID = [NSUUID UUID]; + SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MyFirstSecret"} owner:owner keyclass:key_class_ak]; + + XCTestExpectation* insertExpectation = [self expectationWithDescription:@"insert item"]; + [_keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertTrue(success, @"should have been able to insert item"); + XCTAssertNil(error, @"should not have gotten an error inserting item"); + [insertExpectation fulfill]; + }]; + [self waitForExpectations:@[insertExpectation] timeout:5.0]; + + XCTestExpectation* tamperExpectation = [self expectationWithDescription:@"tamper with item"]; + [_keychain performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) { + XCTAssertNotNil(managedObjectContext, @"should have gotten a managed object to perform work with"); + XCTAssertNil(managedObjectError, @"should not get error performing a block on the managed object context"); + + NSError* error = nil; + SecCDKeychainManagedItem* managedItem = [self->_keychain fetchManagedItemForPersistentID:persistentID withManagedObjectContext:managedObjectContext error:&error]; + XCTAssertNotNil(managedItem, @"should have been able to fetch the managed item we just inserted"); + XCTAssertNil(error, @"should not have gotten an error fetching the managed item"); + + // ok, now let's do something nefarious, like change the metadata + NSDictionary* fakeMetadata = @{@"key" : @"differentValue"}; + managedItem.metadata = [NSPropertyListSerialization dataWithPropertyList:fakeMetadata format:NSPropertyListXMLFormat_v1_0 options:9 error:&error]; + XCTAssertNotNil(managedItem.metadata, @"should have been able to write modified metadata"); + XCTAssertNil(error, @"should not have gotten an error writing modified metadata"); + + SecCDKeychainItem* brokenItem = [[SecCDKeychainItem alloc] initWithManagedItem:managedItem keychain:self->_keychain error:&error]; + XCTAssertNil(brokenItem, @"should not have been able to create item with tampered metadata"); + XCTAssertNotNil(error, @"should have gotten an error attempting to create an item with tampered metadata"); + XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain"); + XCTAssertEqual(error.code, SFKeychainErrorItemDecryptionFailed, @"should have gotten the SFKeychainErrorItemDecryptionFailed error"); + + [tamperExpectation fulfill]; + }]; + [self waitForExpectations:@[tamperExpectation] timeout:5.0]; +} + +@end + +// these tests do not wish to have a keychain already setup +@interface CDKeychainSetupTests : KeychainXCTest +@end + +@implementation CDKeychainSetupTests { + SFKeychainServerFakeConnection* _connection; +} + +- (void)setUp +{ + [super setUp]; + + _connection = [[SFKeychainServerFakeConnection alloc] init]; +} + +- (void)testKeychainLocking +{ + self.lockState = LockStateLockedAndDisallowAKS; + + NSURL* persistentStoreURL = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"CDKeychain"); + NSBundle* resourcesBundle = [NSBundle bundleWithPath:@"/System/Library/Keychain/KeychainResources.bundle"]; + NSURL* managedObjectModelURL = [resourcesBundle URLForResource:@"KeychainModel" withExtension:@"momd"]; + SecCDKeychain* keychain = [[SecCDKeychain alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectModelURL encryptDatabase:false]; + XCTAssertNotNil(keychain, @"should have been able to create a keychain instance"); + + self.keychainPartialMock = OCMPartialMock(keychain); + [[[[self.keychainPartialMock stub] andCall:@selector(getDatabaseKeyDataithError:) onObject:self] ignoringNonObjectArgs] _onQueueGetDatabaseKeyDataWithError:NULL]; + + SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"]; + + NSUUID* persistentID = [NSUUID UUID]; + SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecret"} owner:owner keyclass:key_class_ak]; + + XCTestExpectation* insertExpectation = [self expectationWithDescription:@"insert item"]; + [keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertFalse(success, @"should not be able to insert item while locked"); + XCTAssertNotNil(error, @"should get error inserting item while locked"); + + // in the future, check for proper error + // // add SFKeychainErrorDeviceLocked + + [insertExpectation fulfill]; + }]; + [self waitForExpectations:@[insertExpectation] timeout:5.0]; + + self.lockState = LockStateUnlocked; + + [keychain _registerItemTypeForTesting:[TestItemType itemType]]; + + XCTestExpectation* insertAgainExpectation = [self expectationWithDescription:@"insert item again"]; + [keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) { + XCTAssertTrue(success, @"should be able to insert item after unlock"); + XCTAssertNil(error, @"should not get error inserting after unlock"); + [insertAgainExpectation fulfill]; + }]; + [self waitForExpectations:@[insertAgainExpectation] timeout:5.0]; + + XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch item"]; + [keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) { + XCTAssertNotNil(fetchedItem, @"should have been able to fetch item"); + XCTAssertNil(error, @"should not have gotten an error fetching item"); + XCTAssertEqualObjects(fetchedItem, item, @"fetched item should match inserted item"); + [fetchExpectation fulfill]; + }]; + [self waitForExpectations:@[fetchExpectation] timeout:5.0]; + + self.lockState = LockStateLockedAndDisallowAKS; + dispatch_sync(keychain.queue, ^{ + [keychain _onQueueDropClassAPersistentStore]; + }); + + XCTestExpectation* fetchWhileLockedExpectation = [self expectationWithDescription:@"fetch item while locked"]; + [keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) { + XCTAssertNil(fetchedItem, @"should not be able to fetch item while locked"); + XCTAssertNotNil(error, @"should get an error fetching item while locked"); + + // in the future, check for proper error + // // add SFKeychainErrorDeviceLocked + + [fetchWhileLockedExpectation fulfill]; + }]; + [self waitForExpectations:@[fetchWhileLockedExpectation] timeout:5.0]; +} + +@end + +#endif diff --git a/secdxctests/KeychainCryptoTests.m b/secdxctests/KeychainCryptoTests.m index 56625bed..552e76d1 100644 --- a/secdxctests/KeychainCryptoTests.m +++ b/secdxctests/KeychainCryptoTests.m @@ -47,17 +47,13 @@ @end #if USE_KEYSTORE -#include -#endif +#import @interface KeychainCryptoTests : KeychainXCTest @end @implementation KeychainCryptoTests -#if USE_KEYSTORE -#include - static keyclass_t parse_keyclass(CFTypeRef value) { if (!value || CFGetTypeID(value) != CFStringGetTypeID()) { return 0; @@ -89,6 +85,51 @@ static keyclass_t parse_keyclass(CFTypeRef value) { } } +- (NSDictionary* _Nullable)addTestItemExpecting:(OSStatus)code account:(NSString*)account accessible:(NSString*)accessible +{ + NSDictionary* addQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : account, + (id)kSecAttrService : [NSString stringWithFormat:@"%@-Service", account], + (id)kSecAttrAccessible : (id)accessible, + (id)kSecAttrNoLegacy : @(YES), + (id)kSecReturnAttributes : @(YES), + }; + CFTypeRef result = NULL; + + if(code == errSecSuccess) { + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery, &result), code, @"Should have succeeded in adding test item to keychain"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemAdd"); + } else { + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery, &result), code, @"Should have failed to adding test item to keychain with code %d", code); + XCTAssertNil((__bridge id)result, @"Should not have received a dictionary back from SecItemAdd"); + } + + return CFBridgingRelease(result); +} + +- (NSDictionary* _Nullable)findTestItemExpecting:(OSStatus)code account:(NSString*)account +{ + NSDictionary* findQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : account, + (id)kSecAttrService : [NSString stringWithFormat:@"%@-Service", account], + (id)kSecAttrNoLegacy : @(YES), + (id)kSecReturnAttributes : @(YES), + }; + CFTypeRef result = NULL; + + if(code == errSecSuccess) { + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), code, @"Should have succeeded in finding test tiem"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemCopyMatching"); + } else { + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), code, @"Should have failed to find items in keychain with code %d", code); + XCTAssertNotNil((__bridge id)result, @"Should not have received a dictionary back from SecItemCopyMatching"); + } + + return CFBridgingRelease(result); +} + + - (void)testBasicEncryptDecrypt { CFDataRef enc = NULL; @@ -300,8 +341,9 @@ static keyclass_t parse_keyclass(CFTypeRef value) { CFErrorRef cferror = NULL; kc_with_dbt(true, &cferror, ^bool(SecDbConnectionRef dbt) { - CFErrorRef errref; + CFErrorRef errref = NULL; SecDbExec(dbt, CFSTR("DELETE FROM metadatakeys WHERE keyclass = '6'"), &errref); + XCTAssertEqual(errref, NULL, "Should be no error deleting class A metadatakey"); CFReleaseNull(errref); return true; }); @@ -310,6 +352,39 @@ static keyclass_t parse_keyclass(CFTypeRef value) { [[SecDbKeychainMetadataKeyStore sharedStore] dropClassAKeys]; } +- (void)checkDatabaseExistenceOfMetadataKey:(keyclass_t)keyclass shouldExist:(bool)shouldExist +{ + CFErrorRef cferror = NULL; + + kc_with_dbt(true, &cferror, ^bool(SecDbConnectionRef dbt) { + __block CFErrorRef errref = NULL; + + NSString* sql = [NSString stringWithFormat:@"SELECT data, actualKeyclass FROM metadatakeys WHERE keyclass = %d", keyclass]; + __block bool ok = true; + __block bool keyExists = false; + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &errref, ^(sqlite3_stmt *stmt) { + ok &= SecDbStep(dbt, stmt, &errref, ^(bool *stop) { + NSData* wrappedKeyData = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)]; + NSMutableData* unwrappedKeyData = [NSMutableData dataWithLength:wrappedKeyData.length]; + + keyExists = !!unwrappedKeyData; + }); + }); + + XCTAssertTrue(ok, "Should have completed all operations correctly"); + XCTAssertEqual(errref, NULL, "Should be no error deleting class A metadatakey"); + + if(shouldExist) { + XCTAssertTrue(keyExists, "Metadata class key should exist"); + } else { + XCTAssertFalse(keyExists, "Metadata class key should not exist"); + } + CFReleaseNull(errref); + return true; + }); + CFReleaseNull(cferror); +} + - (void)testKeychainCorruptionCopyMatching { NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, @@ -321,7 +396,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); - + [self checkDatabaseExistenceOfMetadataKey:key_class_ak shouldExist:true]; NSMutableDictionary* dataQuery = item.mutableCopy; [dataQuery removeObjectForKey:(id)kSecValueData]; @@ -334,12 +409,16 @@ static keyclass_t parse_keyclass(CFTypeRef value) { CFReleaseNull(foundItem); [self trashMetadataClassAKey]; + [self checkDatabaseExistenceOfMetadataKey:key_class_ak shouldExist:false]; /* when metadata corrupted, we should not find the item */ result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); XCTAssertEqual(result, errSecItemNotFound, @"failed to find the data for the item we just added in the keychain"); CFReleaseNull(foundItem); + // Just calling SecItemCopyMatching shouldn't have created a new metdata key + [self checkDatabaseExistenceOfMetadataKey:key_class_ak shouldExist:false]; + /* semantics are odd, we should be able to delete it */ result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); XCTAssertEqual(result, 0, @"failed to delete item"); @@ -649,6 +728,44 @@ static keyclass_t parse_keyclass(CFTypeRef value) { [mockSecDbKeychainMetadataKeyStore stopMocking]; } +// If a metadata key is created during a database transaction which is later rolled back, it shouldn't be cached for use later. +- (void)testMetadataKeyDoesntOutliveTxionRollback { + NSString* testAccount = @"TestAccount"; + NSString* otherAccount = @"OtherAccount"; + NSString* thirdAccount = @"ThirdAccount"; + [self addTestItemExpecting:errSecSuccess account:testAccount accessible:(id)kSecAttrAccessibleAfterFirstUnlock]; + [self checkDatabaseExistenceOfMetadataKey:key_class_ck shouldExist:true]; + [self checkDatabaseExistenceOfMetadataKey:key_class_cku shouldExist:false]; + + // This should fail, and not create a CKU metadata key + [self addTestItemExpecting:errSecDuplicateItem account:testAccount accessible:(id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]; + [self checkDatabaseExistenceOfMetadataKey:key_class_ck shouldExist:true]; + [self checkDatabaseExistenceOfMetadataKey:key_class_cku shouldExist:false]; + + // But successfully creating a new CKU item should create the key + [self addTestItemExpecting:errSecSuccess account:otherAccount accessible:(id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]; + [self checkDatabaseExistenceOfMetadataKey:key_class_ck shouldExist:true]; + [self checkDatabaseExistenceOfMetadataKey:key_class_cku shouldExist:true]; + + // Drop all metadata key caches + [SecDbKeychainMetadataKeyStore resetSharedStore]; + + [self findTestItemExpecting:errSecSuccess account:testAccount]; + [self findTestItemExpecting:errSecSuccess account:otherAccount]; + + // Adding another CKU item now should be fine + [self addTestItemExpecting:errSecSuccess account:thirdAccount accessible:(id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]; + [self checkDatabaseExistenceOfMetadataKey:key_class_ck shouldExist:true]; + [self checkDatabaseExistenceOfMetadataKey:key_class_cku shouldExist:true]; + + // Drop all metadata key caches once more, to ensure we can find all three items from the persisted keys + [SecDbKeychainMetadataKeyStore resetSharedStore]; + + [self findTestItemExpecting:errSecSuccess account:testAccount]; + [self findTestItemExpecting:errSecSuccess account:otherAccount]; + [self findTestItemExpecting:errSecSuccess account:thirdAccount]; +} + - (void)testRecoverDataFromBadKeyclassStorage { NSDictionary* metadataAttributesInput = @{@"TestMetadata" : @"TestValue"}; @@ -722,18 +839,24 @@ static keyclass_t parse_keyclass(CFTypeRef value) { [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAfterFirstUnlock]; XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_ck | key_class_last + 1); - + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAlways]; XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_dk | key_class_last + 1); +#pragma clang diagnostic pop [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleWhenUnlockedThisDeviceOnly]; XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_aku | key_class_last + 1); [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]; XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_cku | key_class_last + 1); - + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAlwaysThisDeviceOnly]; XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_dku | key_class_last + 1); +#pragma clang diagnostic pop [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly]; XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_akpu | key_class_last + 1); @@ -764,6 +887,6 @@ static keyclass_t parse_keyclass(CFTypeRef value) { [self performMetadataDecryptionOfData:encryptedData verifyingAccessibility:kSecAttrAccessibleWhenUnlocked]; } -#endif - @end + +#endif diff --git a/secdxctests/KeychainEntitlementsTest.m b/secdxctests/KeychainEntitlementsTest.m new file mode 100644 index 00000000..84482da6 --- /dev/null +++ b/secdxctests/KeychainEntitlementsTest.m @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2018 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@ + */ + +#import +#import + +#import "KeychainXCTest.h" + +#if USE_KEYSTORE +@interface KeychainEntitlementsTest : KeychainXCTest +@end + +@implementation KeychainEntitlementsTest + +- (void)testNoEntitlements { + NSDictionary *params = @{ (id)kSecAttrNoLegacy: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, (id)kSecAttrLabel: @"label", }; + + // Application with no keychain-related entitlements at all, but CopyMatching must work in order to support + // backward compatibility with smart-card-enabled macos applications (com.apple.token AG is added automatically in this case). + [self setEntitlements:@{} validated:false]; + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); + + // However, write access is declined for such application. + XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement); + XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement); +} + +#if TARGET_OS_OSX +- (void)testInvalidEntitlementsAppID { + NSDictionary *params; + params = @{ (id)kSecAttrNoLegacy: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrLabel: @"label", }; + + // Un-validated app-identifier entitlements must disallow any access to the keychain. + [self setEntitlements:@{ @"com.apple.application-identifier": @"com.apple.test-app-identifier" } validated:false]; + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecMissingEntitlement); + XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement); + XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement); + + // However, keychain-access-groups entitlements should work even if not validated, AMFI will take care + // about cases when keychain-access-groups is not correctly used and we have to support cases when + // process contains application-groups entitlement but that entitlement is not present in provisioned profile, thus + // failing entitlement validation test. + [self setEntitlements:@{ @"keychain-access-groups": @[@"com.apple.test-app-identifier"] } validated:false]; + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); + XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecSuccess); + XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecSuccess); +} +#endif // TARGET_OS_OSX + +- (void)testValidEntitlementsAppID { + NSDictionary *params; + params = @{ (id)kSecAttrNoLegacy: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrLabel: @"label", + (id)kSecAttrAccessGroup: @"com.apple.test-app-identifier", }; +#if TARGET_OS_OSX + [self setEntitlements:@{ @"com.apple.application-identifier": @"com.apple.test-app-identifier" } validated:true]; +#else + [self setEntitlements:@{ @"application-identifier": @"com.apple.test-app-identifier" } validated:true]; +#endif + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); + XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecSuccess); + XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecSuccess); +} + +- (void)testDisallowTokenGroupWrite { + NSDictionary *params; + + // Explicit com.apple.token agrp is not acceptable for writing operations, but acceptable for reading. + params = @{ (id)kSecAttrNoLegacy: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrLabel: @"label", + (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken, }; + [self setEntitlements:@{ @"com.apple.application-identifier": (id)kSecAttrAccessGroupToken } validated:true]; + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); + XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement); + XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement); +} + +#if TARGET_OS_OSX +- (void)testInvalidAppGroups { + NSDictionary *params; + params = @{ (id)kSecAttrNoLegacy: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrLabel: @"label", }; + [self setEntitlements:@{ @"com.apple.security.application-groups": @[@"com.apple.test-app-groups"] } validated:false]; + + // Invalid access group entitlement should still allow querying com.apple.token + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); + + // But write-access is forbidden, + XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement); + XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement); + + // Similarly as explicitly referring to AG specified in unverified entitlements. + params = @{ (id)kSecAttrNoLegacy: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrLabel: @"label", + (id)kSecAttrAccessGroup: @"com.apple.test-app-groups", }; + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); + XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement); + XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement); + + // Explicitly referring to com.apple.token should work fine too. + params = @{ (id)kSecAttrNoLegacy: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrLabel: @"label", + (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken, }; + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); +} +#endif // TARGET_OS_OSX + +@end + +#endif // USE_KEYSTORE + diff --git a/secdxctests/KeychainXCTest.h b/secdxctests/KeychainXCTest.h index d8090993..5e172a68 100644 --- a/secdxctests/KeychainXCTest.h +++ b/secdxctests/KeychainXCTest.h @@ -23,12 +23,13 @@ #import "KeychainXCTest.h" #import "SecItemServer.h" +#import "SFKeychainServer.h" #import #import #import #if USE_KEYSTORE -#include +#import typedef enum { LockStateUnlocked, @@ -48,8 +49,20 @@ typedef enum { @property SFAESKeySpecifier* keySpecifier; @property SFAESKey* fakeAKSKey; +@property id keychainPartialMock; + - (bool)setNewFakeAKSKey:(NSData*)newKeyData; +- (void)setEntitlements:(NSDictionary *)entitlements validated:(BOOL)validated; + +- (NSData*)getDatabaseKeyDataithError:(NSError**)error; + +@end + +@interface SFKeychainServerFakeConnection : SFKeychainServerConnection + +- (void)setFakeAccessGroups:(NSArray*)fakeAccessGroups; + @end #endif diff --git a/secdxctests/KeychainXCTest.m b/secdxctests/KeychainXCTest.m index 77b1f8b3..98d5a266 100644 --- a/secdxctests/KeychainXCTest.m +++ b/secdxctests/KeychainXCTest.m @@ -27,15 +27,19 @@ #import "CKKS.h" #import "SecDbKeychainItemV7.h" #import "SecItemPriv.h" +#import "SecTaskPriv.h" +#import "server_security_helpers.h" #import "SecItemServer.h" #import "spi.h" #import "SecDbKeychainSerializedItemV7.h" #import "SecDbKeychainSerializedMetadata.h" #import "SecDbKeychainSerializedSecretData.h" #import "SecDbKeychainSerializedAKSWrappedKey.h" +#import "SecCDKeychain.h" #import #import #import +#import #import #import @@ -47,7 +51,75 @@ @end -@implementation KeychainXCTest +@interface FakeAKSRefKey : NSObject +@end + +@implementation FakeAKSRefKey { + SFAESKey* _key; +} + +- (instancetype)initWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass +{ + if (self = [super init]) { + _key = [[SFAESKey alloc] initRandomKeyWithSpecifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256] error:nil]; + } + + return self; +} + +- (instancetype)initWithBlob:(NSData*)blob keybag:(keybag_handle_t)keybag +{ + if (self = [super init]) { + _key = [[SFAESKey alloc] initWithData:blob specifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256] error:nil]; + } + + return self; +} + +- (NSData*)wrappedDataForKey:(SFAESKey*)key +{ + SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]]; + return [NSKeyedArchiver archivedDataWithRootObject:[encryptionOperation encrypt:key.keyData withKey:_key error:nil] requiringSecureCoding:YES error:nil]; +} + +- (SFAESKey*)keyWithWrappedData:(NSData*)wrappedKeyData +{ + SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; + SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:keySpecifier]; + NSData* keyData = [encryptionOperation decrypt:[NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:wrappedKeyData error:nil] withKey:_key error:nil]; + return [[SFAESKey alloc] initWithData:keyData specifier:keySpecifier error:nil]; +} + +- (NSData*)refKeyBlob +{ + return _key.keyData; +} + +@end + +@implementation SFKeychainServerFakeConnection { + NSArray* _fakeAccessGroups; +} + +- (void)setFakeAccessGroups:(NSArray*)fakeAccessGroups +{ + _fakeAccessGroups = fakeAccessGroups.copy; +} + +- (NSArray*)clientAccessGroups +{ + return _fakeAccessGroups ?: @[@"com.apple.token"]; +} + +@end + +@implementation KeychainXCTest { + id _keychainPartialMock; + CFArrayRef _originalAccessGroups; + +} + +@synthesize keychainPartialMock = _keychainPartialMock; + (void)setUp { @@ -71,22 +143,31 @@ self.keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; [self setNewFakeAKSKey:[NSData dataWithBytes:"1234567890123456789012" length:32]]; - + [SecDbKeychainMetadataKeyStore resetSharedStore]; self.mockSecDbKeychainItemV7 = OCMClassMock([SecDbKeychainItemV7 class]); [[[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(fakeAKSEncryptWithKeybag:keyclass:keyData:outKeyclass:wrappedKey:error:) onObject:self] ignoringNonObjectArgs] aksEncryptWithKeybag:0 keyclass:0 keyData:[OCMArg any] outKeyclass:NULL wrappedKey:[OCMArg any] error:NULL]; [[[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(fakeAKSDecryptWithKeybag:keyclass:wrappedKeyData:outKeyclass:unwrappedKey:error:) onObject:self] ignoringNonObjectArgs] aksDecryptWithKeybag:0 keyclass:0 wrappedKeyData:[OCMArg any] outKeyclass:NULL unwrappedKey:[OCMArg any] error:NULL]; [[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(decryptionOperation) onObject:self] decryptionOperation]; - [[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(isKeychainUnlocked) onObject:self] isKeychainUnlocked]; - + + // bring back with +// [[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(isKeychainUnlocked) onObject:self] isKeychainUnlocked]; + + id refKeyMock = OCMClassMock([SecAKSRefKey class]); + [[[refKeyMock stub] andCall:@selector(alloc) onObject:[FakeAKSRefKey class]] alloc]; + NSArray* partsOfName = [self.name componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" ]"]]; secd_test_setup_temp_keychain([partsOfName[1] UTF8String], NULL); + + _originalAccessGroups = SecAccessGroupsGetCurrent(); } - (void)tearDown { [self.mockSecDbKeychainItemV7 stopMocking]; + SecAccessGroupsSetCurrent(_originalAccessGroups); + [super tearDown]; } @@ -145,6 +226,8 @@ if (self.simulateRolledAKSKey && outKeyclass) { *outKeyclass = keyclass | (key_class_last + 1); + } else if (outKeyclass) { + *outKeyclass = keyclass; } return true; @@ -214,6 +297,45 @@ } } +- (NSData*)getDatabaseKeyDataithError:(NSError**)error +{ + if (_lockState == LockStateUnlocked) { + return [NSData dataWithBytes:"12345678901234567890123456789012" length:32]; + } + else { + if (error) { + // add SFKeychainErrorDeviceLocked + *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorFailedToCommunicateWithServer userInfo:nil]; + } + return nil; + } +} + +// Mock SecTask entitlement retrieval API, so that we can test access group entitlement parsing code in SecTaskCopyAccessGroups() +static NSDictionary *currentEntitlements = nil; +static BOOL currentEntitlementsValidated = false; +static NSArray *currentAccessGroups = nil; + +CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error) { + id value = currentEntitlements[(__bridge id)entitlement]; + if (value == nil && error != NULL) { + *error = (CFErrorRef)CFBridgingRetain([NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:nil]); + } + return CFBridgingRetain(value); +} + +Boolean SecTaskEntitlementsValidated(SecTaskRef task) { + return currentEntitlementsValidated; +} + +- (void)setEntitlements:(NSDictionary *)entitlements validated:(BOOL)validated { + currentEntitlements = entitlements; + currentEntitlementsValidated = validated; + id task = CFBridgingRelease(SecTaskCreateFromSelf(kCFAllocatorDefault)); + currentAccessGroups = CFBridgingRelease(SecTaskCopyAccessGroups((__bridge SecTaskRef)task)); + SecAccessGroupsSetCurrent((__bridge CFArrayRef)currentAccessGroups); +} + @end #endif diff --git a/secdxctests/SFCredentialStoreTests.m b/secdxctests/SFCredentialStoreTests.m new file mode 100644 index 00000000..62aa116e --- /dev/null +++ b/secdxctests/SFCredentialStoreTests.m @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2018 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@ + */ + +#import "KeychainXCTest.h" +#import "SFKeychainServer.h" +#import "SecCDKeychain.h" +#import "SecFileLocations.h" +#import +#import +#import +#import +#import + +#if USE_KEYSTORE + +@interface SFCredentialStore (UnitTestingForwardDeclarations) + +- (instancetype)_init; + +- (id)_serverConnectionWithError:(NSError**)error; + +@end + +@interface SFKeychainServer (UnitTestingForwardDeclarations) + +@property (readonly, getter=_keychain) SecCDKeychain* keychain; + +@end + +@interface SFKeychainServerConnection (UnitTestingRedeclarations) + +- (instancetype)initWithKeychain:(SecCDKeychain*)keychain xpcConnection:(NSXPCConnection*)connection; + +@end + +@interface SecCDKeychain (UnitTestingRedeclarations) + +- (NSData*)_onQueueGetDatabaseKeyDataWithError:(NSError**)error; + +@end + +@interface KeychainNoXPCServerProxy : NSObject + +@property (readonly) SFKeychainServer* server; + +@end + +@implementation KeychainNoXPCServerProxy { + SFKeychainServer* _server; + SFKeychainServerFakeConnection* _connection; +} + +@synthesize server = _server; + +- (instancetype)init +{ + if (self = [super init]) { + NSURL* persistentStoreURL = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"CDKeychain"); + NSBundle* resourcesBundle = [NSBundle bundleWithPath:@"/System/Library/Keychain/KeychainResources.bundle"]; + NSURL* managedObjectModelURL = [resourcesBundle URLForResource:@"KeychainModel" withExtension:@"momd"]; + _server = [[SFKeychainServer alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectModelURL encryptDatabase:false]; + _connection = [[SFKeychainServerFakeConnection alloc] initWithKeychain:_server.keychain xpcConnection:nil]; + } + + return self; +} + +- (id)remoteObjectProxy +{ + return _server; +} + +- (id)remoteObjectProxyWithErrorHandler:(void (^)(NSError*))handler +{ + return _connection; +} + +@end + +@interface SFCredentialStoreTests : KeychainXCTest +@end + +@implementation SFCredentialStoreTests { + SFCredentialStore* _credentialStore; +} + ++ (void)setUp +{ + [super setUp]; + + id credentialStoreMock = OCMClassMock([SFCredentialStore class]); + [[[[credentialStoreMock stub] andCall:@selector(serverProxyWithError:) onObject:self] ignoringNonObjectArgs] _serverConnectionWithError:NULL]; +} + ++ (id)serverProxyWithError:(NSError**)error +{ + return [[KeychainNoXPCServerProxy alloc] init]; +} + +- (void)setUp +{ + [super setUp]; + self.keychainPartialMock = OCMPartialMock([(SFKeychainServer*)[[self.class serverProxyWithError:nil] server] _keychain]); + [[[[self.keychainPartialMock stub] andCall:@selector(getDatabaseKeyDataithError:) onObject:self] ignoringNonObjectArgs] _onQueueGetDatabaseKeyDataWithError:NULL]; + + _credentialStore = [[SFCredentialStore alloc] _init]; +} + +- (BOOL)passwordCredential:(SFPasswordCredential*)firstCredential matchesCredential:(SFPasswordCredential*)secondCredential +{ + return [firstCredential.primaryServiceIdentifier isEqual:secondCredential.primaryServiceIdentifier] && + [[NSSet setWithArray:firstCredential.supplementaryServiceIdentifiers] isEqualToSet:[NSSet setWithArray:secondCredential.supplementaryServiceIdentifiers]] && + [firstCredential.localizedLabel isEqualToString:secondCredential.localizedLabel] && + [firstCredential.localizedDescription isEqualToString:secondCredential.localizedDescription] && + [firstCredential.customAttributes isEqualToDictionary:secondCredential.customAttributes]; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-retain-cycles" +// we don't care about creating retain cycles inside our testing blocks (they get broken properly anyway) + +- (void)testAddAndFetchCredential +{ + SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]]; + __block NSString* credentialIdentifier = nil; + + XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"]; + [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) { + credentialIdentifier = persistentIdentifier; + XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential"); + XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error); + [addExpectation fulfill]; + }]; + [self waitForExpectations:@[addExpectation] timeout:5.0]; + + XCTestExpectation* fetchExpecation = [self expectationWithDescription:@"fetch credential"]; + [_credentialStore fetchPasswordCredentialForPersistentIdentifier:credentialIdentifier withResultHandler:^(SFPasswordCredential* fetchedCredential, NSString* password, NSError* error) { + XCTAssertNotNil(fetchedCredential, @"failed to fetch credential just added to store"); + XCTAssertNil(error, @"received unexpected error fetching credential from store: %@", error); + XCTAssertTrue([self passwordCredential:credential matchesCredential:fetchedCredential], @"the credential we fetched from the store does not match the one we added"); + XCTAssertEqualObjects(password, @"TestPass", @"the password we fetched from the store does not match the one we added"); + [fetchExpecation fulfill]; + }]; + [self waitForExpectations:@[fetchExpecation] timeout:5.0]; +} + +- (void)testLookupCredential +{ + SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]]; + + XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"]; + [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) { + XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential"); + XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error); + [addExpectation fulfill]; + }]; + [self waitForExpectations:@[addExpectation] timeout:5.0]; + + SFServiceIdentifier* serviceIdentifier = [SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]; + if (!serviceIdentifier) { + XCTAssertTrue(false, @"Failed to create a service identifier; aborting test"); + return; + } + + XCTestExpectation* lookupExpecation = [self expectationWithDescription:@"lookup credential"]; + [_credentialStore lookupCredentialsForServiceIdentifiers:@[serviceIdentifier] withResultHandler:^(NSArray* results, NSError* error) { + XCTAssertEqual((int)results.count, 1, @"error looking up credentials with service identifiers; expected 1 result but got %d", (int)results.count); + XCTAssertTrue([self passwordCredential:credential matchesCredential:(SFPasswordCredential*)results.firstObject], @"the credential we looked up does not match the one we added"); + [lookupExpecation fulfill]; + }]; + [self waitForExpectations:@[lookupExpecation] timeout:5.0]; +} + +- (void)testAddDuplicateCredential +{ + SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]]; + + XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"]; + [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) { + XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential"); + XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error); + [addExpectation fulfill]; + }]; + [self waitForExpectations:@[addExpectation] timeout:5.0]; + + XCTestExpectation* conflictingAddExpectation = [self expectationWithDescription:@"add conflicting item"]; + SFCredential* conflictingCredential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"DifferentPassword" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]]; + [_credentialStore addCredential:conflictingCredential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) { + XCTAssertNil(persistentIdentifier, @"adding a credential seems to have succeeded when we expected it to fail"); + XCTAssertNotNil(error, @"failed to get error when adding a credential that should be rejected as a duplicate entry"); + XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"duplicate error domain is not SFKeychainErrorDomain"); + XCTAssertEqual(error.code, SFKeychainErrorDuplicateItem, @"duplicate error is not SFKeychainErrorDuplicateItem"); + [conflictingAddExpectation fulfill]; + }]; + [self waitForExpectations:@[conflictingAddExpectation] timeout:5.0]; +} + +- (void)testRemoveCredential +{ + SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]]; + + __block NSString* newItemPersistentIdentifier = nil; + XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"]; + [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) { + XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential"); + XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error); + + newItemPersistentIdentifier = persistentIdentifier; + [addExpectation fulfill]; + }]; + [self waitForExpectations:@[addExpectation] timeout:5.0]; + + XCTestExpectation* removeExpectation = [self expectationWithDescription:@"remove credential"]; + [_credentialStore removeCredentialWithPersistentIdentifier:newItemPersistentIdentifier withResultHandler:^(BOOL success, NSError* error) { + XCTAssertTrue(success, @"failed to remove credential from store"); + XCTAssertNil(error, @"encountered error attempting to remove credential from store: %@", error); + [removeExpectation fulfill]; + }]; + [self waitForExpectations:@[removeExpectation] timeout:5.0]; + + XCTestExpectation* removeAgainExpectation = [self expectationWithDescription:@"remove credential gain"]; + [_credentialStore removeCredentialWithPersistentIdentifier:newItemPersistentIdentifier withResultHandler:^(BOOL success, NSError* error) { + XCTAssertFalse(success, @"somehow succeeded at removing a credential that we'd already deleted"); + XCTAssertNotNil(error, @"failed to get an error attempting to remove credential from store when there should not be a credential to delete"); + [removeAgainExpectation fulfill]; + }]; + + XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch credential"]; + [_credentialStore fetchPasswordCredentialForPersistentIdentifier:newItemPersistentIdentifier withResultHandler:^(SFPasswordCredential* fetchedCredential, NSString* password, NSError* error) { + XCTAssertNil(fetchedCredential, @"found credential that we expected to be deleted"); + XCTAssertNil(password, @"found password when credential was supposed to be deleted"); + XCTAssertNotNil(error, "failed to get an error when fetching deleted credential"); + [fetchExpectation fulfill]; + }]; + [self waitForExpectations:@[removeAgainExpectation, fetchExpectation] timeout:5.0]; + + // now try adding the thing again to make sure that works + XCTestExpectation* addAgainExpectation = [self expectationWithDescription:@"add credential again"]; + [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) { + XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential"); + XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error); + XCTAssertNotEqual(persistentIdentifier, newItemPersistentIdentifier, @"the added credential has the same persistent identifier as the item we already deleted"); + + newItemPersistentIdentifier = persistentIdentifier; + [addAgainExpectation fulfill]; + }]; + [self waitForExpectations:@[addAgainExpectation] timeout:5.0]; + + XCTestExpectation* fetchAgainExpectation = [self expectationWithDescription:@"fetch credential again"]; + [_credentialStore fetchPasswordCredentialForPersistentIdentifier:newItemPersistentIdentifier withResultHandler:^(SFPasswordCredential* fetchedCredential, NSString* password, NSError* error) { + XCTAssertNotNil(fetchedCredential, @"failed to fetch credential just added to store"); + XCTAssertNil(error, @"received unexpected error fetching credential from store: %@", error); + XCTAssertTrue([self passwordCredential:credential matchesCredential:fetchedCredential], @"the credential we fetched from the store does not match the one we added"); + XCTAssertEqualObjects(password, @"TestPass", @"the password we fetched from the store does not match the one we added"); + [fetchAgainExpectation fulfill]; + }]; + [self waitForExpectations:@[fetchAgainExpectation] timeout:5.0]; +} + +- (void)testRemoveCredentialWithBadPersistentIdentifier +{ + SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]]; + + __block NSString* newItemPersistentIdentifier = nil; + XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"]; + [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) { + XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential"); + XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error); + + newItemPersistentIdentifier = persistentIdentifier; + [addExpectation fulfill]; + }]; + [self waitForExpectations:@[addExpectation] timeout:5.0]; + + NSString* wrongPersistentIdentifier = [[NSUUID UUID] UUIDString]; + XCTestExpectation* removeWrongIdentifierEsxpectation = [self expectationWithDescription:@"remove wrong persistent identifier"]; + [_credentialStore removeCredentialWithPersistentIdentifier:wrongPersistentIdentifier withResultHandler:^(BOOL success, NSError* error) { + XCTAssertFalse(success, @"reported success deleting a credential that was never there"); + XCTAssertNotNil(error, @"failed to get error when attempting to delete an item with an erroneous persistent identifier"); + [removeWrongIdentifierEsxpectation fulfill]; + }]; + + NSString* notEvenAUUIDString = @"badstring"; + XCTestExpectation* removeNonUUIDIdentifierExpectation = [self expectationWithDescription:@"remove non-uuid string identifier"]; + [_credentialStore removeCredentialWithPersistentIdentifier:notEvenAUUIDString withResultHandler:^(BOOL success, NSError* error) { + XCTAssertFalse(success, @"reported success deleting a credential with a malformed persistent identifier"); + XCTAssertNotNil(error, @"failed to get error when attempting to delete an item with a malformed persistent identifier"); + XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain); + XCTAssertEqual(error.code, SFKeychainErrorInvalidPersistentIdentifier); + [removeNonUUIDIdentifierExpectation fulfill]; + }]; + [self waitForExpectations:@[removeWrongIdentifierEsxpectation, removeNonUUIDIdentifierExpectation] timeout:5.0]; +} + +#pragma clang diagnostic pop + +@end + +#endif diff --git a/sectask/SecTask.c b/sectask/SecTask.c index 284a480d..11b2b4b6 100644 --- a/sectask/SecTask.c +++ b/sectask/SecTask.c @@ -379,7 +379,10 @@ Boolean SecTaskEntitlementsValidated(SecTaskRef task) { // TODO: Cache the result uint32_t csflags = 0; const uint32_t mask = CS_VALID | CS_KILL | CS_ENTITLEMENTS_VALIDATED; + const uint32_t debug_mask = CS_DEBUGGED | CS_ENTITLEMENTS_VALIDATED; int rc = csops_task(task, CS_OPS_STATUS, &csflags, sizeof(csflags)); - return rc != -1 && ((csflags & mask) == mask); + // Allow debugged processes that were valid to continue being treated as valid + // We need this all the time (not just on internal) because third parties may need to debug their entitled process in xcode + return (rc != -1) && ((mask & csflags) == mask || (debug_mask & csflags) == debug_mask); } diff --git a/sectask/SecTask.h b/sectask/SecTask.h index 7141a5b3..93022dff 100644 --- a/sectask/SecTask.h +++ b/sectask/SecTask.h @@ -29,9 +29,7 @@ #include #include -#if SEC_OS_IPHONE_INCLUDES #include -#endif #if SEC_OS_OSX #include diff --git a/security-sysdiagnose/security-sysdiagnose.m b/security-sysdiagnose/security-sysdiagnose.m index 1456af69..68473514 100644 --- a/security-sysdiagnose/security-sysdiagnose.m +++ b/security-sysdiagnose/security-sysdiagnose.m @@ -145,6 +145,7 @@ homekit_sysdiagnose(void) (id)kSecMatchLimit : (id)kSecMatchLimitAll, (id)kSecReturnAttributes: @YES, (id)kSecReturnData: @NO, + (id)kSecAttrNoLegacy : @YES, } mutableCopy]; CFTypeRef result = NULL; @@ -196,47 +197,6 @@ unlock_sysdiagnose(void) CFReleaseNull(result); } -static void idsproxy_print_message(CFDictionaryRef messages) -{ - NSDictionary *idsMessages = (__bridge NSDictionary *)messages; - - printf("IDS messages in flight: %d\n", (int)[idsMessages count]); - - [idsMessages enumerateKeysAndObjectsUsingBlock:^(NSString* _Nonnull identifier, NSDictionary* _Nonnull messageDictionary, BOOL * _Nonnull stop) { - printf("message identifier: %s\n", [identifier cStringUsingEncoding:NSUTF8StringEncoding]); - - NSDictionary *messageDataAndPeerID = [messageDictionary valueForKey:(__bridge NSString*)kIDSMessageToSendKey]; - [messageDataAndPeerID enumerateKeysAndObjectsUsingBlock:^(NSString* _Nonnull peerID, NSData* _Nonnull messageData, BOOL * _Nonnull stop1) { - if(messageData) - printf("size of message to recipient: %lu\n", (unsigned long)[messageData length]); - }]; - - NSString *deviceID = [messageDictionary valueForKey:(__bridge NSString*)kIDSMessageRecipientDeviceID]; - if(deviceID) - printf("recipient device id: %s\n", [deviceID cStringUsingEncoding:NSUTF8StringEncoding]); - - }]; -} - -static void -idsproxy_sysdiagnose(void) -{ - - dispatch_semaphore_t wait_for = dispatch_semaphore_create(0); - __block CFDictionaryRef returned = NULL; - - dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - SOSCloudKeychainRetrievePendingMessageFromProxy(processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef error) { - secdebug("SOSCloudKeychainRetrievePendingMessageFromProxy", "returned: %@", returnedValues); - CFRetainAssign(returned, returnedValues); - dispatch_semaphore_signal(wait_for); - }); - - dispatch_semaphore_wait(wait_for, dispatch_time(DISPATCH_TIME_NOW, 2ull * NSEC_PER_SEC)); - secdebug("idsproxy sysdiagnose", "messages: %@", returned); - - idsproxy_print_message(returned); -} static void analytics_sysdiagnose(void) @@ -281,7 +241,6 @@ main(int argc, const char ** argv) engine_sysdiagnose(); homekit_sysdiagnose(); unlock_sysdiagnose(); - idsproxy_sysdiagnose(); analytics_sysdiagnose(); // Keep this one last diff --git a/securityd/securityd_service/KeyStore/KeyStoreEvents.c b/securityd/securityd_service/KeyStore/KeyStoreEvents.c index 726743f8..a64addcc 100644 --- a/securityd/securityd_service/KeyStore/KeyStoreEvents.c +++ b/securityd/securityd_service/KeyStore/KeyStoreEvents.c @@ -26,7 +26,7 @@ static void start(dispatch_queue_t queue) { IOReturn result; io_service_t aksService = IO_OBJECT_NULL; - IONotificationPortRef aksNotifyPort = IO_OBJECT_NULL; + IONotificationPortRef aksNotifyPort = NULL; io_object_t notification = IO_OBJECT_NULL; aksService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kAppleKeyStoreServiceName)); diff --git a/securityd/securityd_service/securityd_service.xcodeproj/project.pbxproj b/securityd/securityd_service/securityd_service.xcodeproj/project.pbxproj index 0c3c44c0..523e170e 100644 --- a/securityd/securityd_service/securityd_service.xcodeproj/project.pbxproj +++ b/securityd/securityd_service/securityd_service.xcodeproj/project.pbxproj @@ -347,7 +347,7 @@ 189D462D166AC95C001D8533 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1000; ORGANIZATIONNAME = Apple; }; buildConfigurationList = 189D4630166AC95C001D8533 /* Build configuration list for PBXProject "securityd_service" */; @@ -476,14 +476,20 @@ ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPRESSION = lossless; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -527,14 +533,20 @@ ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPRESSION = "respect-asset-catalog"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -570,10 +582,6 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = securityd_service/service.entitlements; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); INSTALL_PATH = /usr/libexec; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -583,10 +591,6 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = securityd_service/service.entitlements; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); INSTALL_PATH = /usr/libexec; PRODUCT_NAME = "$(TARGET_NAME)"; }; diff --git a/securityd/securityd_service/securityd_service/main.c b/securityd/securityd_service/securityd_service/main.c index b3eb3c01..52bf2348 100644 --- a/securityd/securityd_service/securityd_service/main.c +++ b/securityd/securityd_service/securityd_service/main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -219,23 +220,23 @@ _kb_verify_create_path(service_user_record_t * ur) if (S_ISDIR(st_info.st_mode)) { created = true; } else { - os_log(OS_LOG_DEFAULT, "invalid directory at '%s' moving aside", kb_path); + os_log(OS_LOG_DEFAULT, "invalid directory at '%{public}s' moving aside", kb_path); snprintf(new_path, sizeof(new_path), "%s-invalid", kb_path); unlink(new_path); if (rename(kb_path, new_path) != 0) { - os_log(OS_LOG_DEFAULT, "failed to rename file: %s (%s)", kb_path, strerror(errno)); + os_log(OS_LOG_DEFAULT, "failed to rename file: %{public}s %{darwin.errno}d", kb_path, errno); goto done; } } } if (!created) { - require_action(mkpath_np(kb_path, 0700) == 0, done, os_log(OS_LOG_DEFAULT, "could not create path: %s (%s)", kb_path, strerror(errno))); + require_action(mkpath_np(kb_path, 0700) == 0, done, os_log(OS_LOG_DEFAULT, "could not create path: %{public}s %{darwin.errno}d", kb_path, errno)); created = true; } done: if (!created) { - os_log(OS_LOG_DEFAULT, "_kb_verify_create_path failed %s", kb_path); + os_log(OS_LOG_DEFAULT, "_kb_verify_create_path failed %{public}s", kb_path); } return created; } @@ -244,7 +245,7 @@ static void _set_thread_credentials(service_user_record_t * ur) { int rc = pthread_setugid_np(ur->uid, ur->gid); - if (rc) { os_log(OS_LOG_DEFAULT, "failed to set thread credential: %i (%s)", errno, strerror(errno)); } + if (rc) { os_log(OS_LOG_DEFAULT, "failed to set thread credential: %{darwin.errno}d", errno); } rc = initgroups(ur->name, ur->gid); if (rc) { os_log(OS_LOG_DEFAULT, "failed to initgroups: %i", rc); } @@ -254,7 +255,7 @@ static void _clear_thread_credentials() { int rc = pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE); - if (rc) { os_log(OS_LOG_DEFAULT, "failed to reset thread credential: %i (%s)", errno, strerror(errno)); } + if (rc) { os_log(OS_LOG_DEFAULT, "failed to reset thread credential: %{darwin.errno}d", errno); } } static bool @@ -271,11 +272,11 @@ _kb_bag_exists(service_user_record_t * ur, const char * bag_file) if (S_ISREG(st_info.st_mode)) { exists = true; } else { - os_log(OS_LOG_DEFAULT, "invalid file at '%s' moving aside", bag_file); + os_log(OS_LOG_DEFAULT, "invalid file at '%{public}s' moving aside", bag_file); snprintf(new_file, sizeof(new_file), "%s-invalid", bag_file); unlink(new_file); if (rename(bag_file, new_file) != 0) { - os_log(OS_LOG_DEFAULT, "failed to rename file: %s (%s)", bag_file, strerror(errno)); + os_log(OS_LOG_DEFAULT, "failed to rename file: %{public}s %{darwin.errno}d", bag_file, errno); } } } @@ -300,13 +301,13 @@ _kb_save_bag_to_disk(service_user_record_t * ur, const char * bag_file, void * d require_action(snprintf(tmp_bag, sizeof(tmp_bag), "%s.tmp", bag_file) < sizeof(tmp_bag), done, os_log(OS_LOG_DEFAULT, "path too large")); fd = open(tmp_bag, O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW, 0600); - require_action(fd != -1, done, os_log(OS_LOG_DEFAULT, "could not create file: %s (%s)", tmp_bag, strerror(errno))); - require_action(write(fd, data, length) == length, done, os_log(OS_LOG_DEFAULT, "failed to write keybag to disk %s (%s)", tmp_bag, strerror(errno))); + require_action(fd != -1, done, os_log(OS_LOG_DEFAULT, "could not create file: %{public}s %{darwin.errno}d", tmp_bag, errno)); + require_action(write(fd, data, length) == length, done, os_log(OS_LOG_DEFAULT, "failed to write keybag to disk %s %{darwin.errno}d", tmp_bag, errno)); /* try atomic swap (will fail if destination doesn't exist); if that fails, try regular rename */ if (renamex_np(tmp_bag, bag_file, RENAME_SWAP) != 0) { - os_log(OS_LOG_DEFAULT, "Warning: atomic swap failed, error=%i (%s)", errno, strerror(errno)); - require_noerr_action(rename(tmp_bag, bag_file), done, os_log(OS_LOG_DEFAULT, "could not save keybag file, error=%i (%s)", errno, strerror(errno))); + os_log(OS_LOG_DEFAULT, "Warning: atomic swap failed, error= %{darwin.errno}d", errno); + require_noerr_action(rename(tmp_bag, bag_file), done, os_log(OS_LOG_DEFAULT, "could not save keybag file, error= %{darwin.errno}d", errno)); } else { (void)unlink(tmp_bag); } @@ -332,12 +333,12 @@ _kb_load_bag_from_disk(service_user_record_t * ur, const char * bag_file, uint8_ _set_thread_credentials(ur); require(_kb_verify_create_path(ur), done); - require_action_quiet(lstat(bag_file, &st_info) == 0, done, os_log(OS_LOG_DEFAULT, "failed to stat file: %s (%s)", bag_file, strerror(errno))); - require_action(S_ISREG(st_info.st_mode), done, os_log(OS_LOG_DEFAULT, "failed to load, not a file: %s", bag_file)); + require_action_quiet(lstat(bag_file, &st_info) == 0, done, os_log(OS_LOG_DEFAULT, "failed to stat file: %{public}s %{darwin.errno}d", bag_file, errno)); + require_action(S_ISREG(st_info.st_mode), done, os_log(OS_LOG_DEFAULT, "failed to load, not a file: %{public}s", bag_file)); buf_size = (size_t)st_info.st_size; fd = open(bag_file, O_RDONLY | O_NOFOLLOW); - require_action(fd != -1, done, os_log(OS_LOG_DEFAULT, "could not open file: %s (%s)", bag_file, strerror(errno))); + require_action(fd != -1, done, os_log(OS_LOG_DEFAULT, "could not open file: %{public}s %{darwin.errno}d", bag_file, errno)); buf = (uint8_t *)calloc(1u, buf_size); require(buf != NULL, done); @@ -365,10 +366,10 @@ _kb_invalidate_bag(service_user_record_t *ur, const char * bag_file, uint64_t * require(ur, out); if (_kb_load_bag_from_disk(ur, bag_file, &buf, &buf_size, kcv)) { - require_action(buf && buf_size <= INT_MAX, out, os_log(OS_LOG_DEFAULT, "failed to read: %s", bag_file)); - require_noerr_action(aks_invalidate_bag(buf, (int)buf_size), out, os_log(OS_LOG_DEFAULT, "failed to invalidate file: %s", bag_file)); + require_action(buf && buf_size <= INT_MAX, out, os_log(OS_LOG_DEFAULT, "failed to read: %{public}s", bag_file)); + require_noerr_action(aks_invalidate_bag(buf, (int)buf_size), out, os_log(OS_LOG_DEFAULT, "failed to invalidate file: %{public}s", bag_file)); } else { - os_log(OS_LOG_DEFAULT, "failed to read file: %s", bag_file); + os_log(OS_LOG_DEFAULT, "failed to read file: %{public}s", bag_file); } out: @@ -400,13 +401,9 @@ _kb_delete_bag_on_disk(service_user_record_t * ur, const char * bag_file, uint64 } } -static int service_kb_load(service_context_t *context, uint64_t * kcv); +static int service_kb_load(service_context_t *context); static int service_kb_load_uid(uid_t s_uid, uint64_t * kcv); -#ifndef AKS_MACOS_ROOT_HANDLE -#define AKS_MACOS_ROOT_HANDLE 4 //temporary define to avoid dependency on AKS change, filed rdar://problem/30542034 -#endif /* AKS_MACOS_ROOT_HANDLE */ - static int _service_kb_set_system(keybag_handle_t handle, keybag_handle_t special_handle) { @@ -422,7 +419,7 @@ _service_kb_get_system(keybag_handle_t special_handle, keybag_handle_t * handle_ } static int -_kb_get_session_handle(service_context_t * context, keybag_handle_t * handle_out, uint64_t * kcv) +_kb_get_session_handle(service_context_t * context, keybag_handle_t * handle_out) { int rc = KB_BagNotLoaded; require_noerr_quiet(_service_kb_get_system(context->s_uid, handle_out), done); @@ -431,7 +428,7 @@ _kb_get_session_handle(service_context_t * context, keybag_handle_t * handle_out done: if (rc == KB_BagNotLoaded) { - if (service_kb_load(context, kcv) == KB_Success) { + if (service_kb_load(context) == KB_Success) { if (_service_kb_get_system(context->s_uid, handle_out) == kIOReturnSuccess) { rc = KB_Success; } @@ -443,7 +440,7 @@ done: static void update_keybag_handle(keybag_handle_t handle) { dispatch_sync(_kb_service_get_dispatch_queue(), ^{ - uid_t uid = abs(handle); + uid_t uid = (handle == (-AKS_MACOS_ROOT_HANDLE)) ? 0 : abs(handle); uint8_t * buf = NULL; size_t buf_size = 0; service_user_record_t * ur = NULL; @@ -519,7 +516,7 @@ done: } static int -service_kb_create(service_context_t * context, const void * secret, int secret_len, uint64_t * kcv) +service_kb_create(service_context_t * context, const void * secret, int secret_len) { __block int rc = KB_GeneralError; @@ -537,9 +534,9 @@ service_kb_create(service_context_t * context, const void * secret, int secret_l require_noerr(rc = aks_create_bag(secret, secret_len, kAppleKeyStoreDeviceBag, &private_handle), done); require_noerr(rc = aks_save_bag(private_handle, (void**)&buf, (int*)&buf_size), done); - require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, kcv), done, rc = KB_BagError); + require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, &context->kcv), done, rc = KB_BagError); require_noerr(rc = _service_kb_set_system(private_handle, context->s_uid), done); - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); if (secret && rc == KB_Success) { aks_unlock_bag(session_handle, secret, secret_len); @@ -608,7 +605,7 @@ _service_kb_load_uid(uid_t s_uid, uint64_t * kcv) } // this function should never fail unless bootstrapping the user for the first time, or rare conditions from aks_load_bag if (rc != KB_Success) { - os_log(OS_LOG_DEFAULT, "%d: error %d loading keybag for uid (%i) at path: %s", _stage, rc, s_uid, bag_file); + os_log(OS_LOG_DEFAULT, "%d: error %d loading keybag for uid (%i) at path: %{public}s", _stage, rc, s_uid, bag_file); } if (buf) free(buf); if (ur) free_user_record(ur); @@ -625,9 +622,9 @@ service_kb_load_uid(uid_t s_uid, uint64_t * kcv) } static int -service_kb_load(service_context_t * context, uint64_t * kcv) +service_kb_load(service_context_t * context) { - return _service_kb_load_uid(context->s_uid, kcv); + return _service_kb_load_uid(context->s_uid, &context->kcv); } static int @@ -662,11 +659,11 @@ service_kb_unload(service_context_t *context) } static int -service_kb_save(service_context_t * context, uint64_t * kcv) +service_kb_save(service_context_t * context) { __block int rc = KB_GeneralError; keybag_handle_t session_handle; - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); dispatch_sync(_kb_service_get_dispatch_queue(), ^{ uint8_t * buf = NULL; @@ -677,7 +674,7 @@ service_kb_save(service_context_t * context, uint64_t * kcv) require_noerr(rc = aks_save_bag(session_handle, (void**)&buf, (int*)&buf_size), done); require_action(ur = get_user_record(context->s_uid), done, rc = KB_GeneralError); require_action(bag_file = _kb_copy_bag_filename(ur, kb_bag_type_user), done, rc = KB_GeneralError); - require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, kcv), done, rc = KB_BagError); + require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, &context->kcv), done, rc = KB_BagError); rc = KB_Success; @@ -693,7 +690,7 @@ done: } static int -service_kb_unlock(service_context_t * context, const void * secret, int secret_len, uint64_t * kcv) +service_kb_unlock(service_context_t * context, const void * secret, int secret_len) { int rc = KB_GeneralError; keybag_handle_t session_handle; @@ -703,7 +700,7 @@ service_kb_unlock(service_context_t * context, const void * secret, int secret_l require_noerr(_kb_get_options_for_uid(context->s_uid, &options), done); /* technically, session_handle is not needed. Call this to handle lazy keybag loading */ - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); require(passcode = CFDataCreateWithBytesNoCopy(NULL, secret, secret_len, kCFAllocatorNull), done); @@ -724,11 +721,11 @@ service_kb_lock(service_context_t * context) } static int -service_kb_change_secret(service_context_t * context, const void * secret, int secret_len, const void * new_secret, int new_secret_len, uint64_t * kcv) +service_kb_change_secret(service_context_t * context, const void * secret, int secret_len, const void * new_secret, int new_secret_len) { __block int rc = KB_GeneralError; keybag_handle_t session_handle; - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); dispatch_sync(_kb_service_get_dispatch_queue(), ^{ uint8_t * buf = NULL; @@ -740,7 +737,7 @@ service_kb_change_secret(service_context_t * context, const void * secret, int s require_noerr(rc = aks_save_bag(session_handle, (void**)&buf, (int*)&buf_size), done); require_action(ur = get_user_record(context->s_uid), done, rc = KB_GeneralError); require_action(bag_file = _kb_copy_bag_filename(ur, kb_bag_type_user), done, rc = KB_GeneralError); - require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, kcv), done, rc = KB_BagError); + require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, &context->kcv), done, rc = KB_BagError); rc = KB_Success; @@ -756,7 +753,7 @@ done: } static int -service_kb_reset(service_context_t * context, const void * secret, int secret_len, uint64_t * kcv) +service_kb_reset(service_context_t * context, const void * secret, int secret_len) { __block int rc = KB_GeneralError; service_user_record_t * ur = NULL; @@ -771,13 +768,13 @@ service_kb_reset(service_context_t * context, const void * secret, int secret_le keybag_handle_t private_handle = bad_keybag_handle, session_handle = bad_keybag_handle; os_log(OS_LOG_DEFAULT, "resetting keybag for uid (%i) in session (%i)", context->s_uid, context->s_id); - _kb_rename_bag_on_disk(ur, bag_file, kcv); + _kb_rename_bag_on_disk(ur, bag_file, &context->kcv); require_noerr(rc = aks_create_bag(secret, secret_len, kAppleKeyStoreDeviceBag, &private_handle), done); require_noerr(rc = aks_save_bag(private_handle, (void**)&buf, (int*)&buf_size), done); - require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, kcv), done, rc = KB_BagError); + require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, &context->kcv), done, rc = KB_BagError); require_noerr(rc = _service_kb_set_system(private_handle, context->s_uid), done); - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); if (secret && rc == KB_Success) { aks_unlock_bag(session_handle, secret, secret_len); @@ -802,12 +799,12 @@ done: } static int -service_kb_is_locked(service_context_t * context, xpc_object_t reply, uint64_t * kcv) +service_kb_is_locked(service_context_t * context, xpc_object_t reply) { int rc = KB_GeneralError; keybag_state_t state; keybag_handle_t session_handle; - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); require_noerr(rc = aks_get_lock_state(session_handle, &state), done); @@ -819,7 +816,7 @@ done: } static int -service_kb_wrap_key(service_context_t *context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv) +service_kb_wrap_key(service_context_t *context, xpc_object_t event, xpc_object_t reply) { int rc = KB_GeneralError; size_t sz; @@ -831,7 +828,7 @@ service_kb_wrap_key(service_context_t *context, xpc_object_t event, xpc_object_t int wrapped_key_size; keyclass_t wrapped_key_class; - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); key = xpc_dictionary_get_data(event, SERVICE_XPC_KEY, &sz); require_action(key != NULL, done, rc = KB_GeneralError); @@ -854,7 +851,7 @@ done: } static int -service_kb_unwrap_key(service_context_t *context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv) +service_kb_unwrap_key(service_context_t *context, xpc_object_t event, xpc_object_t reply) { int rc = KB_GeneralError; size_t sz; @@ -865,7 +862,7 @@ service_kb_unwrap_key(service_context_t *context, xpc_object_t event, xpc_object void *key = NULL; int key_size; - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); wrapped_key = xpc_dictionary_get_data(event, SERVICE_XPC_WRAPPED_KEY, &sz); require_action(wrapped_key != NULL, done, rc = KB_GeneralError); @@ -887,7 +884,7 @@ done: } static int -service_kb_stash_create(service_context_t * context, const void * key, unsigned key_size, uint64_t * kcv) +service_kb_stash_create(service_context_t * context, const void * key, unsigned key_size) { int rc = KB_GeneralError; char * bag_file = NULL; @@ -898,14 +895,14 @@ service_kb_stash_create(service_context_t * context, const void * key, unsigned __block bool saved = false; require(key, done); - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); require_action(ur = get_user_record(context->s_uid), done, rc = KB_GeneralError); require_noerr(rc = aks_stash_escrow(session_handle, true, key, key_size, NULL, 0, (void**)&stashbag, &stashbag_size), done); require_action(bag_file = _kb_copy_bag_filename(ur, kb_bag_type_stash), done, rc = KB_GeneralError); // sync writing the bag to disk dispatch_sync(_kb_service_get_dispatch_queue(), ^{ - saved = _kb_save_bag_to_disk(ur, bag_file, stashbag, stashbag_size, kcv); + saved = _kb_save_bag_to_disk(ur, bag_file, stashbag, stashbag_size, &context->kcv); }); require_action(saved, done, rc = KB_BagError); rc = KB_Success; @@ -918,7 +915,7 @@ done: } static int -service_kb_stash_load(service_context_t * context, const void * key, unsigned key_size, bool nondestructive, uint64_t * kcv) +service_kb_stash_load(service_context_t * context, const void * key, unsigned key_size, bool nondestructive) { __block int rc = KB_GeneralError; char * bag_file = NULL; @@ -928,13 +925,13 @@ service_kb_stash_load(service_context_t * context, const void * key, unsigned ke __block size_t stashbag_size = 0; require(key, done); - require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(rc = _kb_get_session_handle(context, &session_handle), done); require_action(ur = get_user_record(context->s_uid), done, rc = KB_GeneralError); require_action(bag_file = _kb_copy_bag_filename(ur, kb_bag_type_stash), done, rc = KB_GeneralError); // sync loading the bag from disk dispatch_sync(_kb_service_get_dispatch_queue(), ^{ - if (!_kb_load_bag_from_disk(ur, bag_file, &stashbag, &stashbag_size, kcv)) { + if (!_kb_load_bag_from_disk(ur, bag_file, &stashbag, &stashbag_size, &context->kcv)) { rc = KB_BagError; } }); @@ -946,7 +943,7 @@ service_kb_stash_load(service_context_t * context, const void * key, unsigned ke done: if (stashbag) { free(stashbag); } if ((bag_file) && (!nondestructive)) { - _kb_delete_bag_on_disk(ur, bag_file, kcv); + _kb_delete_bag_on_disk(ur, bag_file, &context->kcv); free(bag_file); } if (ur) free_user_record(ur); @@ -959,7 +956,7 @@ done: // removed from the keystore after it is returned. // Requires the entitlement: com.apple.private.securityd.keychain // -OSStatus service_stash_get_key(service_context_t * context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv) +OSStatus service_stash_get_key(service_context_t * context, xpc_object_t event, xpc_object_t reply) { getStashKey_InStruct_t inStruct; getStashKey_OutStruct_t outStruct; @@ -978,7 +975,7 @@ OSStatus service_stash_get_key(service_context_t * context, xpc_object_t event, if (kr == KERN_SUCCESS) { xpc_dictionary_set_data(reply, SERVICE_XPC_KEY, outStruct.outBuf.key.key, outStruct.outBuf.key.keysize); - service_kb_stash_load(context, outStruct.outBuf.key.key, outStruct.outBuf.key.keysize, false, kcv); + service_kb_stash_load(context, outStruct.outBuf.key.key, outStruct.outBuf.key.keysize, false); } else { os_log(OS_LOG_DEFAULT, "failed to get stash key: %d", (int)kr); } @@ -998,7 +995,7 @@ done: // key and get its uuid. The second uses the uuid to flag the // key for blob inclusion. // -OSStatus service_stash_set_key(service_context_t * context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv) +OSStatus service_stash_set_key(service_context_t * context, xpc_object_t event, xpc_object_t reply) { kern_return_t kr = KERN_INVALID_ARGUMENT; io_connect_t conn = IO_OBJECT_NULL; @@ -1007,7 +1004,7 @@ OSStatus service_stash_set_key(service_context_t * context, xpc_object_t event, keybag_state_t state; keybag_handle_t session_handle; - require_noerr(_kb_get_session_handle(context, &session_handle, kcv), done); + require_noerr(_kb_get_session_handle(context, &session_handle), done); require_noerr(aks_get_lock_state(session_handle, &state), done); require_action(!(state & keybag_lock_locked), done, kr = CSSMERR_CSP_OS_ACCESS_DENIED; LOG("stash failed keybag locked")); @@ -1044,7 +1041,7 @@ OSStatus service_stash_set_key(service_context_t * context, xpc_object_t event, NULL, NULL); if (kr == KERN_SUCCESS) { - service_kb_stash_create(context, keydata, (unsigned)keydata_len, kcv); + service_kb_stash_create(context, keydata, (unsigned)keydata_len); } done: os_log(OS_LOG_DEFAULT, "set stashkey %d", (int)kr); @@ -1058,7 +1055,7 @@ done: // // Load the master stash key // -OSStatus service_stash_load_key(service_context_t * context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv) +OSStatus service_stash_load_key(service_context_t * context, xpc_object_t event, xpc_object_t reply) { kern_return_t kr = KERN_SUCCESS; size_t keydata_len = 0; @@ -1066,7 +1063,7 @@ OSStatus service_stash_load_key(service_context_t * context, xpc_object_t event, const uint8_t *keydata = xpc_dictionary_get_data(event, SERVICE_XPC_KEY, &keydata_len); require(keydata, done); - kr = service_kb_stash_load(context, keydata, (cryptosize_t) keydata_len, true, kcv); + kr = service_kb_stash_load(context, keydata, (cryptosize_t) keydata_len, true); done: return kr; @@ -1212,7 +1209,6 @@ void service_peer_event_handler(xpc_connection_t connection, xpc_object_t event) bool free_context = false; const void * data; const char *entitlement; - uint64_t kcv = 0; xpc_object_t reply = xpc_dictionary_create_reply(event); @@ -1259,6 +1255,7 @@ void service_peer_event_handler(xpc_connection_t connection, xpc_object_t event) context->procToken = audit_token; free_context = true; } + context->kcv = 0; require_action(context->s_id != AU_DEFAUDITSID, done, rc = KB_InvalidSession); require_action(context->s_uid != AU_DEFAUDITID, done, rc = KB_InvalidSession); // we only want to work in actual user sessions. @@ -1267,21 +1264,21 @@ void service_peer_event_handler(xpc_connection_t connection, xpc_object_t event) case SERVICE_KB_CREATE: // if (kb_service_has_entitlement(peer, "com.apple.keystore.device")) { secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET, &secret_len); - rc = service_kb_create(context, secret, (int)secret_len, &kcv); + rc = service_kb_create(context, secret, (int)secret_len); // } break; case SERVICE_KB_LOAD: - rc = service_kb_load(context, &kcv); + rc = service_kb_load(context); break; case SERVICE_KB_UNLOAD: rc = service_kb_unload(context); break; case SERVICE_KB_SAVE: - rc = service_kb_save(context, &kcv); + rc = service_kb_save(context); break; case SERVICE_KB_UNLOCK: secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET, &secret_len); - rc = service_kb_unlock(context, secret, (int)secret_len, &kcv); + rc = service_kb_unlock(context, secret, (int)secret_len); break; case SERVICE_KB_LOCK: rc = service_kb_lock(context); @@ -1289,33 +1286,33 @@ void service_peer_event_handler(xpc_connection_t connection, xpc_object_t event) case SERVICE_KB_CHANGE_SECRET: secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET, &secret_len); new_secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET_NEW, &new_secret_len); - rc = service_kb_change_secret(context, secret, (int)secret_len, new_secret, (int)new_secret_len, &kcv); + rc = service_kb_change_secret(context, secret, (int)secret_len, new_secret, (int)new_secret_len); break; case SERVICE_KB_RESET: secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET, &secret_len); - rc = service_kb_reset(context, secret, (int)secret_len, &kcv); + rc = service_kb_reset(context, secret, (int)secret_len); break; case SERVICE_KB_IS_LOCKED: - rc = service_kb_is_locked(context, reply, &kcv); + rc = service_kb_is_locked(context, reply); break; case SERVICE_STASH_GET_KEY: - rc = service_stash_get_key(context, event, reply, &kcv); + rc = service_stash_get_key(context, event, reply); break; case SERVICE_STASH_SET_KEY: - rc = service_stash_set_key(context, event, reply, &kcv); + rc = service_stash_set_key(context, event, reply); break; case SERVICE_STASH_LOAD_KEY: - rc = service_stash_load_key(context, event, reply, &kcv); + rc = service_stash_load_key(context, event, reply); break; case SERVICE_KB_LOAD_UID: uid = (uid_t)xpc_dictionary_get_uint64(event, SERVICE_XPC_UID); - rc = service_kb_load_uid(uid, &kcv); + rc = service_kb_load_uid(uid, &context->kcv); break; case SERVICE_KB_WRAP_KEY: - rc = service_kb_wrap_key(context, event, reply, &kcv); + rc = service_kb_wrap_key(context, event, reply); break; case SERVICE_KB_UNWRAP_KEY: - rc = service_kb_unwrap_key(context, event, reply, &kcv); + rc = service_kb_unwrap_key(context, event, reply); break; #if DEBUG case SERVICE_STASH_BLOB: @@ -1331,15 +1328,15 @@ void service_peer_event_handler(xpc_connection_t connection, xpc_object_t event) { char log[200] = { 0 }; int count = snprintf(log, sizeof(log), "selector: %s (%llu), error: %s (%x), sid: %d, suid: %d, pid: %d", sel_to_char(request), request, err_to_char(rc), rc, context ? context->s_id : 0, context ? context->s_uid : 0, context ? get_caller_pid(&context->procToken) : 0); - if (log_kcv(request) && (count < sizeof(log) - 1) && (count > 0) && (kcv > 0)) { - count = snprintf(log + count, sizeof(log) - count, ", kcv: 0x%0llx", kcv); + if (log_kcv(request) && (count < sizeof(log) - 1) && (count > 0) && (context) && (context->kcv > 0)) { + count = snprintf(log + count, sizeof(log) - count, ", kcv: 0x%0llx", context->kcv); } if (count > 0) { #if DEBUG - LOG("%s", log); + LOG("%{public}s", log); #else if ((rc != 0) || log_kcv(request)) { - os_log(OS_LOG_DEFAULT, "%s", log); + os_log(OS_LOG_DEFAULT, "%{public}s", log); } #endif } @@ -1368,10 +1365,20 @@ bool check_signature(xpc_connection_t connection) uint32_t flags = SecTaskGetCodeSignStatus(task); /* check if valid and platform binary, but not platform path */ + + if ((flags & (CS_VALID | CS_PLATFORM_BINARY | CS_PLATFORM_PATH)) != (CS_VALID | CS_PLATFORM_BINARY)) { - os_log(OS_LOG_DEFAULT, "client is not a platform binary: %0x08x", flags); - CFRelease(task); - return false; + if (SecIsInternalRelease()) { + if ((flags & (CS_DEBUGGED | CS_PLATFORM_BINARY | CS_PLATFORM_PATH)) != (CS_DEBUGGED | CS_PLATFORM_BINARY)) { + os_log(OS_LOG_DEFAULT, "client is not a platform binary: 0x%08x", flags); + CFRelease(task); + return false; + } + } else { + os_log(OS_LOG_DEFAULT, "client is not a platform binary: 0x%08x", flags); + CFRelease(task); + return false; + } } CFStringRef signingIdentity = SecTaskCopySigningIdentifier(task, NULL); @@ -1436,7 +1443,7 @@ int main(int argc, const char * argv[]) { char * errorbuf; if (sandbox_init(SECURITYD_SERVICE_NAME, SANDBOX_NAMED, &errorbuf) != 0) { - os_log(OS_LOG_DEFAULT, "sandbox_init failed %s", errorbuf); + os_log(OS_LOG_DEFAULT, "sandbox_init failed %{public}s", errorbuf); sandbox_free_error(errorbuf); #ifndef DEBUG abort(); diff --git a/securityd/securityd_service/securityd_service/securityd_service.8 b/securityd/securityd_service/securityd_service/securityd_service.8 index 6c0d68db..1094c7d2 100644 --- a/securityd/securityd_service/securityd_service/securityd_service.8 +++ b/securityd/securityd_service/securityd_service/securityd_service.8 @@ -3,7 +3,7 @@ .Os .Sh NAME .Nm securityd_service -.Nd heler process to securityd to unlock keybag +.Nd helper process to securityd to unlock keybag .Sh DESCRIPTION .Nm lock and unlocks the keybag on behalf of diff --git a/securityd/securityd_service/securityd_service/securityd_service_client.h b/securityd/securityd_service/securityd_service/securityd_service_client.h index c0d8667d..293216fc 100644 --- a/securityd/securityd_service/securityd_service/securityd_service_client.h +++ b/securityd/securityd_service/securityd_service/securityd_service_client.h @@ -26,6 +26,7 @@ typedef struct { au_asid_t s_id; uid_t s_uid; audit_token_t procToken; + uint64_t kcv; } service_context_t; int service_client_kb_create(service_context_t *context, const void * secret, int secret_len); diff --git a/securityd/src/SharedMemoryServer.cpp b/securityd/src/SharedMemoryServer.cpp index 3b95482b..df1647ee 100644 --- a/securityd/src/SharedMemoryServer.cpp +++ b/securityd/src/SharedMemoryServer.cpp @@ -38,19 +38,6 @@ already exists at install time. */ -std::string SharedMemoryCommon::SharedMemoryFilePath(const char *segmentName, uid_t uid) { - std::string path; - uid = SharedMemoryCommon::fixUID(uid); - path = SharedMemoryCommon::kMDSMessagesDirectory; // i.e. /private/var/db/mds/messages/ - if (uid != 0) { - path += std::to_string(uid) + "/"; // e.g. /private/var/db/mds/messages/501/ - } - - path += SharedMemoryCommon::kUserPrefix; // e.g. /var/db/mds/messages/se_ - path += segmentName; // e.g. /var/db/mds/messages/501/se_SecurityMessages - return path; -} - static bool makedir(const char *path, mode_t mode) { // Returns true on success. Primarily to centralize logging if (::mkdir(path, mode)==0 || errno==EEXIST) { diff --git a/securityd/src/acl_keychain.cpp b/securityd/src/acl_keychain.cpp index 2520e386..25ca3581 100644 --- a/securityd/src/acl_keychain.cpp +++ b/securityd/src/acl_keychain.cpp @@ -100,6 +100,11 @@ bool KeychainPromptAclSubject::validates(const AclValidationContext &ctx) const bool KeychainPromptAclSubject::validates(const AclValidationContext &context, const TypedList &sample) const { + // Try to grab a common lock. We'll need it in queryUser, but we can't get + // it in validateExplicitly since other callers have it. + SecurityServerEnvironment *env = context.environment(); + StMaybeLock _(env && env->database && env->database->hasCommon() ? &env->database->common() : NULL); + return validateExplicitly(context, ^{ if (SecurityServerEnvironment *env = context.environment()) { Process& process = Server::process(); diff --git a/securityd/src/acls.cpp b/securityd/src/acls.cpp index 958ecb05..223c8cc6 100644 --- a/securityd/src/acls.cpp +++ b/securityd/src/acls.cpp @@ -148,6 +148,9 @@ void SecurityServerAcl::validate(AclAuthorization auth, const Context &context, // void SecurityServerAcl::validatePartition(SecurityServerEnvironment& env, bool prompt) { + // Avert your eyes! + StMaybeLock lock(env.database && env.database->hasCommon() ? &(env.database->common()) : NULL); + // Calling checkAppleSigned() early at boot on a clean system install // will end up trying to create the system keychain and causes a hang. // Avoid this by checking for the presence of the db first. diff --git a/securityd/src/agentquery.cpp b/securityd/src/agentquery.cpp index dbf52186..88107375 100644 --- a/securityd/src/agentquery.cpp +++ b/securityd/src/agentquery.cpp @@ -490,13 +490,13 @@ QueryKeychainUse::QueryKeychainUse(bool needPass, const Database *db) // if passphrase checking requested, save KeychainDatabase reference // (will quietly disable check if db isn't a keychain) - // Always require password, Always require the user's password on keychain approval dialogs - // if (needPass) - mPassphraseCheck = dynamic_cast(db); + // Always require password due to + mPassphraseCheck = dynamic_cast(db); setTerminateOnSleep(true); } +// Callers to this function must hold the common lock Reason QueryKeychainUse::queryUser (const char *database, const char *description, AclAuthorization action) { Reason reason = SecurityAgent::noReason; @@ -537,7 +537,12 @@ Reason QueryKeychainUse::queryUser (const char *database, const char *descriptio hints.erase(retryHint); hints.insert(retryHint); // replace setInput(hints, context); - invoke(); + + { + // Must drop the common lock while showing UI. + StSyncLock syncLock(const_cast(mPassphraseCheck)->common().uiLock(), const_cast(mPassphraseCheck)->common()); + invoke(); + } if (retryCount > kMaximumAuthorizationTries) { @@ -552,11 +557,7 @@ Reason QueryKeychainUse::queryUser (const char *database, const char *descriptio passwordItem->getCssmData(data); - { - // Must hold the 'common' lock to call decode; otherwise there's a data corruption issue - StLock _(const_cast(mPassphraseCheck)->common()); - reason = (const_cast(mPassphraseCheck)->decode(data) ? SecurityAgent::noReason : SecurityAgent::invalidPassphrase); - } + reason = (const_cast(mPassphraseCheck)->decode(data) ? SecurityAgent::noReason : SecurityAgent::invalidPassphrase); } while (reason != SecurityAgent::noReason); diff --git a/securityd/src/auditevents.cpp b/securityd/src/auditevents.cpp index ee7219a4..9cedad36 100644 --- a/securityd/src/auditevents.cpp +++ b/securityd/src/auditevents.cpp @@ -65,7 +65,7 @@ void AuditMonitor::action() Syslog::error("au_sdev_read_aia failed: %d\n", errno); continue; } - secinfo("SS", "%p session notify %d %d %d", this, aia.ai_asid, event, aia.ai_auid); + secinfo("SecServer", "%p session notify %d %d %d", this, aia.ai_asid, event, aia.ai_auid); if (kern_return_t rc = self_client_handleSession(mRelay, mach_task_self(), event, aia.ai_asid)) Syslog::error("self-send failed (mach error %d)", rc); } diff --git a/securityd/src/clientid.cpp b/securityd/src/clientid.cpp index c3da505f..0b80042f 100644 --- a/securityd/src/clientid.cpp +++ b/securityd/src/clientid.cpp @@ -165,9 +165,11 @@ std::string ClientIdentification::partitionIdForProcess(SecStaticCodeRef code) { static CFStringRef const appleReq = CFSTR("anchor apple"); static CFStringRef const masReq = CFSTR("anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9]"); - static CFStringRef const developmentOrDevIDReq = CFSTR("anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13]" - " or " - "anchor apple generic and certificate leaf[subject.CN] = \"Mac Developer:\"* and certificate 1[field.1.2.840.113635.100.6.2.1]"); + static CFStringRef const developmentOrDevIDReq = CFSTR("anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13]" // Developer ID CA and Leaf + " or " + "anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.1] and certificate leaf[field.1.2.840.113635.100.6.1.12]" // WWDR CA and Mac Development Leaf + " or " + "anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.1] and certificate leaf[field.1.2.840.113635.100.6.1.7]"); // WWDR CA and Mac Distribution Leaf static SecRequirementRef apple; static SecRequirementRef mas; static SecRequirementRef developmentOrDevID; diff --git a/securityd/src/connection.cpp b/securityd/src/connection.cpp index 84b0ac8f..f2f1bbcd 100644 --- a/securityd/src/connection.cpp +++ b/securityd/src/connection.cpp @@ -56,7 +56,7 @@ Connection::Connection(Process &proc, Port rPort) // bump the send-rights count on the reply port so we keep the right after replying mClientPort.modRefs(MACH_PORT_RIGHT_SEND, +1); - secinfo("SS", "New client connection %p: %d %d", this, rPort.port(), proc.uid()); + secinfo("SecServer", "New client connection %p: %d %d", this, rPort.port(), proc.uid()); } @@ -66,7 +66,7 @@ Connection::Connection(Process &proc, Port rPort) // Connection::~Connection() { - secinfo("SS", "releasing client connection %p", this); + secinfo("SecServer", "releasing client connection %p", this); assert(!agentWait); } @@ -76,7 +76,7 @@ Connection::~Connection() // void Connection::guestRef(SecGuestRef newGuest, SecCSFlags flags) { - secinfo("SS", "Connection %p switches to guest 0x%x", this, newGuest); + secinfo("SecServer", "Connection %p switches to guest 0x%x", this, newGuest); mGuestRef = newGuest; } @@ -91,7 +91,7 @@ void Connection::terminate() assert(state == idle); mClientPort.modRefs(MACH_PORT_RIGHT_SEND, -1); // discard surplus send right assert(mClientPort.getRefs(MACH_PORT_RIGHT_SEND) == 1); // one left for final reply - secinfo("SS", "Connection %p terminated", this); + secinfo("SecServer", "Connection %p terminated", this); } @@ -107,11 +107,11 @@ void Connection::abort(bool keepReplyPort) mClientPort.destroy(); // dead as a doornail already switch (state) { case idle: - secinfo("SS", "Connection %p aborted", this); + secinfo("SecServer", "Connection %p aborted", this); break; case busy: state = dying; // shoot me soon, please - secinfo("SS", "Connection %p abort deferred (busy)", this); + secinfo("SecServer", "Connection %p abort deferred (busy)", this); break; default: assert(false); // impossible (we hope) @@ -137,7 +137,7 @@ void Connection::beginWork(audit_token_t &auditToken) mOverrideReturn = CSSM_OK; // clear override break; case busy: - secinfo("SS", "Attempt to re-enter connection %p(port %d)", this, mClientPort.port()); + secinfo("SecServer", "Attempt to re-enter connection %p(port %d)", this, mClientPort.port()); CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); //@@@ some state-error code instead? default: assert(false); @@ -169,7 +169,7 @@ void Connection::endWork(CSSM_RETURN &rcode) state = idle; return; case dying: - secinfo("SS", "Connection %p abort resuming", this); + secinfo("SecServer", "Connection %p abort resuming", this); return; default: assert(false); diff --git a/securityd/src/csproxy.cpp b/securityd/src/csproxy.cpp index 7c8a27f5..fb054031 100644 --- a/securityd/src/csproxy.cpp +++ b/securityd/src/csproxy.cpp @@ -66,7 +66,7 @@ void CodeSigningHost::reset() case dynamicHosting: mHostingPort.destroy(); mHostingPort = MACH_PORT_NULL; - secnotice("SS", "%d host unregister", mHostingPort.port()); + secnotice("SecServer", "%d host unregister", mHostingPort.port()); break; case proxyHosting: Server::active().remove(*this); // unhook service handler @@ -74,7 +74,7 @@ void CodeSigningHost::reset() mHostingState = noHosting; mHostingPort = MACH_PORT_NULL; mGuests.erase(mGuests.begin(), mGuests.end()); - secnotice("SS", "%d host unregister", mHostingPort.port()); + secnotice("SecServer", "%d host unregister", mHostingPort.port()); break; } } @@ -147,7 +147,16 @@ CodeSigningHost::Guest *CodeSigningHost::findGuest(Guest *host, const CssmData & // now take the rest of the attrs CFIndex count = CFDictionaryGetCount(attrs); - CFTypeRef keys[count], values[count]; + + CFTypeRef *keys = (CFTypeRef*)malloc(count*sizeof(CFTypeRef)); + CFTypeRef *values = (CFTypeRef*)malloc(count*sizeof(CFTypeRef)); + + if (keys == NULL || values == NULL) { + free(keys); + free(values); + MacOSError::throwMe(errSecMemoryError); + } + CFDictionaryGetKeysAndValues(attrs, keys, values); for (;;) { Guest *match = NULL; // previous match found @@ -155,6 +164,8 @@ CodeSigningHost::Guest *CodeSigningHost::findGuest(Guest *host, const CssmData & if (it->second->isGuestOf(host, strict)) { if (it->second->matches(count, keys, values)) { if (match) { + free(keys); + free(values); MacOSError::throwMe(errSecCSMultipleGuests); // ambiguous } else { match = it->second; @@ -162,10 +173,14 @@ CodeSigningHost::Guest *CodeSigningHost::findGuest(Guest *host, const CssmData & } } } - if (!match) // nothing found + if (!match) { // nothing found + free(keys); + free(values); return host; - else + } + else { host = match; // and repeat + } } } @@ -196,7 +211,7 @@ void CodeSigningHost::registerCodeSigning(mach_port_t hostingPort, SecCSFlags fl case noHosting: mHostingPort = hostingPort; mHostingState = dynamicHosting; - secnotice("SS", "%d host register: %d", mHostingPort.port(), mHostingPort.port()); + secnotice("SecServer", "%d host register: %d", mHostingPort.port(), mHostingPort.port()); break; default: MacOSError::throwMe(errSecCSHostProtocolContradiction); @@ -227,7 +242,7 @@ SecGuestRef CodeSigningHost::createGuest(SecGuestRef hostRef, MachServer::Handler::port(mHostingPort); // put into Handler MachServer::active().add(*this); // start listening mHostingState = proxyHosting; // now proxying for this host - secnotice("SS", "%d host proxy: %d", mHostingPort.port(), mHostingPort.port()); + secnotice("SecServer", "%d host proxy: %d", mHostingPort.port(), mHostingPort.port()); break; case proxyHosting: // already proxying break; @@ -255,7 +270,7 @@ SecGuestRef CodeSigningHost::createGuest(SecGuestRef hostRef, guest->setHash(cdhash, flags & kSecCSGenerateGuestHash); guest->dedicated = (flags & kSecCSDedicatedHost); mGuests[guest->guestRef()] = guest; - secnotice("SS", "%d guest create %d %d status:%d %d %s", mHostingPort.port(), hostRef, guest->guestRef(), guest->status, flags, guest->path.c_str()); + secnotice("SecServer", "%d guest create %d %d status:%d %d %s", mHostingPort.port(), hostRef, guest->guestRef(), guest->status, flags, guest->path.c_str()); return guest->guestRef(); } @@ -273,7 +288,7 @@ void CodeSigningHost::setGuestStatus(SecGuestRef guestRef, uint32_t status, cons if ((~status & guest->status) & (kSecCodeStatusHard | kSecCodeStatusKill)) MacOSError::throwMe(errSecCSHostProtocolStateError); // can't clear guest->status = status; - secnotice("SS", "%d guest change %d %d", mHostingPort.port(), guestRef, status); + secnotice("SecServer", "%d guest change %d %d", mHostingPort.port(), guestRef, status); // replace attributes if requested if (attributes) @@ -305,7 +320,7 @@ void CodeSigningHost::removeGuest(SecGuestRef hostRef, SecGuestRef guestRef) } for (auto &it : matchingGuests) { - secnotice("SS", "%d guest destroy %d", mHostingPort.port(), it); + secnotice("SecServer", "%d guest destroy %d", mHostingPort.port(), it); mGuests.erase(it); } } diff --git a/securityd/src/database.cpp b/securityd/src/database.cpp index 54e50d4b..803bb44f 100644 --- a/securityd/src/database.cpp +++ b/securityd/src/database.cpp @@ -227,3 +227,7 @@ bool Database::validateSecret(const AclSubject *, const AccessCredentials *) return false; } +bool Database::hasCommon() const +{ + return hasParent(); +} diff --git a/securityd/src/database.h b/securityd/src/database.h index 62aa22e8..7e077b4c 100644 --- a/securityd/src/database.h +++ b/securityd/src/database.h @@ -207,6 +207,7 @@ public: static const int maxUnlockTryCount = 3; public: + bool hasCommon() const; DbCommon& common() const { return parent(); } virtual const char *dbName() const = 0; virtual void dbName(const char *name); diff --git a/securityd/src/dbcrypto.cpp b/securityd/src/dbcrypto.cpp index ad615d3b..7aaf8c50 100644 --- a/securityd/src/dbcrypto.cpp +++ b/securityd/src/dbcrypto.cpp @@ -140,8 +140,9 @@ void DatabaseCryptoCore::setup(const DbBlob *blob, const CssmData &passphrase, b mBlobVersion = blob->version(); } memcpy(mSalt, blob->salt, sizeof(mSalt)); - } else + } else { Server::active().random(mSalt); + } mMasterKey = deriveDbMasterKey(passphrase); mHaveMaster = true; } @@ -167,8 +168,9 @@ void DatabaseCryptoCore::setup(const DbBlob *blob, CssmClient::Key master, bool mBlobVersion = blob->version(); } memcpy(mSalt, blob->salt, sizeof(mSalt)); - } else + } else { Server::active().random(mSalt); + } mMasterKey = master; mHaveMaster = true; } diff --git a/securityd/src/kcdatabase.cpp b/securityd/src/kcdatabase.cpp index b80dee1b..99d014ee 100644 --- a/securityd/src/kcdatabase.cpp +++ b/securityd/src/kcdatabase.cpp @@ -192,24 +192,46 @@ unlock_keybag_with_cred(KeychainDatabase &db, const AccessCredentials *cred){ sample.checkProper(); switch (sample.type()) { // interactively prompt the user - no additional data - case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT: { - StSyncLock uisync(db.common().uiLock(), db.common()); - // Once we get the ui lock, check whether another thread has already unlocked keybag - bool locked = false; - service_context_t context = db.common().session().get_current_service_context(); - if ((service_client_kb_is_locked(&context, &locked, NULL) == 0) && locked) { - QueryKeybagPassphrase keybagQuery(db.common().session(), 3); - keybagQuery.inferHints(Server::process()); - if (keybagQuery.query() == SecurityAgent::noReason) { - return true; + case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT: + { + /* + Okay, this is messy. We need to hold the common lock to be certain we're modifying the world + as we intend. But UI ^ common, and QueryKeybagPassphrase::query() has tons of side effects by necessity, + so just confirm that the operation did what we wanted after the fact. + */ + bool query_success = false; + bool unlock_success = false; + bool looped = false; + do { + { + StSyncLock uisync(db.common().uiLock(), db.common()); + // Once we get the ui lock, check whether another thread has already unlocked keybag + bool locked = false; + query_success = false; + service_context_t context = db.common().session().get_current_service_context(); + if ((service_client_kb_is_locked(&context, &locked, NULL) == 0) && locked) { + QueryKeybagPassphrase keybagQuery(db.common().session(), 3); + keybagQuery.inferHints(Server::process()); + if (keybagQuery.query() == SecurityAgent::noReason) { + query_success = true; + } + } else { + // another thread already unlocked the keybag + query_success = true; // NOT unlock_success because we have the wrong lock + } + } // StSyncLock goes out of scope, we have common lock again + bool locked = false; + service_context_t context = db.common().session().get_current_service_context(); + if ((service_client_kb_is_locked(&context, &locked, NULL) == 0) && !locked) { + unlock_success = true; } - } - else { - // another thread already unlocked the keybag - return true; - } - break; + if (looped) { + secnotice("KCdb", "Unlocking the keybag again (threading?)"); + } + looped = true; + } while (query_success && !unlock_success); } + break; // try to use an explicitly given passphrase - Data:passphrase case CSSM_SAMPLE_TYPE_PASSWORD: { if (sample.length() != 2) @@ -617,7 +639,7 @@ void KeychainDatabase::authenticate(CSSM_DB_ACCESS_TYPE mode, RefPointer KeychainDatabase::makeKey(Database &db, const CssmKey &newKey, uint32 moreAttributes, const AclEntryPrototype *owner) { - + StLock lock(common()); if (moreAttributes & CSSM_KEYATTR_PERMANENT) return new KeychainKey(db, newKey, moreAttributes, owner); else @@ -794,7 +816,14 @@ void KeychainDatabase::makeUnlocked(const AccessCredentials *cred, bool unlockKe if (isLocked()) { secnotice("KCdb", "%p(%p) unlocking for makeUnlocked()", this, &common()); assert(mBlob || (mValidData && common().hasMaster())); - establishOldSecrets(cred); + bool asking_again = false; + do { + if (asking_again) { + secnotice("KCdb", "makeUnlocked: establishing old secrets again (threading?)"); + } + establishOldSecrets(cred); + asking_again = true; + } while (!common().hasMaster()); common().setUnlocked(); // mark unlocked if (common().isLoginKeychain()) { CssmKey master = common().masterKey(); @@ -1133,6 +1162,8 @@ bool KeychainDatabase::checkCredentials(const AccessCredentials *creds) { uint32_t KeychainDatabase::interactiveUnlockAttempts = 0; +// This does UI so needs the UI lock. It also interacts with the common, so needs the common lock. But can't have both at once! +// Try to hold the UI lock for the smallest amount of time possible while having the common lock where needed. bool KeychainDatabase::interactiveUnlock() { secinfo("KCdb", "%p attempting interactive unlock", this); @@ -1140,13 +1171,12 @@ bool KeychainDatabase::interactiveUnlock() SecurityAgent::Reason reason = SecurityAgent::noReason; QueryUnlock query(*this); - // take UI interlock and release DbCommon lock (to avoid deadlocks) - StSyncLock uisync(common().uiLock(), common()); - - // now that we have the UI lock, interact unless another thread unlocked us first + if (isLocked()) { query.inferHints(Server::process()); + StSyncLock uisync(common().uiLock(), common()); reason = query(); + uisync.unlock(); if (mSaveSecret && reason == SecurityAgent::noReason) { query.retrievePassword(mSecret); } @@ -1163,7 +1193,9 @@ bool KeychainDatabase::interactiveUnlock() keybagQuery.inferHints(Server::process()); CssmAutoData pass(Allocator::standard(Allocator::sensitive)); CssmAutoData oldPass(Allocator::standard(Allocator::sensitive)); + StSyncLock uisync(common().uiLock(), common()); SecurityAgent::Reason queryReason = keybagQuery.query(oldPass, pass); + uisync.unlock(); if (queryReason == SecurityAgent::noReason) { service_client_kb_change_secret(&context, oldPass.data(), (int)oldPass.length(), pass.data(), (int)pass.length()); } else if (queryReason == SecurityAgent::resettingPassword) { @@ -1201,17 +1233,19 @@ bool KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, Secur // interactively prompt the user case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT: { - secinfo("KCdb", "%p specified interactive passphrase", this); - QueryNewPassphrase query(*this, reason); - StSyncLock uisync(common().uiLock(), common()); - query.inferHints(Server::process()); - CssmAutoData passphrase(Allocator::standard(Allocator::sensitive)); - CssmAutoData oldPassphrase(Allocator::standard(Allocator::sensitive)); - if (query(oldPassphrase, passphrase) == SecurityAgent::noReason) { - common().setup(NULL, passphrase); - change_secret_on_keybag(*this, oldPassphrase.data(), (int)oldPassphrase.length(), passphrase.data(), (int)passphrase.length()); - return true; - } + secinfo("KCdb", "%p specified interactive passphrase", this); + QueryNewPassphrase query(*this, reason); + StSyncLock uisync(common().uiLock(), common()); + query.inferHints(Server::process()); + CssmAutoData passphrase(Allocator::standard(Allocator::sensitive)); + CssmAutoData oldPassphrase(Allocator::standard(Allocator::sensitive)); + SecurityAgent::Reason reason(query(oldPassphrase, passphrase)); + uisync.unlock(); + if (reason == SecurityAgent::noReason) { + common().setup(NULL, passphrase); + change_secret_on_keybag(*this, oldPassphrase.data(), (int)oldPassphrase.length(), passphrase.data(), (int)passphrase.length()); + return true; + } } break; // try to use an explicitly given passphrase @@ -1279,7 +1313,9 @@ bool KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, Secur query.inferHints(Server::process()); CssmAutoData passphrase(Allocator::standard(Allocator::sensitive)); CssmAutoData oldPassphrase(Allocator::standard(Allocator::sensitive)); - if (query(oldPassphrase, passphrase) == SecurityAgent::noReason) { + SecurityAgent::Reason reason(query(oldPassphrase, passphrase)); + uisync.unlock(); + if (reason == SecurityAgent::noReason) { common().setup(NULL, passphrase); change_secret_on_keybag(*this, oldPassphrase.data(), (int)oldPassphrase.length(), passphrase.data(), (int)passphrase.length()); return true; @@ -1678,6 +1714,9 @@ void KeychainDatabase::validateBlob(const DbBlob *blob) // perform basic validation on the blob assert(blob); blob->validate(CSSMERR_APPLEDL_INVALID_DATABASE_BLOB); + if (blob->startCryptoBlob > blob->totalLength) { + CssmError::throwMe(CSSMERR_APPLEDL_INVALID_DATABASE_BLOB); + } switch (blob->version()) { #if defined(COMPAT_OSX_10_0) case DbBlob::version_MacOS_10_0: diff --git a/securityd/src/kckey.cpp b/securityd/src/kckey.cpp index 499926fb..fc35bbc1 100644 --- a/securityd/src/kckey.cpp +++ b/securityd/src/kckey.cpp @@ -42,6 +42,9 @@ KeychainKey::KeychainKey(Database &db, const KeyBlob *blob) // perform basic validation on the incoming blob assert(blob); blob->validate(CSSMERR_APPLEDL_INVALID_KEY_BLOB); + if (blob->startCryptoBlob > blob->totalLength) { + CssmError::throwMe(CSSMERR_APPLEDL_INVALID_KEY_BLOB); + } switch (blob->version()) { #if defined(COMPAT_OSX_10_0) case KeyBlob::version_MacOS_10_0: @@ -206,6 +209,9 @@ void KeychainKey::validate(AclAuthorization auth, const AccessCredentials *cred, db->unlockDb(false); } SecurityServerAcl::validate(auth, cred, relatedDatabase); + + // Need the common lock some more. unlockDb and validate (in validatePartition) also take it, so must be down here. + StMaybeLock lock(relatedDatabase && relatedDatabase->hasCommon() ? &(relatedDatabase->common()) : NULL); database().activity(); // upon successful validation } diff --git a/securityd/src/main.cpp b/securityd/src/main.cpp index 9f66038d..568432f5 100644 --- a/securityd/src/main.cpp +++ b/securityd/src/main.cpp @@ -77,7 +77,7 @@ PCSCMonitor *gPCSC; int main(int argc, char *argv[]) { // clear the umask - we know what we're doing - secnotice("SS", "starting umask was 0%o", ::umask(0)); + secnotice("SecServer", "starting umask was 0%o", ::umask(0)); ::umask(0); // tell the keychain (client) layer to turn off the server interface @@ -100,7 +100,7 @@ int main(int argc, char *argv[]) // check for the Installation-DVD environment and modify some default arguments if found if (access("/etc/rc.cdrom", F_OK) == 0) { // /etc/rc.cdrom exists - secnotice("SS", "starting in installmode"); + secnotice("SecServer", "starting in installmode"); smartCardOptions = "off"; // needs writable directories that aren't } @@ -280,7 +280,7 @@ int main(int argc, char *argv[]) // okay, we're ready to roll - secnotice("SS", "Entering service as %s", (char*)bootstrapName); + secnotice("SecServer", "Entering service as %s", (char*)bootstrapName); Syslog::notice("Entering service"); // go diff --git a/securityd/src/notifications.cpp b/securityd/src/notifications.cpp index 8ef8872b..f4682cc5 100644 --- a/securityd/src/notifications.cpp +++ b/securityd/src/notifications.cpp @@ -204,7 +204,7 @@ bool Listener::testPredicate(const std::function SharedMemoryListener::SharedMemoryListener(const char* segmentName, SegmentOffsetType segmentSize, uid_t uid, gid_t gid) : Listener (kNotificationDomainAll, kNotificationAllEvents), SharedMemoryServer (segmentName, segmentSize, uid, gid), - mActive (false) + mActive (false), mMutex() { } @@ -367,6 +367,7 @@ void SharedMemoryListener::notifyMe(Notification* notification) WriteMessage (notification->domain, notification->event, data, int_cast(length)); + StLock lock(mMutex); if (!mActive) { Server::active().setTimer (this, Time::Interval(kServerWait)); @@ -376,9 +377,10 @@ void SharedMemoryListener::notifyMe(Notification* notification) void SharedMemoryListener::action () { + StLock lock(mMutex); + notify_post (mSegmentName.c_str ()); secinfo("notify", "Posted notification to clients."); secdebug("MDSPRIVACY","[%03d] Posted notification to clients", mUID); - notify_post (mSegmentName.c_str ()); mActive = false; } diff --git a/securityd/src/notifications.h b/securityd/src/notifications.h index fc362d75..4fd7f303 100644 --- a/securityd/src/notifications.h +++ b/securityd/src/notifications.h @@ -143,6 +143,8 @@ protected: bool mActive; + Mutex mMutex; + public: SharedMemoryListener (const char* serverName, u_int32_t serverSize, uid_t uid = 0, gid_t gid = 0); virtual ~SharedMemoryListener (); diff --git a/securityd/src/process.cpp b/securityd/src/process.cpp index 6439308e..1206b157 100644 --- a/securityd/src/process.cpp +++ b/securityd/src/process.cpp @@ -49,7 +49,7 @@ Process::Process(TaskPort taskPort, const ClientSetupInfo *info, const CommonCri // let's take a look at our wannabe client... if (mTaskPort.pid() != mPid) { - secnotice("SS", "Task/pid setup mismatch pid=%d task=%d(%d)", + secnotice("SecServer", "Task/pid setup mismatch pid=%d task=%d(%d)", mPid, mTaskPort.port(), mTaskPort.pid()); CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED); // you lied! } @@ -64,7 +64,7 @@ Process::Process(TaskPort taskPort, const ClientSetupInfo *info, const CommonCri || ServerChild::find(this->pid())) // securityd's child; do not mark this txn dirty VProc::Transaction::deactivate(); - secinfo("SS", "%p client new: pid:%d session:%d %s taskPort:%d uid:%d gid:%d", this, this->pid(), this->session().sessionId(), + secinfo("SecServer", "%p client new: pid:%d session:%d %s taskPort:%d uid:%d gid:%d", this, this->pid(), this->session().sessionId(), (char *)codePath(this->processCode()).c_str(), taskPort.port(), mUid, mGid); } @@ -79,7 +79,7 @@ void Process::reset(TaskPort taskPort, const ClientSetupInfo *info, const Common { StLock _(*this); if (taskPort != mTaskPort) { - secnotice("SS", "Process %p(%d) reset mismatch (tp %d-%d)", + secnotice("SecServer", "Process %p(%d) reset mismatch (tp %d-%d)", this, pid(), taskPort.port(), mTaskPort.port()); //@@@ CssmError::throwMe(CSSM_ERRCODE_VERIFICATION_FAILURE); // liar } @@ -88,9 +88,9 @@ void Process::reset(TaskPort taskPort, const ClientSetupInfo *info, const Common ClientIdentification::setup(this->pid()); // re-constructs processCode() if (CFEqual(oldCode, processCode())) { - secnotice("SS", "%p Client reset amnesia", this); + secnotice("SecServer", "%p Client reset amnesia", this); } else { - secnotice("SS", "%p Client reset full", this); + secnotice("SecServer", "%p Client reset full", this); CodeSigningHost::reset(); } } @@ -124,7 +124,7 @@ void Process::setup(const ClientSetupInfo *info) // Process::~Process() { - secinfo("SS", "%p client release: %d", this, this->pid()); + secinfo("SecServer", "%p client release: %d", this, this->pid()); // release our name for the process's task port if (mTaskPort) @@ -180,7 +180,7 @@ void Process::changeSession(Session::SessionId sessionId) { // re-parent parent(Session::find(sessionId, true)); - secnotice("SS", "%p client change session to %d", this, this->session().sessionId()); + secnotice("SecServer", "%p client change session to %d", this, this->session().sessionId()); } diff --git a/securityd/src/process.h b/securityd/src/process.h index 46d38c15..ce24dc9f 100644 --- a/securityd/src/process.h +++ b/securityd/src/process.h @@ -96,8 +96,9 @@ public: // aclSequence is taken to serialize ACL validations to pick up mutual changes Mutex aclSequence; - - IFDUMP(void dumpNode()); + + // Dumping is buggy and only hurts debugging. It's dead Jim. + //IFDUMP(void dumpNode()); private: void setup(const ClientSetupInfo *info); diff --git a/securityd/src/server.cpp b/securityd/src/server.cpp index 40772eed..6ebc34c9 100644 --- a/securityd/src/server.cpp +++ b/securityd/src/server.cpp @@ -100,8 +100,10 @@ Connection &Server::connection(bool tolerant) void Server::requestComplete(CSSM_RETURN &rcode) { + Server &server = active(); + StLock lock(server); // note: there may not be an active connection if connection setup failed - if (RefPointer &conn = active().mCurrentConnection()) { + if (RefPointer &conn = server.mCurrentConnection()) { conn->endWork(rcode); conn = NULL; } @@ -271,7 +273,7 @@ void Server::notifyDeadName(Port port) // is it a connection? PortMap::iterator conIt = mConnections.find(port); if (conIt != mConnections.end()) { - secinfo("SS", "%p dead connection %d", this, port.port()); + secinfo("SecServer", "%p dead connection %d", this, port.port()); RefPointer con = conIt->second; mConnections.erase(conIt); serverLock.unlock(); @@ -282,7 +284,7 @@ void Server::notifyDeadName(Port port) // is it a process? PortMap::iterator procIt = mProcesses.find(port); if (procIt != mProcesses.end()) { - secinfo("SS", "%p dead process %d", this, port.port()); + secinfo("SecServer", "%p dead process %d", this, port.port()); RefPointer proc = procIt->second; mPids.erase(proc->pid()); mProcesses.erase(procIt); @@ -305,7 +307,7 @@ void Server::notifyDeadName(Port port) // void Server::notifyNoSenders(Port port, mach_port_mscount_t) { - secinfo("SS", "%p dead session %d", this, port.port()); + secinfo("SecServer", "%p dead session %d", this, port.port()); } @@ -318,7 +320,7 @@ kern_return_t self_server_handleSignal(mach_port_t sport, mach_port_t taskPort, int sig) { try { - secnotice("SS", "signal handled %d", sig); + secnotice("SecServer", "signal handled %d", sig); if (taskPort != mach_task_self()) { Syslog::error("handleSignal: received from someone other than myself"); return KERN_SUCCESS; @@ -328,7 +330,7 @@ kern_return_t self_server_handleSignal(mach_port_t sport, ServerChild::checkChildren(); break; case SIGINT: - secnotice("SS", "shutdown due to SIGINT"); + secnotice("SecServer", "shutdown due to SIGINT"); Syslog::notice("securityd terminated due to SIGINT"); _exit(0); case SIGTERM: @@ -355,7 +357,7 @@ kern_return_t self_server_handleSignal(mach_port_t sport, assert(false); } } catch(...) { - secnotice("SS", "exception handling a signal (ignored)"); + secnotice("SecServer", "exception handling a signal (ignored)"); } mach_port_deallocate(mach_task_self(), taskPort); return KERN_SUCCESS; @@ -368,12 +370,13 @@ kern_return_t self_server_handleSession(mach_port_t sport, try { if (taskPort != mach_task_self()) { Syslog::error("handleSession: received from someone other than myself"); + mach_port_deallocate(mach_task_self(), taskPort); return KERN_SUCCESS; } if (event == AUE_SESSION_END) Session::destroy(int_cast(ident)); } catch(...) { - secnotice("SS", "exception handling a signal (ignored)"); + secnotice("SecServer", "exception handling a signal (ignored)"); } mach_port_deallocate(mach_task_self(), taskPort); return KERN_SUCCESS; @@ -385,7 +388,7 @@ kern_return_t self_server_handleSession(mach_port_t sport, // void Server::SleepWatcher::systemWillSleep() { - secnotice("SS", "%p will sleep", this); + secnotice("SecServer", "%p will sleep", this); Session::processSystemSleep(); for (set::const_iterator it = mPowerClients.begin(); it != mPowerClients.end(); it++) (*it)->systemWillSleep(); @@ -393,14 +396,14 @@ void Server::SleepWatcher::systemWillSleep() void Server::SleepWatcher::systemIsWaking() { - secnotice("SS", "%p is waking", this); + secnotice("SecServer", "%p is waking", this); for (set::const_iterator it = mPowerClients.begin(); it != mPowerClients.end(); it++) (*it)->systemIsWaking(); } void Server::SleepWatcher::systemWillPowerOn() { - secnotice("SS", "%p will power on", this); + secnotice("SecServer", "%p will power on", this); Server::active().longTermActivity(); for (set::const_iterator it = mPowerClients.begin(); it != mPowerClients.end(); it++) (*it)->systemWillPowerOn(); @@ -449,13 +452,13 @@ void Server::beginShutdown() { StLock _(*this); if (!mWaitForClients) { - secnotice("SS", "%p shutting down now", this); + secnotice("SecServer", "%p shutting down now", this); _exit(0); } else { if (!mShuttingDown) { mShuttingDown = true; Session::invalidateAuthHosts(); - secnotice("SS", "%p beginning shutdown", this); + secnotice("SecServer", "%p beginning shutdown", this); if (verbosity() >= 2) { reportFile = fopen("/var/log/securityd-shutdown.log", "w"); shutdownSnitch(); @@ -473,11 +476,10 @@ void Server::beginShutdown() // void Server::eventDone() { + StLock lock(*this); if (this->shuttingDown()) { - StLock lazy(*this, false); // lazy lock acquisition if (verbosity() >= 2) { - lazy.lock(); - secnotice("SS", "shutting down with %ld processes and %ld transactions", mProcesses.size(), VProc::Transaction::debugCount()); + secnotice("SecServer", "shutting down with %ld processes and %ld transactions", mProcesses.size(), VProc::Transaction::debugCount()); shutdownSnitch(); } IFDUMPING("shutdown", NodeCore::dumpAll()); @@ -516,14 +518,14 @@ void Server::loadCssm(bool mdsIsInstalled) VProc::Transaction xact; if (!mCssm->isActive()) { if (!mdsIsInstalled) { // non-system securityd instance should not reinitialize MDS - secnotice("SS", "Installing MDS"); + secnotice("SecServer", "Installing MDS"); IFDEBUG(if (geteuid() == 0)) MDSClient::mds().install(); } - secnotice("SS", "CSSM initializing"); + secnotice("SecServer", "CSSM initializing"); mCssm->init(); mCSP->attach(); - secnotice("SS", "CSSM ready with CSP %s", mCSP->guid().toString().c_str()); + secnotice("SecServer", "CSSM ready with CSP %s", mCSP->guid().toString().c_str()); } } } diff --git a/securityd/src/session.cpp b/securityd/src/session.cpp index 8ec65653..75990e12 100644 --- a/securityd/src/session.cpp +++ b/securityd/src/session.cpp @@ -75,7 +75,7 @@ Session::Session(const AuditInfo &audit, Server &server) mSessions[audit.sessionId()] = this; // log it - secnotice("SS", "%p Session %d created, uid:%d sessionId:%d", this, this->sessionId(), mAudit.uid(), mAudit.sessionId()); + secnotice("SecServer", "%p Session %d created, uid:%d sessionId:%d", this, this->sessionId(), mAudit.uid(), mAudit.sessionId()); Syslog::notice("Session %d created", this->sessionId()); } @@ -85,7 +85,7 @@ Session::Session(const AuditInfo &audit, Server &server) // Session::~Session() { - secnotice("SS", "%p Session %d destroyed", this, this->sessionId()); + secnotice("SecServer", "%p Session %d destroyed", this, this->sessionId()); Syslog::notice("Session %d destroyed", this->sessionId()); } @@ -150,7 +150,7 @@ void Session::destroy(SessionId id) void Session::kill() { StLock _(*this); // do we need to take this so early? - secnotice("SS", "%p killing session %d", this, this->sessionId()); + secnotice("SecServer", "%p killing session %d", this, this->sessionId()); invalidateSessionAuthHosts(); // base kill processing @@ -217,7 +217,7 @@ void Session::resetKeyStorePassphrase(const CssmData &passphrase) service_context_t Session::get_current_service_context() { - service_context_t context = { sessionId(), originatorUid(), *Server::connection().auditToken() }; + service_context_t context = { sessionId(), originatorUid(), *Server::connection().auditToken(), 0 }; return context; } diff --git a/securityd/src/structure.cpp b/securityd/src/structure.cpp index ec86e07b..3c5dc50f 100644 --- a/securityd/src/structure.cpp +++ b/securityd/src/structure.cpp @@ -62,8 +62,6 @@ void NodeCore::referent(NodeCore &r) void NodeCore::clearReferent() { StLock _(*this); - if (mReferent) - assert(!mReferent->hasReference(*this)); mReferent = NULL; } @@ -78,21 +76,9 @@ void NodeCore::addReference(NodeCore &p) void NodeCore::removeReference(NodeCore &p) { StLock _(*this); - assert(hasReference(p)); mReferences.erase(&p); } -#if !defined(NDEBUG) - -bool NodeCore::hasReference(NodeCore &p) -{ - assert(p.refCountForDebuggingOnly() > 0); - return mReferences.find(&p) != mReferences.end(); -} - -#endif //NDEBUG - - // // ClearReferences clears the reference set but does not propagate // anything; it is NOT recursive. @@ -100,8 +86,7 @@ bool NodeCore::hasReference(NodeCore &p) void NodeCore::clearReferences() { StLock _(*this); - secinfo("ssnode", "%p clearing all %d references", - this, int(mReferences.size())); + secinfo("ssnode", "%p clearing all %d references", this, int(mReferences.size())); mReferences.erase(mReferences.begin(), mReferences.end()); } @@ -125,7 +110,6 @@ void NodeCore::kill() void NodeCore::kill(NodeCore &ref) { StLock _(*this); - assert(hasReference(ref)); ref.kill(); removeReference(ref); } diff --git a/securityd/src/structure.h b/securityd/src/structure.h index d4f1c53f..a3e623f6 100644 --- a/securityd/src/structure.h +++ b/securityd/src/structure.h @@ -107,8 +107,6 @@ private: typedef set > ReferenceSet; ReferenceSet mReferences; - IFDEBUG(bool hasReference(NodeCore &p)); - #if defined(DEBUGDUMP) public: // dump support NodeCore(); // dump-only constructor (registers node) diff --git a/securityd/src/transition.cpp b/securityd/src/transition.cpp index c3dffa69..112926bf 100644 --- a/securityd/src/transition.cpp +++ b/securityd/src/transition.cpp @@ -63,10 +63,10 @@ #define BEGIN_IPCN *rcode = CSSM_OK; try { #define BEGIN_IPC(name) BEGIN_IPCN RefPointer connRef(&Server::connection(replyPort, auditToken)); \ Connection &connection __attribute__((unused)) = *connRef; \ - secinfo("SS", "request entry " #name " (pid:%d ession:%d)", connection.process().pid(), connection.session().sessionId()); + secinfo("SecServer", "request entry " #name " (pid:%d ession:%d)", connection.process().pid(), connection.session().sessionId()); #define END_IPC(base) END_IPCN(base) Server::requestComplete(*rcode); return KERN_SUCCESS; -#define END_IPCN(base) secinfo("SS", "request return: %d", *(rcode)); \ +#define END_IPCN(base) secinfo("SecServer", "request return: %d", *(rcode)); \ } \ catch (const CommonError &err) { *rcode = CssmError::cssmError(err, CSSM_ ## base ## _BASE_ERROR); } \ catch (const std::bad_alloc &) { *rcode = CssmError::merge(CSSM_ERRCODE_MEMORY_ERROR, CSSM_ ## base ## _BASE_ERROR); } \ @@ -229,7 +229,7 @@ Database *pickDb(Database *db1, Database *db2) kern_return_t ucsp_server_setup(UCSP_ARGS, mach_port_t taskPort, ClientSetupInfo info, const char *identity) { BEGIN_IPCN - secinfo("SS", "request entry: setup"); + secinfo("SecServer", "request entry: setup"); Server::active().setupConnection(Server::connectNewProcess, replyPort, taskPort, auditToken, &info); END_IPCN(CSSM) @@ -241,7 +241,7 @@ kern_return_t ucsp_server_setup(UCSP_ARGS, mach_port_t taskPort, ClientSetupInfo kern_return_t ucsp_server_setupThread(UCSP_ARGS, mach_port_t taskPort) { - secinfo("SS", "request entry: setupThread"); + secinfo("SecServer", "request entry: setupThread"); BEGIN_IPCN Server::active().setupConnection(Server::connectNewThread, replyPort, taskPort, auditToken); END_IPCN(CSSM) @@ -254,7 +254,7 @@ kern_return_t ucsp_server_setupThread(UCSP_ARGS, mach_port_t taskPort) kern_return_t ucsp_server_teardown(UCSP_ARGS) { BEGIN_IPCN - secinfo("SS", "request entry: teardown"); + secinfo("SecServer", "request entry: teardown"); Server::active().endConnection(replyPort); END_IPCN(CSSM) return KERN_SUCCESS; @@ -263,7 +263,7 @@ kern_return_t ucsp_server_teardown(UCSP_ARGS) kern_return_t ucsp_server_verifyPrivileged(UCSP_ARGS) { BEGIN_IPCN - secinfo("SS", "request entry: verifyPrivileged"); + secinfo("SecServer", "request entry: verifyPrivileged"); // doing nothing (we just want securityd's audit credentials returned) END_IPCN(CSSM) return KERN_SUCCESS; @@ -273,7 +273,7 @@ kern_return_t ucsp_server_verifyPrivileged2(UCSP_ARGS, mach_port_t *originPort) { BEGIN_IPCN - secinfo("SS", "request entry: verifyPrivileged2"); + secinfo("SecServer", "request entry: verifyPrivileged2"); // send the port back to the sender to check for a MitM (6986198) *originPort = servicePort; END_IPCN(CSSM) diff --git a/sslViewer/ecc-secp256r1-client.pfx b/sslViewer/ecc-secp256r1-client.pfx deleted file mode 100644 index ec796e987f65ca19a8d0fe58b01518934393f6a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1036 zcmXqLV&Pz7WHxAGKE%eU)#lOmotKfFaX}OFW|k)A^+4g(294X1Wg1tqG%hn}Tx`&| zfQ=iffrpEcX+f4jhJg$l7fc9fCLaq&#)=zCpDrxh%*4dOz~b?X-GFIAZb)grrJ}4u zmq%@ykoyjYkgF-r|17cCIiL9{hl$b$wpGms)IH3L<&Ewfj;gY}^vDQYOjB4X7oEuo|tsj+8M_maxn9CzoGDli%}z!kBxEod-k zU}9uI7Gp$lFB{0c{qmjDw#>OI0dntx29_qK8QJkSmaw}2l(L?-W&I)JTfxdojIXV# zOO9JA2c-Wlo_#POZ{xqy{oK2f&VP!YTAKOp?S?h^?rYAMv^`vR_LiB-*JM2}hI`Hx zTyJkpiRn=>deHVIu21T`S~5$Fu}IbdZjM!F#s7)!4PT-YapFbH4gLO~&6Q1Etd5cY zpPk<#=5<^7rB?T8|Btg5vXw=sKYg~yt@C8@oY;wdT)po$q?xLodLpvaxzgQ#J!f5F z-@!xOnI54Z%Iu7`dB5ul{_b;=@BE_nEtCIE4y-O`?wRnI{Yv}U@F_=EEn*UX<7;Vq zS-Eems{3T#$#%>BE(}Opntf_l{e1P$YZiU{x*-4UT5GPe8}IJ1Pdv2zqhn(7|D&=| zg%uMX{jA}Bta`Um=Cf5QOH)?Oj}2XF2?}by9&zWIBoq3)yC44$s@eHH;J~*?*-yLW z3f?4JtaRzEkjc;!O!#cx#@#Lz?sfgnSM5b=-D=$Xk|b@dpH?nkd+o$qvCRTMIaN5h zOQM>^XSQ5&YSCtl-t}JFPiA%X)v_5KyB8?Q{G5F7bnExvlB~@_of>!2SH*i5U&{-; z7*g0^9`L~6{O%-1#;zlMA4S={Y}BXhZC~Q-^!}Y?>XK*7U%F&U98E#%&HuGodT$TMFt`fm^LU;e>Q=7it%=#j? zU21#uroP=5`Fx)(Y&yyEEbfJtH``7f(S)>zi!+y>{CzlzccVyI^nv|%e>nN^Zd{(l z!cn3&qg7a8-dP4XFt9aHG~i@o)#hVnl450G5s^B%fBF^Qt~-wl-n=++-zhI?jf*CW d$iGhy8KyNju2STk%sPSjSZwr%wLG8%4*(T}y(a(w diff --git a/sslViewer/sslAppUtils.h b/sslViewer/sslAppUtils.h index 0bb8a85b..6e21e157 100644 --- a/sslViewer/sslAppUtils.h +++ b/sslViewer/sslAppUtils.h @@ -16,10 +16,6 @@ extern "C" { #endif -#if ! SEC_OS_OSX_INCLUDES -typedef struct OpaqueSecKeychainRef *SecKeychainRef; -#endif - /* disable some Panther-only features */ #define JAGUAR_BUILD 0 @@ -76,7 +72,7 @@ OSStatus sslAddTrustedRoots( SecKeychainRef keychain, bool *foundOne); -void sslOutputDot(); +void sslOutputDot(void); /* * Lists of SSLCipherSuites used in sslSetCipherRestrictions. diff --git a/supd/Tests/SFAnalyticsTests.m b/supd/Tests/SFAnalyticsTests.m index 7ffa7b04..d0f16d12 100644 --- a/supd/Tests/SFAnalyticsTests.m +++ b/supd/Tests/SFAnalyticsTests.m @@ -22,8 +22,10 @@ */ #import -#import "SFAnalytics.h" +#import #import "SFAnalyticsDefines.h" +#import "SFAnalyticsSQLiteStore.h" +#import "SFSQLite.h" #import #import #import @@ -243,6 +245,22 @@ static NSString* product = NULL; [self assertNoEventsAnywhere]; } +- (void)testDontCrashWithEmptyDBPath +{ + NSString* schema = @"CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT,data BLOB);"; + NSString* path = [NSString stringWithFormat:@"%@/empty", _path]; + + XCTAssertNil([SFAnalyticsSQLiteStore storeWithPath:nil schema:schema]); + XCTAssertNil([SFAnalyticsSQLiteStore storeWithPath:@"" schema:schema]); + XCTAssertNil([SFAnalyticsSQLiteStore storeWithPath:path schema:nil]); + XCTAssertNil([SFAnalyticsSQLiteStore storeWithPath:path schema:@""]); + + XCTAssertNil([[SFSQLite alloc] initWithPath:nil schema:schema]); + XCTAssertNil([[SFSQLite alloc] initWithPath:@"" schema:schema]); + XCTAssertNil([[SFSQLite alloc] initWithPath:path schema:nil]); + XCTAssertNil([[SFSQLite alloc] initWithPath:path schema:@""]); +} + - (void)testAddingEventsWithNilName { [_analytics logSuccessForEventNamed:nil]; @@ -626,7 +644,7 @@ static NSString* product = NULL; } - [self checkSamples:@[@(0.3f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.01f * NSEC_PER_SEC)]; + [self checkSamples:@[@(0.3f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.05f * NSEC_PER_SEC)]; } - (void)testTrackerMultipleBlocks @@ -671,8 +689,6 @@ static NSString* product = NULL; [self checkSamples:@[@(0.2f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.1f * NSEC_PER_SEC)]; } - - - (void)testTrackerCancel { NSString* trackerName = @"UnitTestTrackerCancel"; diff --git a/supd/Tests/SupdTests.m b/supd/Tests/SupdTests.m index e4a7f79d..0217542b 100644 --- a/supd/Tests/SupdTests.m +++ b/supd/Tests/SupdTests.m @@ -24,7 +24,7 @@ #import #import #import "supd.h" -#import "SFAnalytics.h" +#import #import "SFAnalyticsDefines.h" #import @@ -33,7 +33,6 @@ static NSInteger _testnum; static NSString* build = NULL; static NSString* product = NULL; static NSInteger _reporterWrites; -static NSInteger _reporterCleanups; // MARK: Stub FakeCKKSAnalytics @@ -122,15 +121,29 @@ static NSInteger _reporterCleanups; return nil; } +- (SFAnalyticsTopic *)TrustTopic { + for (SFAnalyticsTopic *topic in _supd.analyticsTopics) { + if ([topic.internalTopicName isEqualToString:SFAnaltyicsTopicTrust]) { + return topic; + } + } + return nil; +} + - (void)inspectDataBlobStructure:(NSDictionary*)data +{ + [self inspectDataBlobStructure:data forTopic:[[self keySyncTopic] splunkTopicName]]; +} + +- (void)inspectDataBlobStructure:(NSDictionary*)data forTopic:(NSString*)topic { if (!data || ![data isKindOfClass:[NSDictionary class]]) { XCTFail(@"data is an NSDictionary"); } XCTAssert(_supd.analyticsTopics, @"supd has nonnull topics list"); - SFAnalyticsTopic *keySyncTopic = [self keySyncTopic]; - XCTAssert([keySyncTopic splunkTopicName], @"supd has a nonnull topic name"); + XCTAssert([[self keySyncTopic] splunkTopicName], @"keysync topic has a splunk name"); + XCTAssert([[self TrustTopic] splunkTopicName], @"trust topic has a splunk name"); XCTAssertEqual([data count], 2ul, @"dictionary event and posttime objects"); XCTAssertTrue(data[@"events"] && [data[@"events"] isKindOfClass:[NSArray class]], @"data blob contains an NSArray 'events'"); XCTAssertTrue(data[@"postTime"] && [data[@"postTime"] isKindOfClass:[NSNumber class]], @"data blob contains an NSNumber 'postTime"); @@ -139,13 +152,14 @@ static NSInteger _reporterCleanups; for (NSDictionary* event in data[@"events"]) { if ([event isKindOfClass:[NSDictionary class]]) { + NSLog(@"build: \"%@\", eventbuild: \"%@\"", build, event[@"build"]); XCTAssertTrue([event[@"build"] isEqual:build], @"event contains correct build string"); XCTAssertTrue([event[@"product"] isEqual:product], @"event contains correct product string"); XCTAssertTrue([event[@"eventTime"] isKindOfClass:[NSNumber class]], @"event contains an NSNumber 'eventTime"); NSDate* eventTime = [NSDate dateWithTimeIntervalSince1970:[event[@"eventTime"] doubleValue]]; XCTAssertTrue([[NSDate date] timeIntervalSinceDate:eventTime] < 3, @"eventTime is sane"); XCTAssertTrue([event[@"eventType"] isKindOfClass:[NSString class]], @"all events have a type"); - XCTAssertTrue([event[@"topic"] isEqual:[keySyncTopic splunkTopicName]], @"all events have a topic name"); + XCTAssertTrue([event[@"topic"] isEqual:topic], @"all events have a topic name"); } else { XCTFail(@"event %@ is an NSDictionary", event); } @@ -176,10 +190,9 @@ static NSInteger _reporterCleanups; return encountered; } -- (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft forcedFail:(BOOL)forcedFail +- (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft accuracy:(int)accuracy summaries:(int)summ { - int hardfound = 0, softfound = 0; - NSUInteger summfound = 0; + int hardfound = 0, softfound = 0, summfound = 0; for (NSDictionary* event in data[@"events"]) { if ([event[SFAnalyticsEventType] hasSuffix:@"HealthSummary"]) { ++summfound; @@ -191,17 +204,21 @@ static NSInteger _reporterCleanups; } XCTAssertLessThanOrEqual(((NSArray*)data[@"events"]).count, 1000ul, @"Total event count fits in alloted data"); - if (!forcedFail) { - XCTAssertEqual(summfound, [[[self keySyncTopic] topicClients] count]); - } - // Add fuzziness, we're not testing exact implementation details - XCTAssertEqualWithAccuracy(hardfound, hard, 10); - XCTAssertEqualWithAccuracy(softfound, soft, 10); + XCTAssertEqual(summfound, summ); + + // Add customizable fuzziness + XCTAssertEqualWithAccuracy(hardfound, hard, accuracy); + XCTAssertEqualWithAccuracy(softfound, soft, accuracy); } - (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft { - [self checkTotalEventCount:data hard:hard soft:soft forcedFail:NO]; + [self checkTotalEventCount:data hard:hard soft:soft accuracy:10 summaries:(int)[[[self keySyncTopic] topicClients] count]]; +} + +- (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft accuracy:(int)accuracy +{ + [self checkTotalEventCount:data hard:hard soft:soft accuracy:accuracy summaries:(int)[[[self keySyncTopic] topicClients] count]]; } // This is a dumb hack, but inlining stringWithFormat causes the compiler to growl for unknown reasons @@ -257,10 +274,15 @@ static NSInteger _reporterCleanups; } - (NSDictionary*)getJSONDataFromSupd +{ + return [self getJSONDataFromSupdWithTopic:SFAnalyticsTopicKeySync]; +} + +- (NSDictionary*)getJSONDataFromSupdWithTopic:(NSString*)topic { dispatch_semaphore_t sema = dispatch_semaphore_create(0); __block NSDictionary* data; - [_supd getLoggingJSON:YES topic:SFAnalyticsTopicKeySync reply:^(NSData *json, NSError *error) { + [_supd getLoggingJSON:YES topic:topic reply:^(NSData *json, NSError *error) { XCTAssertNil(error); XCTAssertNotNil(json); if (!error) { @@ -314,6 +336,14 @@ static NSInteger _reporterCleanups; OCMStub([mockTopic databasePathForPCS]).andReturn(pcsPath); OCMStub([mockTopic databasePathForTLS]).andReturn(tlsPath); + // These are not used for testing, but real data can pollute tests so point to empty DBs + NSString *localpath = [_path stringByAppendingFormat:@"/local_empty_%ld.db", _testnum]; + NSString *trustPath = [_path stringByAppendingFormat:@"/trust_empty_%ld.db", _testnum]; + NSString *trustdhealthPath = [_path stringByAppendingFormat:@"/trustdhealth_empty_%ld.db", _testnum]; + OCMStub([mockTopic databasePathForLocal]).andReturn(localpath); + OCMStub([mockTopic databasePathForTrust]).andReturn(trustPath); + OCMStub([mockTopic databasePathForTrustdHealth]).andReturn(trustdhealthPath); + _reporterWrites = 0; mockReporter = OCMClassMock([SFAnalyticsReporter class]); OCMStub([mockReporter saveReport:[OCMArg isNotNil] fileName:[OCMArg isNotNil]]).andDo(^(NSInvocation *invocation) { @@ -326,16 +356,19 @@ static NSInteger _reporterCleanups; _sosAnalytics = [FakeSOSAnalytics new]; _pcsAnalytics = [FakePCSAnalytics new]; _tlsAnalytics = [FakeTLSAnalytics new]; - NSLog(@"ckks sqlite3 %@", [FakeCKKSAnalytics databasePath]); - NSLog(@"sos sqlite3 %@", [FakeSOSAnalytics databasePath]); - NSLog(@"pcs sqlite3 %@", [FakePCSAnalytics databasePath]); - NSLog(@"tls sqlite3 %@", [FakeTLSAnalytics databasePath]); + + // These are only useful for debugging +// NSLog(@"ckks sqlite3 %@", [FakeCKKSAnalytics databasePath]); +// NSLog(@"sos sqlite3 %@", [FakeSOSAnalytics databasePath]); +// NSLog(@"pcs sqlite3 %@", [FakePCSAnalytics databasePath]); +// NSLog(@"tls sqlite3 %@", [FakeTLSAnalytics databasePath]); // Forcibly override analytics flags and enable them by default deviceAnalyticsOverride = YES; deviceAnalyticsEnabled = YES; iCloudAnalyticsOverride = YES; iCloudAnalyticsEnabled = YES; + runningTests = YES; } - (void)tearDown @@ -372,7 +405,7 @@ static NSInteger _reporterCleanups; XCTAssertFalse([keytopic haveEligibleClients], @"Both analytics disabled -> no keysync clients"); deviceAnalyticsEnabled = YES; - XCTAssertFalse([keytopic haveEligibleClients], @"Only device analytics enabled -> no keysync clients"); + XCTAssertTrue([keytopic haveEligibleClients], @"Only device analytics enabled -> we have keysync clients (localkeychain for now)"); } - (void)testHaveEligibleClientsTrust @@ -416,9 +449,10 @@ static NSInteger _reporterCleanups; XCTAssertEqual([self failures:data eventType:@"unittestevent" attributes:utAttrs class:SFAnalyticsEventClassHardFailure], 1); XCTAssertEqual([self failures:data eventType:@"unittestevent" attributes:utAttrs class:SFAnalyticsEventClassSoftFailure], 1); - [self checkTotalEventCount:data hard:2 soft:2]; + [self checkTotalEventCount:data hard:2 soft:2 accuracy:0]; } else { - [self checkTotalEventCount:data hard:0 soft:0 forcedFail:YES]; + // localkeychain requires device analytics only so we still get it + [self checkTotalEventCount:data hard:0 soft:0 accuracy:0 summaries:1]; } } @@ -441,13 +475,13 @@ static NSInteger _reporterCleanups; [_tlsAnalytics logHardFailureForEventNamed:@"tlsunittestevent" withAttributes:tlsAttrs]; [_tlsAnalytics logSoftFailureForEventNamed:@"tlsunittestevent" withAttributes:tlsAttrs]; - NSDictionary* data = [self getJSONDataFromSupd]; - [self inspectDataBlobStructure:data]; + NSDictionary* data = [self getJSONDataFromSupdWithTopic:SFAnaltyicsTopicTrust]; + [self inspectDataBlobStructure:data forTopic:[[self TrustTopic] splunkTopicName]]; if (analyticsEnabled) { - [self checkTotalEventCount:data hard:1 soft:1]; + [self checkTotalEventCount:data hard:1 soft:1 accuracy:0 summaries:(int)[[[self TrustTopic] topicClients] count]]; } else { - [self checkTotalEventCount:data hard:0 soft:0 forcedFail:YES]; + [self checkTotalEventCount:data hard:0 soft:0 accuracy:0 summaries:0]; } } @@ -530,7 +564,7 @@ static NSInteger _reporterCleanups; NSDictionary* data = [self getJSONDataFromSupd]; [self inspectDataBlobStructure:data]; - [self checkTotalEventCount:data hard:testAmount + 1 soft:testAmount + 1]; + [self checkTotalEventCount:data hard:testAmount + 1 soft:testAmount + 1 accuracy:0]; XCTAssertEqual([self failures:data eventType:@"ckkshardfail" attributes:nil class:SFAnalyticsEventClassHardFailure], testAmount); XCTAssertEqual([self failures:data eventType:@"ckkssoftfail" attributes:nil class:SFAnalyticsEventClassSoftFailure], testAmount); @@ -617,7 +651,7 @@ static NSInteger _reporterCleanups; [self inspectDataBlobStructure:data]; // min, max, avg, med, dev, 1q, 3q - [self checkTotalEventCount:data hard:0 soft:0]; + [self checkTotalEventCount:data hard:0 soft:0 accuracy:0]; [self sampleStatisticsInEvents:data[@"events"] name:sampleNameEven values:@[@5.22, @90.78, @35.60, @36.18, @21.52, @21.36, @44.11]]; } @@ -636,7 +670,7 @@ static NSInteger _reporterCleanups; NSDictionary* data = [self getJSONDataFromSupd]; [self inspectDataBlobStructure:data]; - [self checkTotalEventCount:data hard:0 soft:0]; + [self checkTotalEventCount:data hard:0 soft:0 accuracy:0]; [self sampleStatisticsInEvents:data[@"events"] name:sampleName4n1 values:@[@10.72, @94.24, @45.76, @43.90, @23.14, @26.33, @58.83]]; } @@ -654,7 +688,7 @@ static NSInteger _reporterCleanups; NSDictionary* data = [self getJSONDataFromSupd]; [self inspectDataBlobStructure:data]; - [self checkTotalEventCount:data hard:0 soft:0]; + [self checkTotalEventCount:data hard:0 soft:0 accuracy:0]; [self sampleStatisticsInEvents:data[@"events"] name:sampleName4n3 values:@[@1.67, @99.83, @44.33, @38.45, @35.28, @7.92, @81.70]]; } @@ -668,7 +702,7 @@ static NSInteger _reporterCleanups; NSDictionary* data = [self getJSONDataFromSupd]; [self inspectDataBlobStructure:data]; - [self checkTotalEventCount:data hard:0 soft:0]; + [self checkTotalEventCount:data hard:0 soft:0 accuracy:0]; [self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@3.14159]]; } @@ -683,7 +717,7 @@ static NSInteger _reporterCleanups; NSDictionary* data = [self getJSONDataFromSupd]; [self inspectDataBlobStructure:data]; - [self checkTotalEventCount:data hard:0 soft:0]; + [self checkTotalEventCount:data hard:0 soft:0 accuracy:0]; [self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@3.14, @6.28, @4.71, @4.71, @1.57]]; } @@ -697,7 +731,7 @@ static NSInteger _reporterCleanups; NSDictionary* data = [self getJSONDataFromSupd]; [self inspectDataBlobStructure:data]; - [self checkTotalEventCount:data hard:0 soft:0]; + [self checkTotalEventCount:data hard:0 soft:0 accuracy:0]; [self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@313.37] amount:2]; } diff --git a/supd/supd.h b/supd/supd.h index 855ca5ba..399a21a4 100644 --- a/supd/supd.h +++ b/supd/supd.h @@ -36,7 +36,7 @@ @property NSURL* splunkBagURL; @property NSString *internalTopicName; -@property NSArray *topicClients; +@property NSArray* topicClients; // -------------------------------- // Things below are for unit testing @@ -45,6 +45,9 @@ + (NSString*)databasePathForCKKS; + (NSString*)databasePathForSOS; + (NSString*)databasePathForPCS; ++ (NSString*)databasePathForLocal; ++ (NSString*)databasePathForTrust; ++ (NSString*)databasePathForTrustdHealth; + (NSString*)databasePathForTLS; @end @@ -68,6 +71,7 @@ // -------------------------------- // Things below are for unit testing +extern BOOL runningTests; // Do not use 'force' when obtaining logging json extern BOOL deviceAnalyticsOverride; extern BOOL deviceAnalyticsEnabled; extern BOOL iCloudAnalyticsOverride; diff --git a/supd/supd.m b/supd/supd.m index 4f333d5e..d1601f06 100644 --- a/supd/supd.m +++ b/supd/supd.m @@ -24,7 +24,7 @@ #import "supd.h" #import "SFAnalyticsDefines.h" #import "SFAnalyticsSQLiteStore.h" -#import "SFAnalytics.h" +#import #include #import "utilities/debugging.h" @@ -111,6 +111,7 @@ NSUInteger const secondsBetweenUploadsInternal = (60 * 60 * 24); static supd *_supdInstance = nil; +BOOL runningTests = NO; BOOL deviceAnalyticsOverride = NO; BOOL deviceAnalyticsEnabled = NO; BOOL iCloudAnalyticsOverride = NO; @@ -365,6 +366,7 @@ _isiCloudAnalyticsEnabled() @end @implementation SFAnalyticsTopic + - (void)setupClientsForTopic:(NSString *)topicName { NSMutableArray* clients = [NSMutableArray new]; @@ -375,6 +377,10 @@ _isiCloudAnalyticsEnabled() name:@"sos" deviceAnalytics:NO iCloudAnalytics:YES]]; [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForPCS] name:@"pcs" deviceAnalytics:NO iCloudAnalytics:YES]]; + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForSignIn] + name:@"signins" deviceAnalytics:NO iCloudAnalytics:YES]]; + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForLocal] + name:@"local" deviceAnalytics:YES iCloudAnalytics:NO]]; } else if ([topicName isEqualToString:SFAnaltyicsTopicTrust]) { #if TARGET_OS_OSX _set_user_dir_suffix("com.apple.trustd"); // supd needs to read trustd's cache dir for these @@ -385,6 +391,7 @@ _isiCloudAnalyticsEnabled() name:@"trustdHealth" deviceAnalytics:YES iCloudAnalytics:NO]]; [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForTLS] name:@"tls" deviceAnalytics:YES iCloudAnalytics:NO]]; + #if TARGET_OS_OSX _set_user_dir_suffix(NULL); // set back to the default cache dir #endif @@ -734,6 +741,7 @@ _isiCloudAnalyticsEnabled() - (NSData*)getLoggingJSON:(bool)pretty forUpload:(BOOL)upload participatingClients:(NSMutableArray**)clients + force:(BOOL)force // supdctl uploads ignore privacy settings and recency error:(NSError**)error { NSMutableArray* localClients = [NSMutableArray new]; @@ -746,12 +754,12 @@ _isiCloudAnalyticsEnabled() ckdeviceID = os_variant_has_internal_diagnostics("com.apple.security") ? [self askSecurityForCKDeviceID] : nil; } for (SFAnalyticsClient* client in self->_topicClients) { - if ([client requireDeviceAnalytics] && !_isDeviceAnalyticsEnabled()) { + if (!force && [client requireDeviceAnalytics] && !_isDeviceAnalyticsEnabled()) { // Client required device analytics, yet the user did not opt in. secnotice("getLoggingJSON", "Client '%@' requires device analytics yet user did not opt in.", [client name]); continue; } - if ([client requireiCloudAnalytics] && !_isiCloudAnalyticsEnabled()) { + if (!force && [client requireiCloudAnalytics] && !_isiCloudAnalyticsEnabled()) { // Client required iCloud analytics, yet the user did not opt in. secnotice("getLoggingJSON", "Client '%@' requires iCloud analytics yet user did not opt in.", [client name]); continue; @@ -761,20 +769,24 @@ _isiCloudAnalyticsEnabled() if (upload) { NSDate* uploadDate = store.uploadDate; - if (uploadDate && [[NSDate date] timeIntervalSinceDate:uploadDate] < _secondsBetweenUploads) { + if (!force && uploadDate && [[NSDate date] timeIntervalSinceDate:uploadDate] < _secondsBetweenUploads) { secnotice("json", "ignoring client '%@' for %@ because last upload too recent: %@", client.name, _internalTopicName, uploadDate); continue; } - if (!uploadDate) { + if (!force && !uploadDate) { secnotice("json", "ignoring client '%@' because doesn't have an upload date; giving it a baseline date", client.name); [self updateUploadDateForClients:@[client] clearData:NO]; continue; } - secnotice("json", "including client '%@' for upload", client.name); + if (force) { + secnotice("json", "client '%@' for topic '%@' force-included", client.name, _internalTopicName); + } else { + secnotice("json", "including client '%@' for topic '%@' for upload", client.name, _internalTopicName); + } [localClients addObject:client]; } @@ -790,10 +802,6 @@ _isiCloudAnalyticsEnabled() [softFailures addObject:store.softFailures]; } - if (clients) { - *clients = localClients; - } - if (upload && [localClients count] == 0) { if (error) { NSString *description = [NSString stringWithFormat:@"Upload too recent for all clients for %@", _internalTopicName]; @@ -804,6 +812,10 @@ _isiCloudAnalyticsEnabled() return nil; } + if (clients) { + *clients = localClients; + } + [self addFailures:hardFailures toUploadRecords:uploadRecords threshold:_maxEventsToReport/10]; [self addFailures:softFailures toUploadRecords:uploadRecords threshold:0]; @@ -819,6 +831,7 @@ _isiCloudAnalyticsEnabled() if (error) { *error = localError; } + return json; } @@ -859,9 +872,9 @@ _isiCloudAnalyticsEnabled() // this method is kind of evil for the fact that it has side-effects in pulling other things besides the metricsURL from the server, and as such should NOT be memoized. // TODO redo this, probably to return a dictionary. -- (NSURL*)splunkUploadURL +- (NSURL*)splunkUploadURL:(BOOL)force { - if (![self haveEligibleClients]) { + if (!force && ![self haveEligibleClients]) { // force is true IFF called from supdctl. Customers don't have it and internal audiences must call it explicitly. secnotice("getURL", "Not going to talk to server for topic %@ because no eligible clients", [self internalTopicName]); return nil; } @@ -910,7 +923,7 @@ _isiCloudAnalyticsEnabled() if (secondsBetweenUploads > 0) { if (os_variant_has_internal_diagnostics("com.apple.security") && self->_secondsBetweenUploads < secondsBetweenUploads) { - secnotice("getURL", "Overriding server-sent post frequency because device is internal (%lu -> %lu)", secondsBetweenUploads, self->_secondsBetweenUploads); + secnotice("getURL", "Overriding server-sent post frequency because device is internal (%lu -> %lu)", (unsigned long)secondsBetweenUploads, (unsigned long)self->_secondsBetweenUploads); } else { strongSelf->_secondsBetweenUploads = secondsBetweenUploads; } @@ -1043,6 +1056,11 @@ _isiCloudAnalyticsEnabled() return dbpath; } ++ (NSString*)databasePathForLocal +{ + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"Analytics/localkeychain.db") path]; +} + + (NSString*)databasePathForTrustdHealth { #if TARGET_OS_IPHONE @@ -1070,6 +1088,11 @@ _isiCloudAnalyticsEnabled() #endif } ++ (NSString*)databasePathForSignIn +{ + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory(CFSTR("Analytics/signin_metrics.db")) path]; +} + @end @interface supd () @@ -1200,7 +1223,7 @@ static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directo xpc_activity_state_t activityState = xpc_activity_get_state(activity); secnotice("supd", "hit xpc activity trigger, state: %ld", activityState); if (activityState == XPC_ACTIVITY_STATE_RUN) { - // Clean up the reports directory, and then run our regularly scheduled scan + // Run our regularly scheduled scan [self performRegularlyScheduledUpload]; } }); @@ -1223,21 +1246,21 @@ static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directo - (void)performRegularlyScheduledUpload { secnotice("upload", "Starting uploads in response to regular trigger"); NSError *error = nil; - if ([self uploadAnalyticsWithError:&error]) { + if ([self uploadAnalyticsWithError:&error force:NO]) { secnotice("upload", "Regularly scheduled upload successful"); } else { secerror("upload: Failed to complete regularly scheduled upload: %@", error); } } -- (BOOL)uploadAnalyticsWithError:(NSError**)error { +- (BOOL)uploadAnalyticsWithError:(NSError**)error force:(BOOL)force { [self sendNotificationForOncePerReportSamplers]; BOOL result = NO; NSError* localError = nil; for (SFAnalyticsTopic *topic in _analyticsTopics) { @autoreleasepool { // The logging JSONs get quite large. Ensure they're deallocated between topics. - __block NSURL* endpoint = [topic splunkUploadURL]; // has side effects! + __block NSURL* endpoint = [topic splunkUploadURL:force]; // has side effects! if (!endpoint) { secnotice("upload", "Skipping upload for %@ because no endpoint", [topic internalTopicName]); @@ -1250,7 +1273,7 @@ static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directo } NSMutableArray* clients = [NSMutableArray new]; - NSData* json = [topic getLoggingJSON:false forUpload:YES participatingClients:&clients error:&localError]; + NSData* json = [topic getLoggingJSON:false forUpload:YES participatingClients:&clients force:force error:&localError]; if (json) { if ([topic isSampledUpload]) { if (![self->_reporter saveReport:json fileName:[topic internalTopicName]]) { @@ -1362,7 +1385,7 @@ static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directo NSData* json = nil; for (SFAnalyticsTopic* topic in self->_analyticsTopics) { if ([topic.internalTopicName isEqualToString:topicName]) { - json = [topic getLoggingJSON:pretty forUpload:NO participatingClients:nil error:&error]; + json = [topic getLoggingJSON:pretty forUpload:NO participatingClients:nil force:!runningTests error:&error]; } } if (!json) { @@ -1374,7 +1397,7 @@ static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directo - (void)forceUploadWithReply:(void (^)(BOOL, NSError*))reply { secnotice("upload", "Performing upload in response to rpc message"); NSError* error = nil; - BOOL result = [self uploadAnalyticsWithError:&error]; + BOOL result = [self uploadAnalyticsWithError:&error force:YES]; secnotice("upload", "Result of manually triggered upload: %@, error: %@", result ? @"success" : @"failure", error); reply(result, error); } diff --git a/supdctl/main.m b/supdctl/main.m index 0307de74..10137b7e 100644 --- a/supdctl/main.m +++ b/supdctl/main.m @@ -25,7 +25,7 @@ #include "lib/SecArgParse.h" #import "supd/supdProtocol.h" #import -#import "SFAnalytics.h" +#import /* Internal Topic Names */ NSString* const SFAnalyticsTopicKeySync = @"KeySyncTopic"; @@ -81,7 +81,8 @@ static void getLoggingJSON(char *topicName) dispatch_semaphore_signal(sema); }] getLoggingJSON:YES topic:topic reply:^(NSData* data, NSError* error) { if (data) { - nsprintf(@"Logging data we would have uploaded:\n%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); + // Success! Only print the JSON blob to make output easier to parse + nsprintf(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); } else { nsprintf(@"supd gave us an error: %@", error); } @@ -128,7 +129,7 @@ int main(int argc, char **argv) { .command="sysdiagnose", .flag=&getSysdiagnose, .flagval=true, .description="Retrieve the current sysdiagnose dump for security analytics"}, { .command="get", .flag=&getJSON, .flagval=true, .description="Get the JSON blob we would upload to the server if an upload were due"}, - { .command="upload", .flag=&forceUpload, .flagval=true, .description="Force an upload of analytics data to server"}, + { .command="upload", .flag=&forceUpload, .flagval=true, .description="Force an upload of analytics data to server (ignoring privacy settings)"}, {} // Need this! }; diff --git a/tests/secdmockaks/mockaks.h b/tests/secdmockaks/mockaks.h index 8390d5d9..92b6a65b 100644 --- a/tests/secdmockaks/mockaks.h +++ b/tests/secdmockaks/mockaks.h @@ -24,6 +24,9 @@ #ifndef mockaks_h #define mockaks_h +#import "SecKeybagSupport.h" + +#if USE_KEYSTORE #import @interface SecMockAKS : NSObject @@ -32,4 +35,6 @@ + (bool)useGenerationCount; @end +#endif /* USE_KEYSTORE */ + #endif /* mockaks_h */ diff --git a/tests/secdmockaks/mockaks.m b/tests/secdmockaks/mockaks.m index d18e5e9f..7a47c485 100644 --- a/tests/secdmockaks/mockaks.m +++ b/tests/secdmockaks/mockaks.m @@ -21,9 +21,14 @@ * @APPLE_LICENSE_HEADER_END@ */ +#import "SecKeybagSupport.h" + +#if USE_KEYSTORE #import #import #import +#endif + #import #import #import @@ -34,6 +39,8 @@ #import #import "mockaks.h" +#if USE_KEYSTORE + @implementation SecMockAKS + (bool)isLocked:(keyclass_t)key_class @@ -148,7 +155,10 @@ aks_unwrap_key(const void * wrapped_key, int wrapped_key_size, keyclass_t key_cl int aks_ref_key_create(keybag_handle_t handle, keyclass_t cls, aks_key_type_t type, const uint8_t *params, size_t params_len, aks_ref_key_t *ot) { - return -1; + SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; + SFAESKey* key = [[SFAESKey alloc] initRandomKeyWithSpecifier:keySpecifier error:nil]; + *ot = (__bridge_retained aks_ref_key_t)key; + return kAKSReturnSuccess; } int @@ -181,9 +191,9 @@ aks_operation_optional_params(const uint8_t * access_groups, size_t access_group return -1; } -int aks_ref_key_create_with_blob(keybag_handle_t refkey, const uint8_t *ref_key_blob, size_t ref_key_blob_len, aks_ref_key_t* handle) +int aks_ref_key_create_with_blob(keybag_handle_t keybag, const uint8_t *ref_key_blob, size_t ref_key_blob_len, aks_ref_key_t* handle) { - *handle = NULL; + aks_ref_key_create(keybag, 0, 0, NULL, 0, handle); return 0; } @@ -241,6 +251,10 @@ aks_get_lock_state(keybag_handle_t handle, keybag_state_t *state) return 0; } +CFStringRef kMKBDeviceModeMultiUser = CFSTR("kMKBDeviceModeMultiUser"); +CFStringRef kMKBDeviceModeSingleUser = CFSTR("kMKBDeviceModeSingleUser"); +CFStringRef kMKBDeviceModeKey = CFSTR("kMKBDeviceModeKey"); + static CFStringRef staticKeybagHandle = CFSTR("keybagHandle"); int @@ -268,7 +282,27 @@ int MKBKeyBagGetAKSHandle(MKBKeyBagHandleRef keybag, int32_t *handle) return 0; } +int MKBGetDeviceLockState(CFDictionaryRef options) +{ + if ([SecMockAKS isLocked:key_class_ak] ) + return kMobileKeyBagDeviceIsLocked; + return kMobileKeyBagDeviceIsUnlocked; +} + +CF_RETURNS_RETAINED CFDictionaryRef +MKBUserTypeDeviceMode(CFDictionaryRef options, CFErrorRef * error) +{ + return CFBridgingRetain(@{ + (__bridge NSString *)kMKBDeviceModeKey : (__bridge NSString *)kMKBDeviceModeSingleUser, + }); +} + +int MKBForegroundUserSessionID( CFErrorRef * error) +{ + return 0; +} +#endif /* USE_KEYSTORE */ const CFTypeRef kAKSKeyAcl = (CFTypeRef)CFSTR("kAKSKeyAcl"); const CFTypeRef kAKSKeyAclParamRequirePasscode = (CFTypeRef)CFSTR("kAKSKeyAclParamRequirePasscode"); diff --git a/tests/secdmockaks/secdmockaks.m b/tests/secdmockaks/secdmockaks.m index ee43a42e..da508f25 100644 --- a/tests/secdmockaks/secdmockaks.m +++ b/tests/secdmockaks/secdmockaks.m @@ -21,6 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ +#import "SecKeybagSupport.h" #import "SecDbKeychainItem.h" #import "SecdTestKeychainUtilities.h" #import "CKKS.h" @@ -32,7 +33,9 @@ #import #import #import +#if USE_KEYSTORE #import +#endif #import #import "mockaks.h" @@ -57,7 +60,9 @@ * that leads to the vnode delete kevent trap triggering for sqlite * over and over again. */ +#if OCTAGON SecCKKSTestSetDisableSOS(true); +#endif //securityd_init(NULL); } @@ -105,33 +110,6 @@ //kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); } -- (void)testAddKeyByReference -{ - NSDictionary* keyParams = @{ (id)kSecAttrKeyType : (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits : @(1024) }; - SecKeyRef key = SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyParams, NULL); - NSDictionary* item = @{ (id)kSecClass : (id)kSecClassKey, - (id)kSecValueRef : (__bridge id)key, - (id)kSecAttrLabel : @"TestLabel", - (id)kSecAttrNoLegacy : @(YES) }; - - OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); - XCTAssertEqual(result, 0, @"failed to add test item to keychain"); - - NSMutableDictionary* refQuery = item.mutableCopy; - [refQuery removeObjectForKey:(id)kSecValueData]; - refQuery[(id)kSecReturnRef] = @(YES); - CFTypeRef foundItem = NULL; - result = SecItemCopyMatching((__bridge CFDictionaryRef)refQuery, &foundItem); - XCTAssertEqual(result, 0, @"failed to find the reference for the item we just added in the keychain"); - - NSData* originalKeyData = (__bridge_transfer NSData*)SecKeyCopyExternalRepresentation(key, NULL); - NSData* foundKeyData = (__bridge_transfer NSData*)SecKeyCopyExternalRepresentation((SecKeyRef)foundItem, NULL); - XCTAssertEqualObjects(originalKeyData, foundKeyData, @"found key does not match the key we put in the keychain"); - - result = SecItemDelete((__bridge CFDictionaryRef)refQuery); - XCTAssertEqual(result, 0, @"failed to delete key"); -} - - (void)testAddDeleteItem { @@ -265,8 +243,10 @@ - (void)testCreateSampleDatabase { +#if USE_KEYSTORE id mock = OCMClassMock([SecMockAKS class]); OCMStub([mock useGenerationCount]).andReturn(true); +#endif [self createManyItems]; [self createManyKeys]; @@ -286,11 +266,13 @@ - (void)testTestAKSGenerationCount { +#if USE_KEYSTORE id mock = OCMClassMock([SecMockAKS class]); OCMStub([mock useGenerationCount]).andReturn(true); [self createManyItems]; [self findManyItems:50]; +#endif } @@ -318,6 +300,31 @@ XCTAssertEqual(SQLITE_OK, sqlite3_close(handle), "close sqlite"); } +- (void)checkIncremental +{ + /* + * check that we made incremental vacuum mode + */ + + __block CFErrorRef localError = NULL; + __block bool ok = true; + __block int vacuumMode = -1; + + kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { + ok &= SecDbPrepare(dbt, CFSTR("PRAGMA auto_vacuum"), &localError, ^(sqlite3_stmt *stmt) { + ok = SecDbStep(dbt, stmt, NULL, ^(bool *stop) { + vacuumMode = sqlite3_column_int(stmt, 0); + }); + }); + return ok; + }); + XCTAssertEqual(ok, true, "should work to fetch auto_vacuum value: %@", localError); + XCTAssertEqual(vacuumMode, 2, "vacuum mode should be incremental (2)"); + + CFReleaseNull(localError); + +} + - (void)testUpgradeFromVersion10_5 { SecKeychainDbReset(^{ @@ -327,6 +334,8 @@ NSLog(@"find items from old database"); [self findManyItems:50]; + + [self checkIncremental]; } - (void)testUpgradeFromVersion11_1 @@ -338,6 +347,37 @@ NSLog(@"find items from old database"); [self findManyItems:50]; + + [self checkIncremental]; +} + +#if USE_KEYSTORE + +- (void)testAddKeyByReference +{ + NSDictionary* keyParams = @{ (id)kSecAttrKeyType : (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits : @(1024) }; + SecKeyRef key = SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyParams, NULL); + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassKey, + (id)kSecValueRef : (__bridge id)key, + (id)kSecAttrLabel : @"TestLabel", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* refQuery = item.mutableCopy; + [refQuery removeObjectForKey:(id)kSecValueData]; + refQuery[(id)kSecReturnRef] = @(YES); + CFTypeRef foundItem = NULL; + result = SecItemCopyMatching((__bridge CFDictionaryRef)refQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the reference for the item we just added in the keychain"); + + NSData* originalKeyData = (__bridge_transfer NSData*)SecKeyCopyExternalRepresentation(key, NULL); + NSData* foundKeyData = (__bridge_transfer NSData*)SecKeyCopyExternalRepresentation((SecKeyRef)foundItem, NULL); + XCTAssertEqualObjects(originalKeyData, foundKeyData, @"found key does not match the key we put in the keychain"); + + result = SecItemDelete((__bridge CFDictionaryRef)refQuery); + XCTAssertEqual(result, 0, @"failed to delete key"); } - (bool)isLockedSoon:(keyclass_t)key_class @@ -350,7 +390,6 @@ return false; } - /* * Lock in the middle of migration */ @@ -419,6 +458,8 @@ SecKeychainDbGetVersion(dbt, &version, &error); XCTAssertEqual(error, NULL, "error getting version"); XCTAssertEqual(version, 0x50a, "managed to upgrade when we shouldn't have"); + + return true; }); /* user got the SEP out of DFU */ @@ -433,12 +474,15 @@ int version = 0; SecKeychainDbGetVersion(dbt, &version, &error); XCTAssertEqual(error, NULL, "error getting version"); - XCTAssertEqual(version, 0x20b, "didnt managed to upgrade"); + XCTAssertEqual(version, 0x40b, "didnt managed to upgrade"); + + return true; }); NSLog(@"find items from old database"); [self findManyItems:50]; } +#endif /* USE_KEYSTORE */ @end diff --git a/trust/SecCertificate.h b/trust/SecCertificate.h index d3c19711..1f291452 100644 --- a/trust/SecCertificate.h +++ b/trust/SecCertificate.h @@ -49,7 +49,7 @@ #include #include -#endif +#endif // SEC_OS_OSX __BEGIN_DECLS @@ -145,16 +145,27 @@ __nullable CFDataRef SecCertificateCopyNormalizedSubjectSequence(SecCertificateRef certificate) __OSX_AVAILABLE_STARTING(__MAC_10_12_4, __IPHONE_10_3); +/*! + @function SecCertificateCopyKey + @abstract Retrieves the public key for a given certificate. + @param certificate A reference to the certificate from which to retrieve the public key. + @result A reference to the public key for the specified certificate. Your code must release this reference by calling the CFRelease function. If the public key has an encoding issue or uses an unsupported algorithm, the returned reference will be null. + */ +__nullable CF_RETURNS_RETAINED +SecKeyRef SecCertificateCopyKey(SecCertificateRef certificate) + API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); + #if TARGET_OS_IPHONE /*! @function SecCertificateCopyPublicKey @abstract Retrieves the public key for a given certificate. @param certificate A reference to the certificate from which to retrieve the public key. @result A reference to the public key for the specified certificate. Your code must release this reference by calling the CFRelease function. + @discussion NOTE: Deprecated in iOS 12.0; use SecCertificateCopyKey instead for cross-platform availability. */ __nullable SecKeyRef SecCertificateCopyPublicKey(SecCertificateRef certificate) - __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_10_3); + API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopyKey", ios(10.3, 12.0)) API_UNAVAILABLE(macos); #endif #if TARGET_OS_OSX @@ -164,9 +175,10 @@ SecKeyRef SecCertificateCopyPublicKey(SecCertificateRef certificate) @param certificate A reference to the certificate from which to retrieve the public key. @param key On return, a reference to the public key for the specified certificate. Your code must release this reference by calling the CFRelease function. @result A result code. See "Security Error Codes" (SecBase.h). + @discussion NOTE: Deprecated in macOS 10.14; use SecCertificateCopyKey instead for cross-platform availability. */ OSStatus SecCertificateCopyPublicKey(SecCertificateRef certificate, SecKeyRef * __nonnull CF_RETURNS_RETAINED key) - __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA); + API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopyKey", macos(10.3, 10.14)) API_UNAVAILABLE(ios); #endif /*! @@ -189,7 +201,7 @@ CFDataRef SecCertificateCopySerialNumberData(SecCertificateRef certificate, CFEr */ __nullable CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate) - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_NA, __MAC_NA, __IPHONE_10_3, __IPHONE_11_0, "SecCertificateCopySerialNumber is deprecated. Use SecCertificateCopySerialNumberData instead."); + API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopySerialNumberData", ios(10.3, 11.0)) API_UNAVAILABLE(macos); #endif #if TARGET_OS_OSX @@ -202,7 +214,7 @@ CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate) */ __nullable CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate, CFErrorRef *error) - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_7, __MAC_10_13, __IPHONE_NA, __IPHONE_NA, "SecCertificateCopySerialNumber is deprecated. Use SecCertificateCopySerialNumberData instead."); + API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopySerialNumberData", macos(10.7, 10.13)) API_UNAVAILABLE(ios); #endif /* diff --git a/trust/SecCertificatePriv.h b/trust/SecCertificatePriv.h index a874f611..b0786e3c 100644 --- a/trust/SecCertificatePriv.h +++ b/trust/SecCertificatePriv.h @@ -389,6 +389,18 @@ CFDataRef SecCertificateGetSubjectKeyID(SecCertificateRef certificate) CFArrayRef SecCertificateCopyiPhoneDeviceCAChain(void) __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0); +typedef CF_ENUM(uint32_t, SeciAPSWAuthCapabilitiesType) { + kSeciAPSWAuthGeneralCapabilities = 0, + kSeciAPSWAuthAirPlayCapabilities = 1, + kSeciAPSWAuthHomeKitCapabilities = 2, +} __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_11_3); + +/* Return the iAP SW Auth capabilities bitmask from the specificed + * SeciAPSWAuthCapabilitiesType type marker extensions. */ +CF_RETURNS_RETAINED +CFDataRef SecCertificateCopyiAPSWAuthCapabilities(SecCertificateRef certificate, + SeciAPSWAuthCapabilitiesType type) + __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_11_3); /*! @function SecCertificateCopyExtensionValue @@ -407,11 +419,6 @@ CFDataRef SecCertificateCopyExtensionValue(SecCertificateRef certificate, CFTypeRef extensionOID, bool *isCritical) __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_11_3); -/* Return a (modern) SecKeyRef for the public key embedded in the cert. */ -#if TARGET_OS_OSX - SecKeyRef SecCertificateCopyPublicKey_ios(SecCertificateRef certificate); -#endif - /* * Legacy functions (OS X only) */ diff --git a/trust/SecCertificateRequest.h b/trust/SecCertificateRequest.h index efb37676..ba33965e 100644 --- a/trust/SecCertificateRequest.h +++ b/trust/SecCertificateRequest.h @@ -119,7 +119,7 @@ typedef SecATV *SecRDN; @abstract Return a newly generated CSR for subject and keypair. @param subject RDNs in the subject @param paramters Parameters for the CSR generation. See above. - @param publicKey Public key (NOTE: This is unused) + @param publicKey Public key @param privateKey Private key @result On success, a newly allocated CSR, otherwise NULL @@ -138,7 +138,7 @@ CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN _Nonnull * _Nonnull @abstract Return a newly generated CSR for subject and keypair. @param subject RDNs in the subject in array format @param paramters Parameters for the CSR generation. See above. - @param publicKey Public key (NOTE: This is unused) + @param publicKey Public key @param privateKey Private key @result On success, a newly allocated CSR, otherwise NULL @discussion The subject array contains an array of the RDNS. Each RDN is diff --git a/trust/SecPolicyPriv.h b/trust/SecPolicyPriv.h index b40920e0..e7e6fbee 100644 --- a/trust/SecPolicyPriv.h +++ b/trust/SecPolicyPriv.h @@ -64,7 +64,7 @@ extern const CFStringRef kSecPolicyAppleOTAPKISigner extern const CFStringRef kSecPolicyAppleTestOTAPKISigner __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12, __MAC_10_13_4, __IPHONE_7_0, __IPHONE_11_3); extern const CFStringRef kSecPolicyAppleIDValidationRecordSigningPolicy - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_7_0, __IPHONE_10_0); + API_DEPRECATED_WITH_REPLACEMENT("kSecPolicyAppleIDValidationRecordSigning", ios(7.0,10.0), macos(10.9,10.12)); extern const CFStringRef kSecPolicyAppleIDValidationRecordSigning __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0); extern const CFStringRef kSecPolicyAppleSMPEncryption @@ -173,6 +173,14 @@ extern const CFStringRef kSecPolicyAppleBasicAttestationUser __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); extern const CFStringRef kSecPolicyAppleiPhoneVPNApplicationSigning __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +extern const CFStringRef kSecPolicyAppleiAPSWAuth + API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); +extern const CFStringRef kSecPolicyAppleDemoDigitalCatalog + API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); +extern const CFStringRef kSecPolicyAppleAssetReceipt + API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); +extern const CFStringRef kSecPolicyAppleDeveloperIDPlusTicket + API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); /*! @enum Policy Name Constants (Private) @@ -686,7 +694,7 @@ SecPolicyRef SecPolicyCreateCodeSigning(void); /*! @function SecPolicyCreateLockdownPairing @abstract basic x509 policy for checking lockdown pairing certificate chains. - @disucssion This policy checks some of the Basic X.509 policy options with no + @discussion This policy checks some of the Basic X.509 policy options with no validity check. It explicitly allows for empty subjects. @result A policy object. The caller is responsible for calling CFRelease on this when it is no longer needed. @@ -1648,6 +1656,22 @@ __nullable CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateAppleBasicAttestationUser(CFDataRef __nullable testRootHash) __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +/*! + @function SecPolicyCreateiAPSWAuth + @abstract Returns a policy object for verifying iAP Software Auth certificates + @discussion The resulting policy uses the Basic X.509 policy with no validity check + and pinning options: + * There are exactly 2 certs in the chain. + * The leaf has a marker extension with OID 1.2.840.113635.100.6.59.1 + The intended use of this policy is that the caller pass in the + SW Auth root to SecTrustSetAnchorCertificates(). + @result A policy object. The caller is responsible for calling CFRelease on this when + it is no longer needed. + */ +__nullable CF_RETURNS_RETAINED +SecPolicyRef SecPolicyCreateiAPSWAuth(void) + __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); + /*! @function SecPolicyCreateDemoDigitalCatalog @abstract Returns a policy object for evaluating certificate chains for signing Digital @@ -1664,6 +1688,69 @@ __nullable CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateDemoDigitalCatalogSigning(void) __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); +/*! + @function SecPolicyCreateAppleAssetReceipt + @abstract Returns a policy object for evaluating certificate chains for signing Asset Receipts + @discussion This policy uses the Basic X.509 policy with no validity check + and pinning options: + * The chain is anchored to any of the production Apple Root CAs. Internal releases allow + the chain to be anchored to Test Apple Root CAs if a defaults write for the policy is set. + * There are exactly 3 certs in the chain. + * The intermediate has a marker extension with OID 1.2.840.113635.100.6.2.10. + * The leaf has a marker extension with OID 1.2.840.113635.100.6.61. + * RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. + @result A policy object. The caller is responsible for calling CFRelease + on this when it is no longer needed. + */ +__nullable CF_RETURNS_RETAINED +SecPolicyRef SecPolicyCreateAppleAssetReceipt(void) + API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); + +/*! + @function SecPolicyCreateAppleDeveloperIDPlustTicket + @abstract Returns a policy object for evaluating certificate chains for signing Developer ID+ Tickets + @discussion This policy uses the Basic X.509 policy with no validity check + and pinning options: + * The chain is anchored to any of the production Apple Root CAs. + * There are exactly 3 certs in the chain. + * The intermediate has a marker extension with OID 1.2.840.113635.100.6.2.17. + * The leaf has a marker extension with OID 1.2.840.113635.100.6.1.30. + * RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. + @result A policy object. The caller is responsible for calling CFRelease + on this when it is no longer needed. + */ +__nullable CF_RETURNS_RETAINED +SecPolicyRef SecPolicyCreateAppleDeveloperIDPlusTicket(void) + API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); + +/*! + @function SecPolicyCreateiAPSWAuthWithExpiration + @abstract Returns a policy object for verifying iAP Software Auth certificates + @param checkExpiration Determines whether the policy checks expiration on the certificates + @discussion The resulting policy uses the Basic X.509 policy and pinning options: + * There are exactly 2 certs in the chain. + * The leaf has a marker extension with OID 1.2.840.113635.100.6.59.1 + The intended use of this policy is that the caller pass in the + SW Auth root to SecTrustSetAnchorCertificates(). + @result A policy object. The caller is responsible for calling CFRelease on this when + it is no longer needed. + */ +__nullable CF_RETURNS_RETAINED +SecPolicyRef SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration) + API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); + +/*! + @function SecPolicyCreateAppleFDRProvisioning + @abstract Returns a policy object for verifying FDR Provisioning certificates + @discussion The resulting policy uses the Basic X.509 policy with no validity check. + The intended use of this policy is that the caller pass in the FDR root to SecTrustSetAnchorCertificates(). + @result A policy object. The caller is responsible for calling CFRelease on this when + it is no longer needed. + */ +__nullable CF_RETURNS_RETAINED +SecPolicyRef SecPolicyCreateAppleFDRProvisioning(void) + API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); + /* * Legacy functions (OS X only) */ @@ -1707,7 +1794,8 @@ SecPolicyRef SecPolicyCreateItemImplInstance(SecPolicyRef policy); to SecPolicyCreateWithProperties. The return value can be NULL if no supported policy was found for the OID argument. */ __nullable -CFStringRef SecPolicyGetStringForOID(CSSM_OID* oid); +CFStringRef SecPolicyGetStringForOID(CSSM_OID* oid) + API_DEPRECATED("No longer supported", macos(10.5,10.14)); /*! @function SecPolicyCreateAppleTimeStampingAndRevocationPolicies diff --git a/trust/SecTrust.h b/trust/SecTrust.h index 3783409e..04f5dfa5 100644 --- a/trust/SecTrust.h +++ b/trust/SecTrust.h @@ -43,7 +43,7 @@ CF_IMPLICIT_BRIDGING_ENABLED @typedef SecTrustResultType @abstract Specifies the trust result type. @discussion SecTrustResultType results have two dimensions. They specify - both whether evaluation suceeded and whether this is because of a user + both whether evaluation succeeded and whether this is because of a user decision. The commonly expected result is kSecTrustResultUnspecified, which indicates a positive result that wasn't decided by the user. The common failure is kSecTrustResultRecoverableTrustFailure, which means a @@ -348,7 +348,7 @@ CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust) dispatch queue, or in a separate thread from your application's main run loop. Alternatively, you can use the SecTrustEvaluateAsync function. */ -OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType * __nullable result) +OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result) __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0); #ifdef __BLOCKS__ @@ -367,6 +367,31 @@ OSStatus SecTrustEvaluateAsync(SecTrustRef trust, __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0); #endif +/*! + @function SecTrustEvaluateWithError + @abstract Evaluates a trust reference synchronously. + @param trust A reference to the trust object to evaluate. + @param error A pointer to an error object + @result A boolean value indicating whether the certificate is trusted + @discussion This function will completely evaluate trust before returning, + possibly including network access to fetch intermediate certificates or to + perform revocation checking. Since this function can block during those + operations, you should call it from within a function that is placed on a + dispatch queue, or in a separate thread from your application's main + run loop. + If the certificate is trusted and the result is true, the error will be set to NULL. + If the certificate is not trusted or the evaluation was unable to complete, the result + will be false and the error will be set with a description of the failure. + The error contains a code for the most serious error encountered (if multiple trust + failures occurred). The localized description indicates the certificate with the most + serious problem and the type of error. The underlying error contains a localized + description of each certificate in the chain that had an error and all errors found + with that certificate. + */ +__attribute__((warn_unused_result)) bool +SecTrustEvaluateWithError(SecTrustRef trust, CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error) + API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)); + /*! @function SecTrustGetTrustResult @param trust A reference to a trust object. diff --git a/trust/SecTrustPriv.h b/trust/SecTrustPriv.h index b04be624..58656527 100644 --- a/trust/SecTrustPriv.h +++ b/trust/SecTrustPriv.h @@ -414,30 +414,22 @@ OSStatus SecTrustSetPinningPolicyName(SecTrustRef trust, CFStringRef policyName) OSStatus SecTrustSetPinningException(SecTrustRef trust) __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +#ifdef __BLOCKS__ /*! - @function SecTrustEvaluateWithError - @abstract Evaluates a trust reference synchronously. + @function SecTrustEvaluateFastAsync + @abstract Evaluates a trust reference asynchronously. @param trust A reference to the trust object to evaluate. - @param error A pointer to an error object - @result A boolean value indicating whether the certificate is trusted - @discussion This function will completely evaluate trust before returning, - possibly including network access to fetch intermediate certificates or to - perform revocation checking. Since this function can block during those - operations, you should call it from within a function that is placed on a - dispatch queue, or in a separate thread from your application's main - run loop. - If the certificate is trusted and the result is true, the error will be set to NULL. - If the certificate is not trusted or the evaluation was unable to complete, the result - will be false and the error will be set with a description of the failure. - The error contains a code for the most serious error encountered (if multiple trust - failures occurred). The localized description indicates the certificate with the most - serious problem and the type of error. The underlying error contains a localized - description of each certificate in the chain that had an error and all errors found - with that certificate. + @param queue A dispatch queue on which the result callback will be + executed. Note that this function MUST be called from that queue. + @param result A SecTrustCallback block which will be executed when the + trust evaluation is complete. The block is guaranteed to be called exactly once + when the result code is errSecSuccess, and not called otherwise. Note that this + block may be called synchronously inline if no asynchronous operations are required. + @result A result code. See "Security Error Codes" (SecBase.h). */ -__attribute__((warn_unused_result)) bool -SecTrustEvaluateWithError(SecTrustRef trust, CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error) - __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); +OSStatus SecTrustEvaluateFastAsync(SecTrustRef trust, dispatch_queue_t queue, SecTrustCallback result) + __API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)); +#endif /*! @function SecTrustReportTLSAnalytics diff --git a/xcconfig/PlatformLibraries.xcconfig b/xcconfig/PlatformLibraries.xcconfig index 3a36cf4c..27829467 100644 --- a/xcconfig/PlatformLibraries.xcconfig +++ b/xcconfig/PlatformLibraries.xcconfig @@ -49,10 +49,6 @@ OTHER_LDFLAGS_APPLEACCOUNT[sdk=iphonesimulator*] = $(OTHER_LDFLAGS_APPLEACCOUNT_ OTHER_LDFLAGS_APPLEACCOUNT[sdk=appletv*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) OTHER_LDFLAGS_APPLEACCOUNT[sdk=watchos*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) -OTHER_LDFLAGS_CORECDP_BRIDGE_NO = -framework CoreCDP -OTHER_LDFLAGS_CORECDP_BRIDGE_YES = -OTHER_LDFLAGS_CORECDP = $(OTHER_LDFLAGS_CORECDP_BRIDGE_$(BRIDGE)) - // The bridge appears to support protocol buffers. OTHER_LDFLAGS_PROTOBUF = -framework ProtocolBuffer diff --git a/xcconfig/Security.xcconfig b/xcconfig/Security.xcconfig index a9a2b0a0..e95fb5bc 100644 --- a/xcconfig/Security.xcconfig +++ b/xcconfig/Security.xcconfig @@ -1,8 +1,3 @@ - -SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) $(SDKROOT)/$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks - -MACOSX_DEPLOYMENT_TARGET = 10.13.4 - OTHER_CFLAGS = -isystem $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders -fconstant-cfstrings HEADER_SYMLINKS = $(PROJECT_DIR)/header_symlinks @@ -31,7 +26,8 @@ WARNING_CFLAGS[sdk=embedded*] = $(WARNING_CFLAGS) -Wformat=2 // The SOS headers get copied into a specific directory in the framework during their own copy files phase. // This breaks TAPI during the build, which does INSTALLHDR -> INSTALLAPI without running any copy files phases. // So, we must include each file as a 'public' header in the TAPI command. -OTHER_TAPI_FLAGS_SOS = -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoCollections.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCircleDer.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSGenCount.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h +// We also add some 'private' headers here that aren't in the framework; this is unfortunate but better than putting very internal headers as SPI. +OTHER_TAPI_FLAGS_SOS = -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoCollections.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCircleDer.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSGenCount.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h -extra-private-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h // This isn't OTHER_TAPI_FLAGS because we'll mess up other, non-Security.framework frameworks in the project // Please don't add any more headers here. diff --git a/xcscripts/install-test-framework.sh b/xcscripts/install-test-framework.sh new file mode 100644 index 00000000..ae4aae17 --- /dev/null +++ b/xcscripts/install-test-framework.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +framework="$1" + +found=no + +for a in ${TEST_FRAMEWORK_SEARCH_PATHS}; do + if test -d "${a}/${framework}" ; then + dst="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + mkdir -p "{dst}" || { echo "mkdir failed with: $?" ; exit 1; } + ditto "${a}/${framework}" "${dst}/${framework}" || { echo "ditto failed with: $?" ; exit 1; } + xcrun codesign -s - -f "${dst}/${framework}" || { echo "codesign failed with: $?" ; exit 1; } + + found=yes + break + fi +done + +test "X${found}" != "Xyes" && exit 1 + +exit 0 -- 2.47.2